《數據結構》中表達式求值的經典算法是用兩個棧,一個存數字,一個存運算符。依次讀入表達式中的每一個字符,如果數字則進數字棧,如果運算符則和運算符棧的棧頂運算符比較優先權做相應操做,直至整個表達式求值完畢。運算符的優先級表以下ios
+ | - | * | / | ( | ) | # | |
+ | > | > | < | < | < | > | > |
- | > | > | < | < | < | > | > |
* | > | > | > | > | < | > | > |
/ | > | > | > | > | < | > | > |
( | < | < | < | < | < | = | |
) | > | > | > | > | > | > | |
# | < | < | < | < | < | =算法 |
學了編譯原理後,發現能夠用遞歸降低分析來求表達式的值。表達式的文法以下express
<Expr> -> <Term> { (+|-) <Term> }
<Term> -> <Factor> { (*|/) <Factor> }
<Factor> -> (<Expr>) | num數據結構
按照遞歸降低分析的技巧,每個非終結符寫一個函數ide
#pragma once #include<string> using namespace std; /************************************************************************/ /* 文法以下 <Expr> -> <Term> { (+|-) <Term> } <Term> -> <Factor> { (*|/) <Factor> } <Factor> -> (<Expr>) | num /************************************************************************/ class Calculator { public: Calculator(string &str); ~Calculator(); double calculate() { return ans; } double ans; //表達式的值 private: int cur; //目前的位置 string str; double expression(); double term(); double factor(); };
#include "Calculator.h" #include<stdlib.h> Calculator::Calculator(string & str) :str(str),cur(0),ans(0) { ans = expression(); } Calculator::~Calculator() { } double Calculator::expression() { double num1 = term(); double num2; while (str[cur] == '+' || str[cur] == '-') { char op = str[cur++]; //運算符 num2 = term(); if (op == '+') num1 += num2; else if (op == '-') num1 -= num2; } if (str[cur] == ')') ++cur; //factor遇到'('會調用此函數,所以要吃掉')' return num1; } double Calculator::term() { double num1 = factor(); double num2; while (str[cur] == '*' || str[cur] == '/') { char op = str[cur++] ; num2 = factor(); if (op == '*') num1 *= num2; else if (op == '/') num1 /= num2; } return num1; } double Calculator::factor() { char tmp = str[cur]; double result = tmp - '0'; ++cur; if (tmp == '(') return expression(); else {//取數字 int flag = 0;//0爲小數點以前,1位小數點以後 double temp = 10; while (str[cur] >= '0' && str[cur] <= '9' || str[cur]=='.') { if (str[cur] == '.') { ++cur; flag = 1; } else { if (!flag)//小數點以前 result = result * 10 + str[cur] - '0'; else { result = result + double(str[cur] - '0') / temp; temp *= 10; } ++cur; } } return result; } }
main函數函數
#include <iostream> #include "Calculator.h" using namespace std; int main() { string str; cin >> str; Calculator cal(str); cout << cal.calculate() << endl; }
運行結果:spa