数据结构课程设计之算术表达式求值.docx
《数据结构课程设计之算术表达式求值.docx》由会员分享,可在线阅读,更多相关《数据结构课程设计之算术表达式求值.docx(10页珍藏版)》请在冰豆网上搜索。
![数据结构课程设计之算术表达式求值.docx](https://file1.bdocx.com/fileroot1/2022-10/27/b5eefc45-cc28-4e4e-972e-f3f5c0812dab/b5eefc45-cc28-4e4e-972e-f3f5c0812dab1.gif)
数据结构课程设计之算术表达式求值
1【实验题目及要求】
[问题描述]
一个算术表达式是由操作数(operand)、运算符(operator)和界限符(delimiter)组成的。
假设操作数是正实数,运算符只含加减乘除等四种运算符,界限符有左右括号和表达式起始、结束符“#”,如:
#(7+15)*(23-28/4)#。
引入表达式起始、结束符是为了方便。
编程利用“算符优先法”求算术表达式的值。
[基本要求]
(1)从键盘或文件读入一个合法的算术表达式,输出正确的结果。
(2)显示输入序列和栈的变化过程。
(3)考虑算法的健壮性,当表达式错误时,要给出错误原因的提示。
(4)实现非整数的处理(可选功能)。
2【源代码(C语言)】
#include
#include
#include
#defineMAXSIZE20
#defineOK1
#defineERROR0
#defineOVERLOW0
#defineYES1
#defineNO0
typedefstruct{
char*base;
char*top;
intstacksize;//最大存储量
}OPTR;//字符存储栈
typedefstruct{
float*base;
float*top;
intstacksize;//最大存储量
}OPND;//数值存储栈
intInitOptrStack(OPTR*);//字符栈初始化函数
intOptrPush(OPTR*,char);//进字符栈操作
intOptrPop(OPTR*,char*);//出字符栈操作
intOptrEmpty(OPTR);//判断字符栈是否为空
charGetOptrTop(OPTR);//返回字符栈顶元素
intInitOpndStack(OPND*);//数值栈初始化函数
intOpndPush(OPND*,float);//进数值栈操作
intOpndPop(OPND*,float*);//出数值栈操作
intOpndEmpty(OPND);//判断数值栈是否为空
intJudgeChar(char);//判断是否为字符
floatGetFloat(char*);//接收一个数字
charPrecede(char,char);//判断优先级操作
floatCaculate(float,float,char);//计算数值
voidmain()
{
charch,noMean,ci;
floatnum,number1,number2;
OPTRoptr;
OPNDopnd;
//system("color30");
InitOptrStack(&optr);
InitOpndStack(&opnd);
while
(1){
printf("请输入表达式以“#”开始,以“#”结束\n");
do{
ch=getchar();
}while(ch!
='#');//忽略前面非‘#’字符
OptrPush(&optr,ch);
ch=getchar();
while(ch!
='#'||GetOptrTop(optr)!
='#'){
if(!
JudgeChar(ch)){//如果输入的是数字
num=GetFloat(&ch);
OpndPush(&opnd,num);
}
else{//输入的是字符
switch(Precede(GetOptrTop(optr),ch)){
case'<':
OptrPush(&optr,ch);//栈顶优先级低
ch=getchar();
break;
case'=':
OptrPop(&optr,&noMean);//左右括号,把左括号出栈
ch=getchar();
break;
case'>':
//栈顶优先级高
if(OpndPop(&opnd,&number2)&&OpndPop(&opnd,&number1)){
OptrPop(&optr,&ci);
num=Caculate(number1,number2,ci);//出栈计算
OpndPush(&opnd,num);
}
else{
printf("输入过多运算符!
\n");
system("PAUSE");
exit(0);
}
break;
}//witch
}//else
}
if(opnd.top-opnd.base>=2){
printf("俩个括号之间缺少运算符!
\n");
system("PAUSE");
exit(0);
}
OpndPop(&opnd,&num);//直接把OPND的栈元素赋值给num
printf("运算结果为%.3f\n",num);
}
system("PAUSE");
}
intInitOptrStack(OPTR*OP)
{
OP->base=(char*)malloc((MAXSIZE+1)*sizeof(char));
OP->top=OP->base;
OP->stacksize=MAXSIZE;
returnOK;
}
intOptrPush(OPTR*OP,charch)
{
*(OP->top)=ch;
OP->top++;
returnOK;
}
intOptrPop(OPTR*OP,char*ch)
{
if(OP->base==OP->top)
returnERROR;
else{
OP->top--;
*ch=*(OP->top);
returnOK;
}
}
intOptrEmpty(OPTROP)
{
if(OP.top==OP.base)
returnYES;
else
returnNO;
}
charGetOptrTop(OPTROP)
{
return*(OP.top-1);
}
intInitOpndStack(OPND*OP)
{
if(!
(OP->base=(float*)malloc((MAXSIZE+1)*sizeof(float))))
exit(OVERLOW);
OP->top=OP->base;
OP->stacksize=MAXSIZE;
returnOK;
}
intOpndPush(OPND*OP,floatnumber)
{
*(OP->top)=number;
OP->top++;
returnOK;
}
intOpndPop(OPND*OP,float*number)
{
if(OP->top==OP->base)
returnERROR;
else{
OP->top--;
*number=*(OP->top);
returnOK;
}
}
intOpndEmpty(OPNDOP)
{
if(OP.top==OP.base)
returnYES;
else
returnNO;
}
intJudgeChar(charch)
{
if(ch>='0'&&ch<='9')
returnNO;
else
returnYES;
}
floatGetFloat(char*ch)
{
inti;
floatnum=0;
for(i=0;*ch>='0'&&*ch<='9';i++){
num=num*10+*ch-'0';
*ch=getchar();
}
returnnum;
}
charPrecede(chara,charb)
{
charch;
switch(a){
case'+':
case'-':
if(b=='*'||b=='/'||b=='(')
ch='<';
else
ch='>';
break;
case'*':
case'/':
if(b=='(')
ch='<';
else
ch='>';
break;
case'(':
if(b==')')
ch='=';
elseif(b=='#'){
printf("缺少反括号\n");
system("PAUSE");
exit(0);
}
else
ch='<';
break;
case')':
if(b=='('){
printf("两个括号之间没有符号相连!
\n");
system("PAUSE");
exit(0);
}
ch='>';
break;
case'#':
if(b=='#')
ch='=';
elseif(b==')'){
printf("没有左括号!
\n");
system("PAUSE");
exit(0);
}
else
ch='<';
break;
default:
printf("输入运算符超出范围!
\n");
system("PAUSE");
exit(0);
break;
}
returnch;
}
floatCaculate(floatnumber1,floatnumber2,charci)
{
floatnum;
switch(ci){
case'+':
num=number1+number2;break;
case'-':
num=number1-number2;break;
case'*':
num=number1*number2;break;
case'/':
num=number1/number2;break;
}
returnnum;
}
3【算法思想】
根据栈的原理