受大一学妹沈灵邀请,编了一个计算算术表达式的程序,主要运用栈来实现,具体思想参照,《数据结构》胡学刚,张晶主编第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+#等。希望以后有时间尽量完善。