輸入以 = 結尾的算術表達式(含 + - * / ( ),數值為非負實數),輸出計算結果保留兩位小數。多組測試。
維護兩個棧:
- num:操作數棧(double)
- op:運算符棧(char),初始壓入 '=' 作為哨兵
| 棧頂 \ 當前 | + - | * / | ( | ) | = |
|---|---|---|---|---|---|
| + - | > | < | < | > | > |
| * / | > | > | < | > | > |
| ( | < | < | < | = | 錯誤 |
| = | < | < | < | 錯誤 | = |
<:當前優先級高,壓棧。
>:棧頂優先級高/等,彈出計算。
=:匹配成功,彈出哨兵。
num。char cmp = compare(op.top(), cur);
if (cmp == '<') op.push(cur);
else if (cmp == '>') {
double b = num.top(); num.pop();
double a = num.top(); num.pop();
num.push(calc(a, op.top(), b));
op.pop();
// 當前運算符不進棧,指針不動,下輪再比較
} else if (cmp == '=') op.pop(); // 匹配括號或結束
num.top() 即為結果。double calc(double a, char op, double b) {
switch(op) {
case '+': return a+b;
case '-': return a-b;
case '*': return a*b;
case '/': return a/b; // 題目保證除數非 0
}
return 0;
}
char compare(char top, char cur) {
if (top == '+' || top == '-') {
if (cur == '*' || cur == '/' || cur == '(') return '<';
return '>';
}
if (top == '*' || top == '/') {
if (cur == '(') return '<';
return '>';
}
if (top == '(') {
if (cur == ')') return '=';
return '<';
}
if (top == ')') return '>';
if (top == '=') {
if (cur == '=') return '=';
return '<';
}
return '>'; // default
}
sscanf 或手寫狀態機讀取完整浮點數(含小數點)。( 在棧中優先級最低,遇 ) 才匹配。printf("%.2f\n", ans) 自動四捨五入保留兩位小數。while(k--) 循環。