利用栈求表达式的值.docx
《利用栈求表达式的值.docx》由会员分享,可在线阅读,更多相关《利用栈求表达式的值.docx(15页珍藏版)》请在冰豆网上搜索。
利用栈求表达式的值
利用栈求表达式的值
编写程序实现表达式求值,即验证某算术表达式的正确性,若正确,则计算该算术表达式的值。
主要功能描述如下:
1、从键盘上输入表达式。
2、分析该表达式是否合法:
(1)是数字,则判断该数字的合法性。
若合法,则压入数据到堆栈中。
(2)是规定的运算符,则根据规则进行处理。
在处理过程中,将计算该表达式的值。
(3)若是其它字符,则返回错误信息。
3、若上述处理过程中没有发现错误,则认为该表达式合法,并打印处理结果。
程序中应主要包含下面几个功能函数:
voidinitstack():
初始化堆栈
intMake_str():
语法检查并计算
intpush_operate(intoperate):
将操作码压入堆栈
intpush_num(doublenum):
将操作数压入堆栈
intprocede(intoperate):
处理操作码
intchange_opnd(intoperate):
将字符型操作码转换成优先级
intpush_opnd(intoperate):
将操作码压入堆栈
intpop_opnd():
将操作码弹出堆栈
intcaculate(intcur_opnd):
简单计算+,-,*,/
doublepop_num():
弹出操作数
源代码:
#include
#include
#include
#include
#defineMAXSIZE100
#defineN1000
inti=0; //表达式数
typedefstructexpression//表达式结构
{
longdoubleresult;
charexpstr[MAXSIZE];
}expression;
expressionexpr[N];//表达式的一个整体容器s
typedefstruct//操作码栈定义
{
charcode[MAXSIZE];
inttop;
}opnd;
typedefstruct//操作数栈定义
{
doubledate[MAXSIZE];
inttop;
}num;
//《——opnd栈操作——》:
voidinitstack(opnd*op)//初始化栈
{
op->top=-1;
}
intempty_opnd(opnd*op)//判空
{
if(op->top==-1)
return0;
elsereturn1;
}
intpush_opnd(opnd*op,charco)//压栈
{
if(op->top==MAXSIZE-1)
{
printf("The\"opnd\"stackisfull.");
return0;
}
op->top++;
op->code[op->top]=co;
return1;
}
charpop_opnd(opnd*op)//出栈
{
chara='\0';
if(op->top==-1)
{
printf("error:
The\"opnd\"stackisempty.");
returna;
}
a=op->code[op->top];
op->top--;
returna;
}
charget_opnd(opnd*op)//查看栈顶
{
chara='\0';
if(op->top==-1)
{
printf("error:
The\"opnd\"stackisempty.");
returna;
}
else
returnop->code[op->top];
}
//《——num栈操作——》:
voidinitstack(num*nu)
{
nu->top=-1;
}
intempty_num(num*nu)//判空
{
if(nu->top==-1)
return0;
elsereturn1;
}
intpush_num(num*nu,doubleda)//压栈
{
if(nu->top==MAXSIZE-1)
{
printf("error:
The\"date\"stackisfull.");
return0;
}
nu->top++;
nu->date[nu->top]=da;
return1;
}
doublepop_num(num*nu)//出栈
{
doublea='\0';
if(nu->top==-1)
{
printf("error:
The\"date\"stackisempty.");
returna;
}
a=nu->date[nu->top];
nu->top--;
returna;
}
doubleget_num(num*nu)//查看栈顶
{
if(nu->top!
=-1)
returnnu->date[nu->top];
}
//《——结束栈定义操作——》
//《——函数操作——》:
intchange_opnd(charcode)//将字符型操作码转换成优先级,非表达式字符反回-2
{
switch(code)
{
case'=':
return1;break;
case')':
return2;break;
case'+':
return3;break;
case'-':
return3;break;
case'*':
return4;break;
case'/':
return4;break;
case'(':
return0;break;//操作码级别>=0;
case'1':
case'2':
case'3':
case'4':
case'5':
case'6':
case'7':
case'8':
case'9':
case'0':
case'.':
return-1;//操作数级别=-1;
default:
return-2;//其它符号级别=-2
}
}
charprocede(chartop,charcode)//处理操作码,判断栈的操作
{
if(change_opnd(code)==0)//“(”入栈
return('<');
else
if(change_opnd(code)==2&&change_opnd(top)==0)//“(”和“)”同时出现,“(”出栈,“)”不入栈
return('=');
else
if(change_opnd(code)<=change_opnd(top))//弹出两个数字和一个符号进行计算
return('>');
else
return('<');//入栈
}
doublechange_num(charstr[])//数字字符串转成double型数字
{
char*s=str;
intp=1,q=0;//p=小数点前位数,q=小数点后位数
chard[]=".",z[]="0";
doubleda=0,p1;
if(strstr(str,d)==0)//判断是否有小数点
p=strlen(str);
else
if(strstr(str,d)==str)//没有输入小数点前的数,如“.032”
{
p=1;
q=strlen(str)-1;
strcpy(str,strcat(z,str));
}
else
{
p=strstr(str,d)-str;
q=strlen(str)-p-1;
}
for(inti=0;i
123=1*100+2*10+3*1
da=da+((int)str[i]-48)*pow(10,p-i-1);
for(intj=0;j0.123=1*0.1+2*0.01+3*0.001
da=da+((int)str[strlen(str)-1-j]-48)*pow(0.1,q-j);
returnda;
}
intmake_str()//语法检查
{
char*p,*p1;
intn=0;
printf("\n请输入表达式,以“=”结尾:
");
gets(expr[i].expstr);
p=expr[i].expstr;
p1=p;
while
(1)
{
if(*p=='\0')
if(*(p-1)=='=')//语法检查结束
break;
else
{//没有以"="结尾
printf("\n表达式以\"=\"结尾。
请重新输入:
");
gets(expr[i].expstr);
p=expr[i].expstr;
n=0;
continue;
}
if(change_opnd(*p)==2)//一个")",n-1
n--;
if(change_opnd(*p)==0)//一个"(",n+1
n++;
if(*p1==*p)//第一个字符的判断,只能以“数字”或“(”开头,不能有非法字符
if(change_opnd(*p)>0)
{
printf("\n表达式只能以“数字”或“(”开头。
请重新输入:
");
gets(expr[i].expstr);
p=expr[i].expstr;
n=0;
continue;
}
else
if(change_opnd(*p)==-2)
{
printf("\n表达式\"%c\"为非法字符。
请重新输入:
",*p);
gets(expr[i].expstr);
p=expr[i].expstr;
n=0;
continue;
}
else
{//合法刚跳到下一个字符
p=p+1;
continue;
}
if(change_opnd(*p)==-2)//非法字符判断
{
printf("\n表达式\"%c\"为非法字符。
请重新输入:
",*p);
gets(expr[i].expstr);
p=expr[i].expstr;
n=0;
continue;
}
if(change_opnd(*p)==0)//"("前一个字符只能是"+、-、*、/、("
{
if(change_opnd(*