題目:
描述 給定一個(gè)字符串描述的算術(shù)表達(dá)式,計(jì)算出結(jié)果值。 輸入字符串長(zhǎng)度不超過(guò) 100 ,合法的字符包括 ”+, -, *, /, (, )” , ”0-9” 。 數(shù)據(jù)范圍:運(yùn)算過(guò)程中和最終結(jié)果均滿足∣val∣≤2^31?1 ,即只進(jìn)行整型運(yùn)算,確保輸入的表達(dá)式合法 輸入描述: 輸入算術(shù)表達(dá)式 輸出描述: 計(jì)算出結(jié)果值 示例1 輸入: 400+5 復(fù)制 輸出: 405
考點(diǎn):棧
解題思路:
使用 2 個(gè)棧,一個(gè) stack_nums 用來(lái)保存計(jì)算過(guò)程的操作數(shù),一個(gè) stack_symbol 用來(lái)保存運(yùn)算符。
在HashMap中,指定加減優(yōu)先級(jí)為1,乘除優(yōu)先級(jí)為2
循環(huán)遍歷字符串s,
操作符入棧:
若當(dāng)前字符為'+', '-', '*', '/', '(' 時(shí),壓入運(yùn)算符棧 stack_symbol,
操作數(shù)入棧:
若當(dāng)前字符為數(shù)值類(lèi)型,相當(dāng)于循環(huán)讀取字符串轉(zhuǎn)化為十進(jìn)制整數(shù),直到下一個(gè)字符為非數(shù)值類(lèi)型,把它壓入操作數(shù)棧中。
執(zhí)行運(yùn)算:
當(dāng)遍歷到加減乘除運(yùn)算符時(shí),判斷棧stack_symbol內(nèi)存在優(yōu)先級(jí)大于等于當(dāng)前運(yùn)算符,則可以先執(zhí)行一次運(yùn)算,盡可能先消費(fèi)棧stack_symbol內(nèi)的運(yùn)算符;
當(dāng)右括號(hào)出現(xiàn)時(shí)需要執(zhí)行一次優(yōu)先級(jí)運(yùn)算,并從操作符棧內(nèi)彈出對(duì)應(yīng)的左括號(hào);
運(yùn)算規(guī)則:棧是后進(jìn)先出,參與加減乘除運(yùn)算時(shí),第一個(gè)從 stack_nums 棧頂彈出的數(shù)應(yīng)在運(yùn)算符后面,第二個(gè) stack_nums 從棧頂彈出的數(shù)應(yīng)在運(yùn)算符前面。
特殊情況處理:
括號(hào)的處理:
括號(hào)有2種情況,
第一種是負(fù)數(shù)攜帶的括號(hào),即除了第一個(gè)位置出現(xiàn)的數(shù)外,后面的數(shù)為負(fù)數(shù)時(shí)所附帶的括號(hào),
第二種是,需要優(yōu)先進(jìn)行運(yùn)算的式子
負(fù)數(shù)的處理:
對(duì)于負(fù)數(shù)的處理,增加一步 0 - n 運(yùn)算,假設(shè)負(fù)號(hào)后面的數(shù)等于 n
開(kāi)頭第一個(gè)數(shù)帶 '-' 號(hào),s.charAt(0) == '-'
s = "0" + s;
或者括號(hào) () 里面第一個(gè)數(shù)帶 '-' 號(hào),
s = s.replace( "(-", "(0-" );
認(rèn)為是負(fù)號(hào),否則認(rèn)為是減號(hào)
當(dāng)循環(huán)結(jié)束時(shí),若棧stack_symbol內(nèi)還有運(yùn)算符,繼續(xù)算完
import java.util.Scanner;
import java.util.Stack;
import java.util.Map;
import java.util.HashMap;
// 注意類(lèi)名必須為 Main, 不要有任何 package xxx 信息
/**
* @ClassName
* @Description
* @Author liulvhua
* @Date 2023/4/5
**/
public class HJ54 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
Stack<Integer> stack_nums = new Stack<>();
Stack<Character> stack_symbol = new Stack<>();
Map<Character, Integer> map = new HashMap<>();
map.put('+', 1);
map.put('-', 1);
map.put('*', 2);
map.put('/', 2);
while (sc.hasNextLine()) {
String s = sc.nextLine();
if (s.charAt(0) == '-') {//第一個(gè)數(shù)為負(fù)數(shù)
s = "0" + s;
}
s = s.replace("(-", "(0-");//其他位置負(fù)數(shù)處理
for (int i = 0; i < s.length(); i++) {
char ch = s.charAt(i);
if (ch == ' ') continue;
if (ch == '(') {
stack_symbol.push(ch);
continue;
}
if (ch == ')') {
//括號(hào)結(jié)束計(jì)算一次
stack_nums.push(calculate(stack_nums, stack_symbol));
if (!stack_symbol.isEmpty() && stack_symbol.peek() == '(') {
//當(dāng)前計(jì)算是括號(hào)內(nèi)最后一次運(yùn)算,彈出左括號(hào)
stack_symbol.pop();
}
continue;
}
if (map.containsKey(ch)) {
// 棧內(nèi)至少有1個(gè)運(yùn)算符且棧頂不是左括號(hào),并且棧內(nèi)運(yùn)算符優(yōu)先級(jí)大于等于當(dāng)前運(yùn)算符號(hào)優(yōu)先級(jí),執(zhí)行一次計(jì)算,
// 即先消費(fèi)已入棧的高優(yōu)先級(jí)運(yùn)算符
while (!stack_symbol.isEmpty() && stack_symbol.peek() != '(' && map.get(stack_symbol.peek()) >= map.get(ch)) {
stack_nums.push(calculate(stack_nums, stack_symbol));
}
stack_symbol.push(ch);
} else {
int num = 0;
int j = i;//循環(huán)讀取十進(jìn)制整數(shù)
while (j < s.length() && Character.isDigit(s.charAt(j))) {
num = num * 10 + s.charAt(j) - '0';
j++;
}
stack_nums.push(num);
i = j - 1;
}
}
// 循環(huán)結(jié)束還有未算盡的式子,優(yōu)先級(jí)低
while (!stack_symbol.isEmpty()) {
stack_nums.push(calculate(stack_nums, stack_symbol));
if (!stack_symbol.isEmpty() && stack_symbol.peek() == '(') {
stack_symbol.pop();
}
}
System.out.println(stack_nums.pop());
}
}
/**
* 執(zhí)行運(yùn)算
* @param stack_nums 操作數(shù)棧
* @param stack_symbol 運(yùn)算符棧
* @return
*/
public static int calculate(Stack<Integer> stack_nums, Stack<Character> stack_symbol) {
int res = 0;
int opt_nums2 = stack_nums.pop();
int opt_nums1 = stack_nums.pop();
char symbol = stack_symbol.pop();
switch (symbol) {
case '+': {
res = opt_nums1 + opt_nums2;
break;
}
case '-': {
res = opt_nums1 - opt_nums2;
break;
}
case '*': {
res = opt_nums1 * opt_nums2;
break;
}
case '/': {
res = opt_nums1 / opt_nums2;
break;
}
}
return res;
}
}
執(zhí)行用例:文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-729354.html
2*3-2*(1-2*2)-0
12
2*3-2*(1-2*(1-3))-0
-4
2*3-2*(1-2*(1-3))-0
-4
2*3-2*(1-2*(1-3)*(-1))-0
12?文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-729354.html
到了這里,關(guān)于Java算法題 給一個(gè)字符串表達(dá)式,實(shí)現(xiàn)一個(gè)基本計(jì)算器,返回計(jì)算結(jié)果的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!