【数据结构】栈的基本操作及其应用

分别定义两个栈——符号栈、数值栈

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];//输出的结果为栈顶元素
}

执行效果如下:

分享完毕~

欢迎小伙伴们在文下评论和私信喔~

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Jesonary

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值