解法细节说明:
分析:这一算式用str保存,然后用op和in两个栈存运算符和数,数可以是中途加减操作过的数。
编写一个判断数字还是操作符的函数,在起始时顺便返回标记,以便下面一操作。
op栈在入栈的时候,函数判断过之后,注意对起始位置的入栈。
这时要说一下运算级别,就是优先级,首先,标识符在左,则任何的运算符都大于它,反之一样,以0 1234代表起始和4个基本操作。即:
1 0 0 0 0
1 0 0 0 0
1 0 0 0 0
1 1 1 0 0
1 1 1 0 0 值得注意的细节是,0,0位置的数,请看: (6+8+9)这时候第二个加法一定要比第一个加法优先级小,然后让前面两个6+8算出来,而如果是()两个起始的比较,)一定要比(的优先级大才可以存入,以便结束的判断。
之后看数字就入栈,是运算符时栈为空,或者优先级大就存栈,或者结束。
#include<stdio.h>
#include<iostream>
#include<stack>
using namespace std;
char str[100];
int mat[5][5] = {
1,0,0,0,0,
1,0,0,0,0,
1,0,0,0,0,
1,1,1,0,0,
1,1,1,0,0,
};
stack<int>op;
stack<double> in;
void get(bool &o,int &n,int &i){
if(i == 0 && op.empty() == true)
{
o = true;
n = 0;
return;
}
if(str[i] == 0){
o = true;
n = 0;
return;
}
if(str[i]>='0'&&str[i]<='9'){
o = false;
}
else{
o = true;
if(str[i]=='+') n = 1;
if(str[i]=='-') n = 2;
if(str[i]=='*') n = 3;
if(str[i]=='/') n = 4;
i+=2;//跳过空格
return;
}
n = 0;
for(;str[i]!=' '&&str[i]!=0;i++){
n*=10;
n+=str[i] - '0';
}
if(str[i]==' ')
i++;//弥补数字判断没有对空格的跳跃++
return;
}
int main(){
while(gets(str)){
if(str[0]=='0'&&str[1]==0) break;
bool stro;
int strn;
int i = 0;
while(!op.empty()) op.pop();
while(!in.empty()) in.pop();
while(true){
get(stro,strn,i);//i很重要,要传入去,函数为局部变量
if(stro == false) in.push((double)strn);
else{//这一位为操作符
double tmp;
if(op.empty()==true||mat[strn][op.top()] == 1){
op.push(strn);//不计算算数
}
else{//操作符的优先级小与栈内,立马运算
while(mat[stro][op.top()]==0)//一直算到起始,优先级最小,即操作符的优先级大于栈内
{
int top = op.top();
op.pop();
double b = in.top();
in.pop();
double a = in.top();
in.pop();
if(top==1) tmp = a+b;
else if(top==2) tmp = a-b;
else if(top==3) tmp = a*b;
else if(top==4) tmp = a/b;
in.push(tmp);
}//算完,记得存新运算符
op.push(strn);
}
}
if(op.size()==2&&op.top()==0) break;
}
cout<<in.top()<<endl;
}
}
这代码量难以想象在半小时内竟然可以完成,总有些小细节忘记,还是先把草稿打好再写为妙。