分别定义两个栈——符号栈、数值栈
struct opstack{//符号栈
char data[MAXSIZE];//存储操作符
int top;
}op;
struct ststack{//数值栈
float data[MAXSIZE];//存储操作数
int top;
}st;
问题:
编写程序,利用栈实现算术表达式的求解。
分析题目——要设计一个程序以实现 + - * / ,这并非难事,思路先构筑好一切OK~ 据前中后缀表达式的难易程度, 我选择用后缀表达式对用户输入的算式进行转置运算。
一、各函数代码如下:
void trans(char exp[],char postexp[]){//将算术表达式exp转换为后缀表达式postexp
char ch;
int i=0,j=0; //i扫描exp的下标,j扫描postexp的下标
op.top=-1;
ch=exp[i];//将用户输入的算数表达式存入数组exp中
i++;
while(ch != '\0'){//未结束
switch(ch)//先对操作符分类编程
{
case '+':
case '-':
while (op.top!=-1)
{
postexp[j]=op.data[op.top];
j++;
op.top--;
}
op.top++;
op.data[op.top]=ch;//依次存入符号栈中
break;
case '*':
case '/':
while(op.top!=-1 && (op.data[op.top]=='*' || op.data[op.top]=='/')){//将*与/优先级提于+-之前
postexp[j]=op.data[op.top];
j++;
op.top--;
}
op.top++;
op.data[op.top]=ch;
break;
default:
while (ch>='0' && ch<='9')
{
postexp[j]=ch;
j++;
ch=exp[i];
i++;
}
i--;
postexp[j]='#';
j++;
//postexp[j]=' '; j++; //用空格标识一个数值串结束
}
ch=exp[i]; i++;
}
while(op.top!=-1){ //此时,exp扫描完毕,栈不空时出栈并存放到postexp中
postexp[j]=op.data[op.top];
j++;
op.top--;
}
postexp[j]='\0'; //给postexp表达式添加结束标识
}
后对转置后的后缀表达式求值
float compvalue(char postexp[]){//对后缀表达式postexp求值
float d;
char ch;
int i=0;
st.top=-1;
ch=postexp[i]; i++;
while (ch!='\0'){//未结束
switch(ch){
case '+': st.data[st.top-1]=st.data[st.top-1]+st.data[st.top];//遇到操作符就弹出两个数 并将结果进栈
st.top--; break;
case '-': st.data[st.top-1]=st.data[st.top-1]-st.data[st.top];
st.top--; break;
case '*': st.data[st.top-1]=st.data[st.top-1]*st.data[st.top];
st.top--; break;
case '/':
if(st.data[st.top]!=0)
st.data[st.top-1]=st.data[st.top-1]/st.data[st.top];
else{
printf("\n\t除零错误!\n");//防止除数为0
exit(0);
}
st.top--; break;
default:
d=0;
while (ch>='0' && ch<='9')//遇到操作数就进栈直到#为止
{
d=10*d+ch-'0';
ch=postexp[i]; i++;
}
st.top++;
st.data[st.top]=d;
}
ch=postexp[i]; i++;
}
return st.data[st.top];//输出的结果为栈顶元素
}
二、完整代码(含各函数及main)
#include <iostream.h>
#include <stdio.h>
#include <stdlib.h>
#define MAXSIZE 100
struct opstack{//符号栈
char data[MAXSIZE];//存储操作符
int top;
}op;
struct ststack{//数值栈
float data[MAXSIZE];//存储操作数
int top;
}st;
void trans(char exp[],char postexp[]);//将算术表达式exp转换为后缀表达式postexp
float compvalue(char postexp[]);//对后缀表达式postexp求值
int main()
{
char exp[20];
cout<<"请输入算数表达式,请勿用空格用作连接各数据的间隔:(仅包含+ - * /)"<<endl;
cin>>exp;
char postexp[30];
float f=0.0;
trans(exp,postexp);//求exp的逆波兰式,得到postexp
printf("%s = %.2f\n",exp,compvalue(postexp));//格式化输出
return 0;
}
void trans(char exp[],char postexp[]){//将算术表达式exp转换为后缀表达式postexp
char ch;
int i=0,j=0; //i扫描exp的下标,j扫描postexp的下标
op.top=-1;
ch=exp[i];//将用户输入的算数表达式存入数组exp中
i++;
while(ch != '\0'){//未结束
switch(ch)//先对操作符分类编程
{
case '+':
case '-':
while (op.top!=-1)
{
postexp[j]=op.data[op.top];
j++;
op.top--;
}
op.top++;
op.data[op.top]=ch;//依次存入符号栈中
break;
case '*':
case '/':
while(op.top!=-1 && (op.data[op.top]=='*' || op.data[op.top]=='/')){//将*与/优先级提于+-之前
postexp[j]=op.data[op.top];
j++;
op.top--;
}
op.top++;
op.data[op.top]=ch;
break;
default:
while (ch>='0' && ch<='9')
{
postexp[j]=ch;
j++;
ch=exp[i];
i++;
}
i--;
postexp[j]='#';
j++;
//postexp[j]=' '; j++; //用空格标识一个数值串结束
}
ch=exp[i]; i++;
}
while(op.top!=-1){ //此时,exp扫描完毕,栈不空时出栈并存放到postexp中
postexp[j]=op.data[op.top];
j++;
op.top--;
}
postexp[j]='\0'; //给postexp表达式添加结束标识
}
float compvalue(char postexp[]){//对后缀表达式postexp求值
float d;
char ch;
int i=0;
st.top=-1;
ch=postexp[i]; i++;
while (ch!='\0'){//未结束
switch(ch){
case '+': st.data[st.top-1]=st.data[st.top-1]+st.data[st.top];//遇到操作符就弹出两个数 并将结果进栈
st.top--; break;
case '-': st.data[st.top-1]=st.data[st.top-1]-st.data[st.top];
st.top--; break;
case '*': st.data[st.top-1]=st.data[st.top-1]*st.data[st.top];
st.top--; break;
case '/':
if(st.data[st.top]!=0)
st.data[st.top-1]=st.data[st.top-1]/st.data[st.top];
else{
printf("\n\t除零错误!\n");//防止除数为0
exit(0);
}
st.top--; break;
default:
d=0;
while (ch>='0' && ch<='9')//遇到操作数就进栈直到#为止
{
d=10*d+ch-'0';
ch=postexp[i]; i++;
}
st.top++;
st.data[st.top]=d;
}
ch=postexp[i]; i++;
}
return st.data[st.top];//输出的结果为栈顶元素
}
执行效果如下:
分享完毕~
欢迎小伙伴们在文下评论和私信喔~