博前感想:
表达式求值比较难理解,特别是各种表达式的优先级需要自己设计,还要看自己怎么把这个优先级的比较关系带入到程序里面。这里我门可以自己写一个简单的栈,也可以调用系统自带的#include<stack>。
代码块:
#include <iostream>
#include <string>
#include <cmath>
#include <stack> //stack有top(获取站顶),push(进入站),pop函数(出战)
using namespace std;
stack <char> optr; //运算控制符
stack <int> optn; //数字站
int zuobiao(char ch) //获取坐标给上面的函数来选择优先级
{
int biao=0;
switch(ch)
{
case'+':
biao=0;break;
case'-':
biao=1;break;
case'*':
biao=2;break;
case'/':
biao=3;break;
case'(':
biao=4;break;
case')':
biao=5;break;
case'$':
biao=6;
default:break;
}
return biao;
}
char quyou(char ch2,char ch1) //运算符间的优先级关系
{
const char youxian[7][7]=
{
{ '>','>','<','<','<','>','>' },
{ '>','>','<','<','<','>','>' },
{ '>','>','>','>','<','>','>' },
{ '>','>','>','>','<','>','>' },
{ '<','<','<','<','<','=','0' },
{ '>','>','>','>','0','>','>' },
{ '<','<','<','<','<','0','=' },
};
int biao1,biao2;
biao1=zuobiao(ch1);
biao2=zuobiao(ch2);
return youxian[biao1][biao2];
}
int cal(int a,char c,int b)
{
switch(c)
{
case'+':
return b+a; //顺序不能换
case'-':
return b-a;
case'*':
return b*a;
case'/':
return b/a;
default:
break;
}
return 0;
}
int jisuan()
{
optr.push('$'); //运算符站先推入一个'$'
int i=0; //i用于统计数字的位数
char h;
h=getchar(); //一开始的h用getchar进去判断是运算符还是数字
while(h!='$'||optr.top()!='$') //这种循环无需控制次数了
{
if(h>='0'&&h<='9') //一开始先转入else,i就是1,如果下一位还是数字,转入if,接下来还是数字还是转入if
{
if(i==1) //读入了一个数字发现是多位数,x用来存储原来已经进去的数字
{
int x=optn.top();
optn.pop();
optn.push(10*x+(h-'0'));
i=1; //把i=1控制可以循环多次,知道h不是数字为值
}
else //说明是个位数
{
optn.push(h-'0');
i++;
}
h=getchar(); //再次读入
}
else //输入h的不是数字的情况
{
int a=0;int b=0;char w;i=0;
switch(quyou(h,optr.top())) //h是已经在站里面的运算符
{
case'<':
//w=optr.top();optr.pop();
//a=optn.top();optn.pop();
//b=optn.top();optn.pop();
//cal(a,w,b);
//optn.push(cal(a,w,b));
optr.push(h);
h=getchar();
break; //break出这个else直接回到while
case'=': //托括号在接受下一个字符
optr.pop();
h=getchar();
break; //同理
case'>':
//h=getchar();
//optn.push(h);
w=optr.top();optr.pop();
a=optn.top();optn.pop();
b=optn.top();optn.pop();
cal(a,w,b);
optn.push(cal(a,w,b)); //把运算结果放入站内
}
}
//optn.top();
}
return optn.top(); //top的括号不能忘了
//cout<<optn.top();
}
int main()
{
cout<<"请输入要算的表达式的个数:"<<endl;
int n; // 需要计算的表达式的个数
cin>>n;
cout<<"请输入"<<n<<"个表达式"<<"但是不能连续输入"<<n<<"个表达式:"<<endl;
getchar(); //读入输入的表达式
while(n!=0)
{
while(!optr.empty()) {optr.pop();} //非空的栈就把里面的东西取出来
while(!optn.empty()) {optn.pop();}
int q=jisuan();
cout<<"计算结果为:"<<endl;
cout<<q<<endl;
getchar(); //用于输入下一个表达式并且读入getchar中
n--;
}
return 0;
}
这个实验主要是为了加深对栈的理解。