維護兩個堆疊:
valStack。op:
opStack 為空或頂端為 (,直接壓入。priority(op) > priority(top) 則壓入;否則彈出頂端運算子 topOp、彈出兩個運算元 b, a、計算 a topOp b 壓回 valStack,重複直到可壓入 op。(,直接壓入 opStack。),持續彈出計算直到遇到 ( 並丟棄它。opStack 剩餘運算子依序彈出計算。valStack 頂端即為結果。int priority(char op) {
switch (op) {
case '+': case '-': return 1;
case '*': case '/': return 2;
default: return 0;
}
}
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <math.h>
#define MAX 1024
double valStack[MAX]; int vtop = 0;
char opStack[MAX]; int otop = 0;
void pushVal(double v) { valStack[vtop++] = v; }
double popVal() { return valStack[--vtop]; }
void pushOp(char c) { opStack[otop++] = c; }
char popOp() { return opStack[--otop]; }
char peekOp() { return otop ? opStack[otop-1] : 0; }
int isEmptyOp() { return otop == 0; }
int priority(char op) {
if (op == '+' || op == '-') return 1;
if (op == '*' || op == '/') return 2;
return 0;
}
double apply(char op, double a, double b) {
switch (op) {
case '+': return a + b;
case '-': return a - b;
case '*': return a * b;
case '/': return b ? a / b : NAN;
}
return NAN;
}
double evaluate(const char *expr) {
vtop = otop = 0;
const char *p = expr;
while (*p) {
if (isspace(*p)) { p++; continue; }
if (isdigit(*p) || *p == '.') {
char *end;
double v = strtod(p, &end);
pushVal(v);
p = end;
} else if (*p == '(') {
pushOp(*p++);
} else if (*p == ')') {
while (!isEmptyOp() && peekOp() != '(') {
char op = popOp();
double b = popVal(), a = popVal();
pushVal(apply(op, a, b));
}
if (!isEmptyOp() && peekOp() == '(') popOp(); // discard '('
p++;
} else if (strchr("+-*/", *p)) {
char op = *p++;
while (!isEmptyOp() && peekOp() != '(' && priority(op) <= priority(peekOp())) {
char topOp = popOp();
double b = popVal(), a = popVal();
pushVal(apply(topOp, a, b));
}
pushOp(op);
} else {
fprintf(stderr, "Invalid char: %c\n", *p);
return NAN;
}
}
while (!isEmptyOp()) {
char op = popOp();
double b = popVal(), a = popVal();
pushVal(apply(op, a, b));
}
return popVal();
}
int main() {
char line[1024];
printf("Enter expression (empty to quit): ");
while (fgets(line, sizeof(line), stdin) && line[0] != '\n') {
line[strcspn(line, "\n")] = 0;
double ans = evaluate(line);
if (!isnan(ans)) printf("Result: %.4f\n", ans);
printf("Enter expression (empty to quit): ");
}
return 0;
}
- 前為運算子或開頭,視為一元運算子(優先序最高)。時間 O(n),空間 O(n),n 為表達式長度。