//链栈的应用 表达式运算
#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;
}
在这里插入代码片
备注:存在一点点错误,以后有时间改进解决。
欢迎码友提出解决思路。
运行结果截图: