用栈来实现表达式的计算

来源:互联网 发布:linux recv函数 编辑:程序博客网 时间:2024/05/16 06:51

栈可以用来实现表达式的计算 分别用两个栈来存储运算符合运算数,默认#变成表达式的结束操作,现在运算符栈中放入一个#建,以便于后面的匹配,然后遍历

字符串,若是运算符,则与运算符的头元素进行比较,优先级高,则运算数拿出两个,与运算符的头元素进行运算,随后入运算数的栈,在这里没搞明白为什么这个】

遍历到的字符串不用入运算符的栈,若是等于,则表示括号匹配,运算符里面出一个元素,若是小于,则运算符入栈,总体就是这么一个流程

#include<iostream>#include<stack>#include<string>#include<cstring>using namespace std;stack<char>Optr;//用于寄存运算符stack<double>Opnd;//用于寄存操作数或运算结果,运算结果有可能是浮点数string Exepression;//用于存放表达式//比较运算符的优先级char Compare(char a, char b)            //返回两算符a和b的优先级关系{if ('#' == a)if ('#' == b)return '=';elsereturn '<';if ('+' == a || '-' == a)if ('*' == b || '/' == b || '(' == b)return '<';elsereturn '>';if ('*' == a || '/' == a)if ('(' == b)return '<';elsereturn '>';if ('(' == a)if (')' == b)return '=';elsereturn '<';}//用于计算数值,随后放回栈中double Calculate(double a, double b, char fuHao) {switch (fuHao){case '+':return a + b;case '-':return a - b;case '*':return a * b;case '/':return a / b;default:break;}}//在字符串中找是不是数字还是运算符bool isOptr(char c) {//下面这种字符串从未用过,先敲着再说//static string operator("+-*/()#");//if (operator.find(c) == string::npos)//return false;//找到末尾都没有找到,就是数字//return true;是算符 *以上这段是从别人那里抄来的,因此自己大意还没搞明白if (c == '+' || c == '-' || c == '/' || c == '*')return true;return false;}//用于计算的过程 核心代码 用于求值的过程double EvaluateExpression() {//表达式的末尾是‘#’,表示结束int i = 0, j = 0, num = 0;while (Exepression[i] != '#' || Optr.top() != '#') {//如果不是运算符,则计算出数字if (!isOptr(Exepression[i])) {num = 0;while (!isOptr(Exepression[i])) {num *= 10;num += Exepression[i] - '0';++i;}Opnd.push(num);}else {switch (Compare(Optr.top(), Exepression[i])) {//若是<,则运算符优先级较低,将符号放进运算符栈中case '<':Optr.push(Exepression[i]);++i;break;//若是等号的话,则脱括号case '=':Optr.pop();++i;break;//若是>的话,则把数字栈的头两个值给拿出来,进行计算,随后再把计算好的结果放进数字栈中case'>':double a = Opnd.top();Opnd.pop();double b = Opnd.top();Opnd.pop();//这里在除法的时候会出错,因为a-b是先a在栈里,所以,应该顺序换一下Opnd.push(Calculate(b, a, Optr.top()));Optr.pop();break;}}}//最后放入#已进行匹配,来匹配运算符的结束Optr.push('#');double res = Opnd.top();Opnd.pop();return res;}int main() {//先在运算符数组中放入一个运算符#以便与最后的进行匹配,最后输入的字符串也要输入#cin >> Exepression;Optr.push('#');cout << EvaluateExpression();return 0;}
先贴上自己的代码,但有bug,以后再改

然后贴上正确的代码

#include <iostream>#include <string>#include <cstring>#include <stack>using namespace std;stack<int> opnd;        //操作数栈 stack<char> optr;        //算符栈 char expression[100];    //用于盛放表达式 char Compare(char a, char b);            //返回两算符a和b的优先级关系 int Calculate(int a, int b, char op);    //返回计算结果 int EvaluateExpression();                //求值过程 bool IsOptr(char c);                    //是否是算符 int main(){    optr.push('#');                        //在表达式最左边增设一个'#'构成整个表达式的一对'#'     while(scanf("%s", expression) != EOF)        cout<<"Result:"<<EvaluateExpression()<<endl;        return 0; }char Compare(char a, char b)            //返回两算符a和b的优先级关系{    if('#' == a)        if('#' == b)            return '=';        else             return '<';        if('+'==a || '-'==a)        if('*'==b || '/'==b || '('==b)            return '<';        else             return '>';        if('*'==a || '/'==a)        if('(' == b)            return '<';        else             return '>';                    if('(' == a)        if(')' == b)            return '=';        else            return '<';}int Calculate(int a, int b, char op)    //返回计算结果 {    switch(op)    {        case '+':            return a+b;        case '-':            return a-b;        case '*':            return a*b;        case '/':            return a/b;                }}bool IsOptr(char c)                {    static string oprator("+-*/()#");    if(oprator.find(c) == string::npos)        return false;    //不是算符     return true;        //是算符 }int EvaluateExpression()                //求值过程{    int i=0, num=0;    while(expression[i]!='#' || optr.top()!='#')    {            if(!IsOptr(expression[i]))        {    //不是算符,则是操作数             num = 0;            while(!IsOptr(expression[i]))            {    //求得此操作数                 num *= 10;                num += expression[i]-'0';                ++i;                }            opnd.push(num);        }        else        {            switch(Compare(optr.top(), expression[i]))            {                case '<':                    optr.push(expression[i]);                    ++i;                    break;                case '=':                    optr.pop();                    ++i;                    break;                case '>':                    int a = opnd.top(); opnd.pop();                    int b = opnd.top(); opnd.pop();                    opnd.push(Calculate(b, a, optr.top()));    //注意这里a和b的顺序                     optr.pop();                    break;                }            }    }        optr.push('#');        //在表达式最左边增设一个'#'构成整个表达式的一对'#'     int res=opnd.top();    opnd.pop();    return res;}


很奇怪的是在vs上面竟然不能运行,但在DEV上能运行

0 0