用栈来实现表达式的计算

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

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

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

#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 '=';
	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 '<';
}

//用于计算数值,随后放回栈中
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
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值