需求:支援多位數運算元、括號、優先級、冪次 (`^`),將中綴轉後綴並計算結果。
#include
using namespace std;
int prec(char op) {
if (op == '+' || op == '-') return 1;
if (op == '*' || op == '/') return 2;
if (op == '^') return 3;
return 0;
}
bool isNum(const string& t) { return !t.empty() && isdigit(t[0]); }
vector tokenize(const string& s) {
vector tok;
for (size_t i = 0; i < s.size(); ) {
if (isspace(s[i])) { ++i; continue; }
if (isdigit(s[i]) || s[i]=='.') {
size_t j = i;
while (j < s.size() && (isdigit(s[j]) || s[j]=='.')) ++j;
tok.push_back(s.substr(i, j-i));
i = j;
} else {
tok.push_back(string(1, s[i++]));
}
}
return tok;
}
vector toPostfix(const vector& infix) {
vector post;
vector st;
for (auto& t : infix) {
if (isNum(t)) post.push_back(t);
else if (t == "(") st.push_back('(');
else if (t == ")") {
while (!st.empty() && st.back() != '(') {
post.push_back(string(1, st.back())); st.pop_back();
}
if (!st.empty()) st.pop_back(); // pop '('
} else { // operator
char op = t[0];
while (!st.empty() && st.back() != '(' && prec(st.back()) >= prec(op)) {
post.push_back(string(1, st.back())); st.pop_back();
}
st.push_back(op);
}
}
while (!st.empty()) { post.push_back(string(1, st.back())); st.pop_back(); }
return post;
}
double evalPostfix(const vector& post) {
vector st;
for (auto& t : post) {
if (isNum(t)) st.push_back(stod(t));
else {
double b = st.back(); st.pop_back();
double a = st.back(); st.pop_back();
double r = 0;
switch (t[0]) {
case '+': r = a + b; break;
case '-': r = a - b; break;
case '*': r = a * b; break;
case '/': r = a / b; break;
case '^': r = pow(a, b); break;
}
st.push_back(r);
}
}
return st.back();
}
int main() {
string line;
while (getline(cin, line)) {
if (line.empty()) continue;
auto infix = tokenize(line);
auto post = toPostfix(infix);
double ans = evalPostfix(post);
cout << "後綴: ";
for (auto& t : post) cout << t << ' ';
cout << "\n結果: " << ans << "\n";
}
}
輸入: 3 + 4 * 2 / ( 1 - 5 ) ^ 2 ^ 3 後綴: 3 4 2 * 1 5 - 2 3 ^ ^ / + 結果: 3.000122
掌握「Tokenize → Shunting-yard → Stack Eval」三步曲,任意中綴算術表達式皆可精確轉換並計算。