Description
Input
每行一个表达式,数字全为int型整数,长度不超过100字符
Output
Sample Input
Sample Output
1.0000
3.0000
1.0000
-3.0000
解法一:
//即使程序写的再差,也要坚持把它写完!
/*
不同的思路,所以写出的程序也有所不同,所以并不存在好坏,没有最好的程序,只有更好的,不是别人的都比自己的好,借鉴别人的一些技巧,没必要全部模仿!
*/
#include <cstdio>
#include <cstring>
int _cp[1<<7][1<<7];
void Init()
{
memset(_cp,-1,sizeof(_cp));
_cp['+']['+']=_cp['-']['-']=_cp['+']['-']=_cp['-']['+']=0;
_cp['*']['*']=_cp['/']['/']=_cp['*']['/']=_cp['/']['*']=0;
_cp['*']['+']=_cp['*']['-']=_cp['/']['+']=_cp['/']['-']=1;//后面优先级比前面低
_cp['(']['+']=_cp['(']['-']=_cp['(']['*']=_cp['(']['/']=1;
//小技巧:对使用到的情况进行初始化
}
bool IsDigit(char c)
{
if(c>='0' && c<='9')
return 1;
return 0;
}
double operation(double f1,char c,double f2)
{
switch(c)
{
case '+':
return f1+f2;
break;
case '-':
return f1-f2;
break;
case '*':
return f1*f2;
break;
case '/':
return f1/f2;
break;
default:
break;
}
}
int main()
{
freopen("data.in","r",stdin);
const int nMax=105;
char line[nMax];
while(gets(line))
{
int len=strlen(line);
line[len]=')';
line[len+1]='\0';
double data_stack[nMax];
char ope_stack[nMax];
int data_top=-1;
int ope_top=0;
ope_stack[0]='(';
Init();
bool first=true;
for(int i=0;i<=len;)
{
if(line[i]==')')//括号中内容历编完成的情况
{
double f1,f2;
f2=data_stack[data_top--];
while(ope_top>=0 && ope_stack[ope_top--]!='(')
f2=operation(data_stack[data_top--],ope_stack[ope_top+1],f2);
data_stack[++data_top]=f2;
i++;
}
else if(IsDigit(line[i]))//扫描到数字
{
first=false;
int num=0;
while(IsDigit(line[i]))//当表达式中可为浮点数时只需要追加小数点判断就行。
{
num+=num*10+line[i]-'0';
i++;
}
data_stack[++data_top]=num;
}
else if(first && (line[i]=='+' || line[i]=='-'))//+,- 表示数的符号
{
int sign=1;
if(line[i]=='-') sign=-1;
i++;
int num=0;
while(IsDigit(line[i]))
{
num+=num*10+line[i]-'0';
i++;
}
data_stack[++data_top]=sign*num;
first=false;
}
else if(_cp[ope_stack[ope_top]][line[i]]>=0)//后面操作符优先级低于前面的情况
{
if(ope_stack[ope_top]!='(')
{
char c=ope_stack[ope_top--];
double result=operation(data_stack[data_top-1],c,data_stack[data_top]);
data_top-=2;
data_stack[++data_top]=result;
}
ope_stack[++ope_top]=line[i];
i++;
}
else
{
if(line[i]=='(')
first=true;
ope_stack[++ope_top]=line[i++];
}
}
printf("%.4lf\n",data_stack[0]);
}
return 0;
}
另一种思路(推荐):
/*
用栈转换成逆波兰式求解,这个解法较上一解法更清楚一些!推荐
主要步骤:
1)去空字符
2)初始化优先级
3)转换:其中需要注意有:
① +,- 被用作数字符号的判断
② 括号匹配中注意点
③ 运算操作
*/
#include <cstdio>
#include <cstring>
const int nMax=105;
char line[nMax];
double data_stack[nMax];
char opt_stack[nMax];
int data_top,opt_top;
int insp[1<<7],outsp[1<<7];
void init()
{
insp['#']=outsp['#']=0;
insp['(']=1;
outsp[')']=1;
outsp['(']=6;
insp['+']=insp['-']=2;
outsp['+']=outsp['-']=3;
insp['*']=insp['/']=4;
outsp['*']=outsp['/']=5;
}
void delete_blank()
{
int i,j;
for(i=0,j=0;line[i];i++)
{
if(line[i]!=' ' && line[i]!='\t')
line[j++]=line[i];
}
line[j]='\0';
}
bool is_digit(char c)
{
if(c>='0' && c<='9')
return 1;
return 0;
}
double calculate(char c)//③
{
double f2=data_stack[data_top--];
double f1=data_stack[data_top--];
switch(c)
{
case '+':
return data_stack[++data_top]=f1+f2;
break;
case '-':
return data_stack[++data_top]=f1-f2;
break;
case '*':
return data_stack[++data_top]=f1*f2;
break;
case '/':
return data_stack[++data_top]=f1/f2;
break;
default:
break;
}
}
double exchange()
{
int len=strlen(line);
for(int i=0;i<len;i++)
{
if((line[i]=='+' || line[i]=='-') && (i==0 || line[i-1]=='('))
data_stack[++data_top]=0;//①
if(is_digit(line[i]))
{
double num=0;
while(is_digit(line[i++]))
num+=num*10+line[i]-'0';
data_stack[++data_top]=num;
i--;
}
else if(insp[opt_stack[opt_top]]<outsp[line[i]])
opt_stack[++opt_top]=line[i];
else
{
do
{
calculate(opt_stack[opt_top--]);
}while(insp[opt_stack[opt_top]]>outsp[line[i]]);
if(opt_stack[opt_top]!='(')
opt_stack[++opt_top]=line[i];
else
opt_top--;//②
}
}
while(opt_stack[opt_top]!='#')
calculate(opt_stack[opt_top--]);
return data_stack[0];
}
int main()
{
freopen("data.in","r",stdin);
init();
while(gets(line))
{
delete_blank();
data_top=opt_top=-1;
opt_stack[++opt_top]='#';
printf("%.4f\n",exchange());
}
return 0;
}
/*
解法二:使用递归实现,很不错的解法。
推荐!
*/
#include <cstdio>
#include <cstring>
const int nMax=105;
char line[nMax];
void init()
{
int i,j;
for(i=j=0;line[i];i++)
if(line[i]!=' ' && line[i]!='\t')
line[j++]=line[i];
line[j]='\0';
}
bool is_num(int l,int r)
{
for(int i=l;i<=r;i++)
if(line[i]<'0' || line[i]>'9')
return false;
return true;
}
double calculate(int l,int r)
{
int i;
if(l>r) return 0;
if(is_num(l,r))
{
/*double num=0;
for(i=l;i<=r;i++)
num=num*10+line[i]-'0';
return num;*/
//方法二:
double num;
sscanf(line+l,"%lf",&num);
return num;
}
int p;
//只需要保证先加减后乘除即可
for(p=0,i=l;i<=r;i++)
{
if(line[i]=='(') p++;
else if(line[i]==')') p--;
if(!p && line[i]=='+')
return calculate(l,i-1)+calculate(i+1,r);
}
//for(p=0,i=r;i>=l;i--)//无需逆向搜索
for(p=0,i=l;i<=r;i++)
{
if(line[i]=='(') p++;
else if(line[i]==')') p--;
if(!p && line[i]=='-')
return calculate(l,i-1)-calculate(i+1,r);
}
for(p=0,i=1;i<=r;i++)
{
if(line[i]=='(') p++;
else if(line[i]==')') p--;
if(!p && line[i]=='*')
return calculate(l,i-1)*calculate(i+1,r);
}
//for(p=0,i=r;i>=0;i--)
for(p=0,i=l;i<=r;i++)
{
if(line[i]=='(') p++;
else if(line[i]==')') p--;
if(!p && line[i]=='/')
return calculate(l,i-1)/calculate(i+1,r);
}
return calculate(l+1,r-1);
}
int main()
{
freopen("e:\data.in","r",stdin);
while(gets(line))
{
init();
printf("%.4lf\n",calculate(0,strlen(line)-1));
}
return 0;
}
分享到:
相关推荐
非常完美的表达式求值课程设计非常完美的表达式求值课程设计非常完美的表达式求值课程设计非常完美的表达式求值课程设计非常完美的表达式求值课程设计非常完美的表达式求值课程设计非常完美的表达式求值课程设计非常...
利用栈编写表达式求值程序:输入含有“+”、“-”、“*”、“/”四则运算的表达式,其中负数要用(0-正数)表示,并以=结束。要求输出表达式的值(两运算符号的优先关系见教材表3.1)。此题目可选做。 Input 第一...
字符串表达式求值 输入类似1+2+3,6*5/7的字符串,计算出值
C++实现表达式求值 本实验要求设计一个算术表达式求值的程序,该程序必须可以接受包含(,),+,-,*,/,%,和^(求幂运算符,a^b=ab )的中缀表达式,并求出结果。如果表达式正确,则输出表达式的结果;如果表达式非法...
表达式求值
数据结构栈实现表达式求值数据结构栈实现表达式求值数据结构栈实现表达式求值数据结构栈实现表达式求值
算术表达式求值算术表达式求值算术表达式求值算术表达式求值
表达式求值 算法 代码 报告 流程图表达式求值 算法 代码 报告 流程图表达式求值 算法 代码 报告 流程图
用栈的方法实现表达式求值,代码结构清晰,很容易读懂,适合初学者学习,100%原装代码。
实验题目: 基于栈的算术表达式求值算法 实验环境: 学习完了数据结构第三章内容栈和队列 实验目的: 1.掌握栈的定义及实现; 2.掌握利用栈求解算术表达式的方法。 实验内容: 通过修改完善教材中的算法...
栈实现表达式求值
表达式求值(中缀变前缀,中缀变后缀,前缀求值,后缀求值) 任务调度(基于时间,优先级)
表达式求值程序,希望可以给在学习C语言的童鞋们提供一些帮助。
表达式求值,用二叉树来表示以后,进行遍历求解。
严蔚敏数据结构 表达式求值 c语言实现 符号优先级
C++用栈实现表达式求值,经过验收的,可以运行,没有问题
表达式求值,用栈实现,C++,支持符号、括号、以及出错处理,程序健壮性应该比较好,本人自己编写,上传的压缩包中有一个运行环境为VS2005,另一个运行环境为VC6.0的源文件,可根据自己电脑的运行环境自行选择
数据结构 严蔚敏 表达式求值 c代码实现
该程序很好实现了算术表达式求值,支持+、-、*、/,以=结束,符合正常表达式。
采用对文件的操作。和很多表达式求值的程序相比本程序最大特点是成功地解决了对float型和乘方的运算。