算术表达式的计算(栈的应用)

受大一学妹沈灵邀请,编了一个计算算术表达式的程序,主要运用栈来实现,具体思想参照,《数据结构》胡学刚,张晶主编第2章栈的应用

首先,我们建立两个栈,一个用来保存数字,一个用来保存字符。对于输入的字符串,每当遇到数字就将其放入到数字栈中,遇到运算符或者括号就将其放入到字符栈中。

在程序的开始我写了一个函数,用来实现求取操作符的优先级。对于'+','-','*','/','(',')','#'分别定义它们的优先级。

在主程序中,首先声明两个栈,然后对于用户输入的字符串#....#的格式,首先是将第一个#入栈,紧接着,判断是否是数字,如果是数字的话,就将其放入数字栈,这里要注意屏幕上输入的数字应该是其对应的ASC2码,比如,输入2的话,对应的值是2+'0'=50.这里还有一点要注意,就是处理多位数的情况,当第一个数字的位数多于一位,要判断后面的数是不是数字,不断地进行循环操作。比如输入12,处理到1,保存到num=1,处理到2,num = num*10+2 = 12.

如果不是数字的话,判断当前的字符的优先级和栈顶元素的优先级大小,如果前者大于后者,直接入栈,否则弹出字符栈的栈顶元素和数字栈的前两个元素,运算之后将结果压入数字栈,然后再判断当前字符的优先级和栈顶元素优先级的大小,循环操作。这里也有几点要注意,第一,碰到'('直接入栈,不需要比较。第二,栈顶元素为'(',当前字符为')直接弹栈。第三,当#号遇到#号,你懂的,直接弹栈。最后将当前操作符压栈。

最后将数字栈内的元素弹出,也就是唯一的一个栈顶元素。

#include <iostream>
#include <stack>
using namespace std;

int get_priority(char c){      //得到运算符的优先级
    if(c=='#')	return 0;
    if(c==')'||c=='(')  return 1;
    if(c=='+'||c=='-')	return 2;
    if(c=='*'||c=='/')	return 3;
    return -1;
}

int main(){
    stack<int>int_s;     //存放数字的栈
    stack<char>char_s;   //存放运算符、括号的栈
    string str;         //待输入的表达式
    cin>>str;
    for(int i=0;i<str.length();i++){
        if(i==0){
            char_s.push(str[i]);          //将第一个"#"入栈
            continue;
        }
        int num;
        int j=0;
        if(str[i]>='0'&&str[i]<='9')     //判断若是数字,把数字入栈.处理一位或者多位数字的情况
        {
            num = str[i] - '0';
            j = i+1;
            while(str[j]>='0'&&str[j]<='9'){
                num = num*10 + (str[j]-'0');
                j++;
            }
            i = j-1;
            int_s.push(num);
        }
        else{
            if(str[i]=='('){     //第一次遇到左括号直接入栈
                char_s.push(str[i]);
                continue;
            }
            if(get_priority(str[i])>get_priority(char_s.top())){   //当前运算符的优先级大于栈顶符号的优先级,入栈
                char_s.push(str[i]);
            }
            else{
                //当前运算符等于或者小于栈顶符号的优先级,则将数字弹出计算,再压栈
                do{
                    int a = int_s.top();
                    int_s.pop();
                    int b = int_s.top();
                    int_s.pop();
                    char ch = char_s.top();
                    char_s.pop();
                    int result;
                    if(ch == '-')	result = b - a;
                    if(ch == '+')	result = b + a;
                    if(ch == '*')	result = b * a;
                    if(ch == '/')	result = b / a;
                    int_s.push(result);      //将结果压栈
                }while(get_priority(char_s.top())>get_priority(str[i]));
                if(str[i] == ')'&&char_s.top()=='('){   //左右括号对应则将栈内左括号弹出
                    char_s.pop();
                    continue;
                }
                if(str[i] == '#'&&char_s.top()=='#'){
                    char_s.pop();
                    continue;       //结束本轮循环
                }
                char_s.push(str[i]);       //将运算符入栈
            }
        }    
    } 
    cout<<"计算结果为:"<<int_s.top()<<endl;
    return 0; 
}




当前,程序还有很多不完善的地方,运算符只有+,-,*,/四个,而且对于用户输入的错误表达式还不能很好的处理,比如#3+#等。希望以后有时间尽量完善。


  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值