背景:
在严蔚敏版《数据结构》教材中已经介绍了表达式求值的算法,现在我们将该算法的功能进行扩展,要求可以处理的运算符包括:+、-、*、/、%(整数取余)、^(乘方)、(、)。
要求:
采用算符优先算法,计算的中间结果只保留整数。
输入:
第一行为整数N。表示下面有N个表达式
从第二行起的后面N行为N个由整数构成的表达式
输出:
共N行,每行为相应表达式的计算结果。
如果判断出表达式有错误,则输出:error.
如果在计算过程中出现除数为0的情况,则输出:Divide 0.
特殊情况说明:
在表达式中,如果操作数出现负数(例如-8),则要特别注意。例如:
10加-8表示为:10+-8。
10减-8表示为:10--8。
测试输入
4 2^3 2^0 2^3^2 2^(3-1)^(10-8)
11 (2+8 2+8) 8/0 8/(8+5-13) 2^(2-5) 10-(80-30(/3*3+4 10-80-30)/3*3+4 (2+8)(3+2) (2)3(8) 30(/3+3)+4 10(20-8)+2
测试输出
8 1 512 16
error. error. Divide 0. Divide 0. error. error. error. error. error. error. error.
源代码
#include <stdio.h>
#include <math.h>
#include <string.h>
char yunsuanshi[100], *p; //运算式存储字符串,运算式当前读取位置
struct t // 建立符号栈
{ char dat[100];
int top;
}prt;
struct d //建立数字栈
{ long int dat[100];
int top;
}prd;
char Prior[9][9]= //优先级列表
{ {'>','>','<','<','<','<','<','>','>'},
{'>','>','<','<','<','<','<','>','>'},
{'>','>','>','>','<','<','<','>','>'},
{'>','>','>','>','<','<','<','>','>'},
{'>','>','>','>','>','<','<','>','>'},
{'>','>','>','>','>','<','<','>','>'},
{'<','<','<','<','<','<','<','=',' '},
{'>','>','>','>','>','>',' ','>','>'},
{'<','<','<','<','<','<','<',' ','='}
};
void pushd(long int a){ //数字入栈
prd.dat[prd.top++]=a;
}
void pusht(char a){ //符号入栈
prt.dat[prt.top++]=a;
}
int popd( ){ //数字出栈
return prd.dat[--prd.top];
}
char popt( ){ //符号出栈
return prt.dat[--prt.top];
}
int numble ( ){ //数字整理
long int b=0;
do{
b = b*10 + *p -'0';
p++;
}
while( *p>='0' && *p<='9' ) ;
return b;
}
int operation ( int x, char a, int y) { // 数学运算
switch(a){
case '+': return x+y;
case '-': return x-y;
case '*': return x*y;
case '/': if ( y )
return x/y;
else{
printf("Divide 0.\n");
return 0;
}
case '%': return (int) fmod(x,y);
case '^': if (y>=0 )
return (int) pow(x,y);
else
return 0;
default: printf("error. \n");
return 0;
}
}
int signswitch ( char a ){ //符号转换
char signs[]={ '+', '-', '*', '/', '%', '^', '(', ')', '#', '\0' };
int k;
k = 0;
while ( signs[k]!='\0' && signs[k] != a )
k++;
if ( signs[k] == a )
return k;
else
return -1;
}
char refusal ( char a,char b ) { // 判定优先级
return Prior[signswitch(a)][signswitch(b)];
}
int main( )
{ int j, k, l;
int flag=0; //flag=0表示前一个符号不是)
int n;
char b;
prt.dat[0]='#';
prt.top=1;
prd.top=0;
scanf("%d",&n);
for(int i=1;i<=n;i++){
k:;
printf ("");
scanf("%s", yunsuanshi); // 接收运算式
strcat( yunsuanshi, "#" ); //在运算式结尾加#号
p = yunsuanshi;
while ( *p!='#' || prt.dat[prt.top-1]!='#' ){
if ( *p>='0' && *p<='9')
pushd(numble());
else { //如果是符号与栈顶的符号比较并运算
if ( flag==1 && *p=='(' ){
printf("error.\n");
return 1;
}
else if ( *p==')')
flag=1;
else
flag=0;
switch ( refusal(prt.dat[prt.top-1], *p ) ){ // 当前运算符优先级高则运算符入栈
case '<':
pusht ( *p++ ); //处理下一个字符
break;
case '=':
popt( ); //脱括号
p++;
break;
case '>':
b=popt( ); // 当前运算符优先级低则进行栈顶计算
k=popd(); //第二操作数出栈
l=popd(); //第一操作数出栈
k=operation(l,b,k); //计算
pushd(k); //计算结果入栈
break;
case ' ':
printf("error.\n");
goto k;
return 1;
}
}
}
if(prd.dat[prd.top-1]!=0)
printf("%d\n",prd.dat[prd.top-1]); // 输出结果
}
return 0;
}
部分案例可能通不过!!!