链栈的应用 表达式运算

//链栈的应用  表达式运算
#include <stdio.h>
#include <iostream>
using namespace std;
#define sElemType int
typedef struct linkNode{
sElemType data;//数据域 
linkNode *next;//指针域
}*linkStack;
//判空函数(链栈为空返回1;不为空返回0)
int isEmpty(linkStack top){
return top==NULL;
}
//初始化链栈
void initLinkStack(linkStack &top){
top=NULL;
}
//插入元素到链栈
void push(linkStack &top,sElemType val){
linkStack newNode=new linkNode[1];
newNode->data=val;
newNode->next=top;
top=newNode;
}
//删除链栈的栈顶元素
void pop(linkStack &top,sElemType &val){
if(isEmpty(top)){
return;
}
val=top->data;
linkStack tempPtr=top;
top=top->next;
delete tempPtr;
}
//跟之前的栈结构额外增加一个getTop函数
sElemType getTop(linkStack top){
return top->data;
}
//数组左边行:@,+,-,*,/,(,);
//数组上边列:@,+,-,*,/,(,);
//0表示上边列的优先级大于左边行
//1表示上边列的优先级小于左边行
int priority[7][7]={
{0,0,0,0,0,0,0},
{1,1,0,0,0,0,1},
{1,1,0,0,0,0,1},
{1,1,1,1,0,0,1},
{1,1,1,1,0,0,1},
{1,0,0,0,0,0,0},
{1,1,1,1,1,1,1}
};
//返回操作符对应的行或列

int ordOfOptr(char c){
switch (c){
case '@':return 0;break;
case '+':return 1;break;
case '-':return 2;break;
case '*':return 3;break;
case '/':return 4;break;
case '(':return 5;break;
case ')':return 6;break;
}
return 10;
}

//判断左边与右边的操作符的优先级大小,如果左边的操作符优先级大于右边,
//则返回1,否则,返回0

int priOfLeftOrRight(char left,char right){
return priority[ordOfOptr(left)][ordOfOptr(right)];
}
//判断字符是操作数还是操作符,如果是操作数,返回1;如果是操作符,返回0
//弊端:只能处理一位数

int opndOrOptr(char c){
if(c>=48&&c<=57){
return 1;
}
return 0;
}
//实现计算两个操作数的加减乘除
int calc(char optr,int left,int right){
if('+'==optr) {
return
left+right;}
if('-'==optr) {
return
left-right;}
if('*'==optr){
return
left*right;}
if('/'==optr){
return
left/right;}

return 0;

}
//表达式运算
void expEval(char *exp){
linkStack OPTR,OPND;
initLinkStack(OPTR);
initLinkStack(OPND);
push(OPTR,'@');
while('\0'!=*exp){
	if(1==opndOrOptr(*exp)){
	//该字符为操作数时

	push(OPND,*exp-'0');
	}
	else {
			//该字符为操作符时

			sElemType optr=getTop(OPTR);
				if(0==priOfLeftOrRight(optr,*exp)){
				//如果右边的操作符优先级大于左边时
				push(OPTR,*exp);
				}
			
				else{
				//如果右边的操作符优先级小于左边时
					
					if(1==priOfLeftOrRight(optr,*exp)){
						sElemType left,right;
						pop(OPND,right);
						pop(OPND,left);
						push(OPND,calc(*exp,left,right));
					}
					//如果右边的操作符优先级大于左边时
				//	if(0==priOfLeftOrRight(optr,*exp)){
				//		push(OPTR,*exp);
				//	}
				//	push(OPTR,*exp);
				}
	}
//字符右移
	exp++;

}
	
	while(isEmpty(OPTR)==0){
//当操作符栈不为空时
		sElemType optr2;
		pop(OPTR,optr2);
		if('@'!=optr2&&'('!=optr2&&')'!=optr2){
		sElemType left,right;
		pop(OPND,right);
		pop(OPND,left);
		push(OPND,calc(optr2,left,right));
		}
	
	}
	
	 
	 	
 //输出结果
	cout<<getTop(OPND); 
}

int main(){
	char exp[100];
	cin>>exp;
	expEval(exp);
	return 0;

}
在这里插入代码片

备注:存在一点点错误,以后有时间改进解决。
欢迎码友提出解决思路。

运行结果截图:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值