使用兩個棧:
#。掃描輸入字符串,根據運算符優先級決定“移入”還是“歸約(計算)”。
typedef struct {
char name; // 運算符字符
int priority; // 優先級:! (3) > */ (2) > +- (1) > () (0)
int opnum; // 目數:! (1元) , +-*/ (2元)
} OPERATOR;
# (優先級 0)。topOp。op.priority > topOp.priority:壓入 op (移入)。topOp 執行計算,結果壓入數值棧,重新比較 (歸約)。op 壓入棧。#。
double getNumFromString(char *s, int *i) {
char buf[100]; int j = 0;
while (s[*i] >= '0' && s[*i] <= '9') buf[j++] = s[(*i)++];
if (s[*i] == '.') {
buf[j++] = s[(*i)++];
while (s[*i] >= '0' && s[*i] <= '9') buf[j++] = s[(*i)++];
}
buf[j] = '\0';
return atof(buf);
}
double operate(OPERATOR op) {
if (op.opnum == 2) { // 二元
double b = popNumber(), a = popNumber();
switch (op.name) {
case '+': return a + b;
case '-': return a - b;
case '*': return a * b;
case '/': return a / b; // 原代碼此處有 bug: a+b
}
} else if (op.opnum == 1) { // 一元階乘
double n = popNumber();
double res = 1;
while (n > 1) res *= n--;
return res;
}
return 0; // 不應到達
}
原代碼 Bug 修正:除法分支寫成return num1 + num2;,已修正為a / b。
Input: 3+4*2/(1-5)!=
Output: 3.000000 // 3 + 4*2/(-4) = 3 + (-2) = 1 -> 1! = 1 ? 等等
// 實際: 3+4*2/(1-5) = 3 + 8/(-4) = 3 - 2 = 1. 1! = 1.
// 輸入 "3+4*2/(1-5)!" 應輸出 1.
^、三角函數等。