这个题目是大部分人都是用栈来写的,本周训练老师也讲了两次栈的原理。自己最近也看了数据结构中与栈有关的内容,还是比较深刻理解了没有括号情况下表达式求解。
#include<stdio.h>
#include<string.h>
#include<stack>
using namespace std;
char s[250],post[250];//s是输入的中缀表达式,post是转化出来的后缀表达式
stack<char>op;//存放运算符
stack<double>num;//存放运算过程中的数字
int isnum(char c)//判断字符是否为数字
{
if(c>='0'&&c<='9')
return 1;
return 0;
}
double opmode(char c)//运算符优先级判定
{
if(c=='+') return 1;
if(c=='-') return 2;
if(c=='*') return 3;
if(c=='/') return 4;
return -1;
}
void change()//将中缀表达式转化为后缀表达式
{
int i,j=0,len;
memset(post,0,sizeof(post));
len=strlen(s);
for(i=0; i<len; i++)
{
if(s[i]==' ') continue;
post[j++]=' ';//空格是关键,主要是区分数字用的,出现俩个连续的1会当成11,而不是两个1
while(isnum(s[i])) post[j++]=s[i++];
int c=opmode(s[i]);
//当前运算的与栈顶运算符号进行比较
if(c!=-1)
{
if(c<=2)//优先级小于等于栈顶的运算符时,将栈顶的运算符输入到数组中
{
while(!op.empty())//因为+-遇到任何一个栈内符号都会小于或等于,所以将所有运算符输出
{
post[j++]=op.top();
op.pop();
}
}
else
{
while(!op.empty()&&opmode(op.top())>2)//栈顶运算符是*/时,才将栈顶的输出
{
post[j++]=op.top();
op.pop();
}
}
op.push(s[i]);//优先级大时或者上面操作后将当前运算符入栈
}
}
while(!op.empty())//对象处理完毕将栈中存留的运算符一并输出
{
post[j++]=op.top();
op.pop();
}
}
double cal()//计算后缀表达式
{
while(!num.empty()) num.pop();//清空栈
int i=0,len;
len=strlen(post);
for(i=0;i<len;i++)
{
if(post[i]==' ') continue;
double cur=0;
bool hasnum=0;
while(isnum(post[i]))//提取数字
{
cur*=10;
cur+=post[i]-'0';
hasnum=1;
i++;
}
if(hasnum) num.push(cur);
if(opmode(post[i])!=-1)//遇到运算符,提取栈顶两个数字进行计算
{
double n1=num.top();
num.pop();
double n2=num.top();
num.pop();
switch(post[i])
{
case '+':num.push(n1+n2);break;
case '-':num.push(n2-n1);break;
case '*':num.push(n1*n2);break;
case '/':num.push(n2/n1);break;
}
}
}
return num.top();//输出答案
}
int main()
{
while(gets(s))
{
if(strcmp(s,"0")==0) break;
change();
printf("%.2f
",cal());
}
return 0;
}
版权声明:本文为博主原创文章,未经博主允许不得转载。http://xiang578.top/