严蔚敏《数据结构》表达式求值

严蔚敏《数据结构》表达式求值
容器:两个栈,一个存放字符CS,一个存放数字S;两个数组,一个放中缀表达式c[N],一个放逆波兰式s[N]
方式:1.先将中缀表达以字符的形式全部输入(运用了gets()函数)并放到一个数组c[N]中;
2.求逆波兰式,遍历数组c[N],利用isdigit()函数判断字符数组里面的字符是数字字符还是非数字字符,是数字字符的话,将其放入数组s[N],s[N]中利用,作为分隔符;遍历c[N],遇到+,-,(则将他们放入CS中,遇到)则不用把他放入CS,然后POP字符栈中的元素,判断元素是否为(,如果是(,则把(POP出来,继续访问数组c[N],遇到*或者/则要把他放入s[N]中,还要判断CS中是否有(,有的话,还要全部POP出CS中的元素,并放入s[N]中。
3.求值,先处理s[N]数组,利用atoi()函数将数字字符(char型)转化为(int型),然后把它放入数字栈S,遇到操作符就POP两个数字,进行计算,如此重复。

#include<bits/stdc++.h>
using namespace std;
#define N 100

#define STACK_INIT_SIZE 5
#define STACKINCREMENT 10
#define OK 1
#define ERROR 0

typedef char CSElemType;
typedef int SElemType;

typedef int Status;

//字符栈 
typedef struct{//栈的顺序存储表示 
	CSElemType *top;//栈顶 
	CSElemType *base;//栈底 
	int cstacksize;//栈当前存储空间 
}CSqStack;

//数字栈 
typedef struct{//栈的顺序存储表示 
	SElemType *top;//栈顶 
	SElemType *base;//栈底 
	int stacksize;//栈当前存储空间 
}SqStack;

//字符栈的初始化 
Status InitCStack(CSqStack &CS)
{
	CS.base=(CSElemType*)malloc(sizeof(CSElemType)*STACK_INIT_SIZE);
	if(!CS.base)
	{
		exit(OVERFLOW);
	}
	CS.top=CS.base;
	CS.cstacksize=STACK_INIT_SIZE;
	return OK;
}

//数字栈的初始化 
Status InitStack(SqStack &S)
{
	S.base=(SElemType*)malloc(sizeof(SElemType)*STACK_INIT_SIZE);
	if(!S.base)
	{
		exit(OVERFLOW);
	}
	S.top=S.base;
	S.stacksize=STACK_INIT_SIZE;
	return OK;
}

//判断字符栈是否为空 
Status CStackEmpty(CSqStack &CS)
{
	if(CS.top==CS.base)
	{
		return OK;
	}
	else
	{
		return ERROR;
	}
}

//判断数字栈是否为空 
Status StackEmpty(SqStack &S)
{
	if(S.top==S.base)
	{
		return OK;
	}
	else
	{
		return ERROR;
	}
}

//判断字符栈是否满 
Status CStackFull(CSqStack &CS)
{
	if(CS.top-CS.base>=CS.cstacksize)
	{
		return OK;
	}
	else
	{
		return ERROR;
	}
}

//判断数字栈是否满 
Status StackFull(SqStack &S)
{
	if(S.top-S.base>=S.stacksize)
	{
		return OK;
	}
	else
	{
		return ERROR;
	}
}


//用e返回栈顶元素的值 
Status GetTop(SqStack S,SElemType &e)
{
	if(StackEmpty(S))
	{
		return ERROR;
	}
	e=*(S.top-1);
	return OK;
}

//将字符e插入栈顶 
Status CPush(CSqStack &CS,CSElemType e)
{
	if(CStackFull(CS))
	{
		CS.base=(CSElemType*)realloc(CS.base,sizeof(CSElemType)*(CS.cstacksize+STACK_INIT_SIZE));
	
		if(!CS.base)
		{
			exit(OVERFLOW);
		}
		CS.top=CS.base+CS.cstacksize;
		CS.cstacksize+=STACKINCREMENT;
	}
	*CS.top++=e;
	return OK;
}

//将数字e插入栈顶 
Status Push(SqStack &S,SElemType e)
{
	if(StackFull(S))
	{
		S.base=(SElemType*)realloc(S.base,sizeof(SElemType)*(S.stacksize+STACK_INIT_SIZE));
	
		if(!S.base)
		{
			exit(OVERFLOW);
		}
		S.top=S.base+S.stacksize;
		S.stacksize+=STACKINCREMENT;
	}
	*S.top++=e;
	return OK;
}

//取出字符栈顶元素,用e返回其值 
Status CPop(CSqStack &CS,CSElemType &e)
{
	if(CStackEmpty(CS))
	{
		return ERROR;
	}
	e=*--CS.top;
	return OK;
}

//取出数字栈顶元素,用e返回其值 
Status Pop(SqStack &S,SElemType &e)
{
	if(StackEmpty(S))
	{
		return ERROR;
	}
	e=*--S.top;
	return OK;
}


//展示数字栈的元素 
void DisplayStack(SqStack &S)
{
	int i;
	SqStack t;
	SElemType e;
	
	printf("请输出栈顶的元素:");
	while (!StackEmpty(S))
	{
	   Pop(S,e);
	   printf("%d\n",e);
	   Push(t,e);
	} 
	while (!StackEmpty(t))
	{
	   Pop(t,e);
	   Push(S,e);
	} 
	printf("\n");
	return;
}

//回收栈 
Status DestroyStack(SqStack &S)
{
	free(S.base);
	S.base=NULL;
	S.stacksize=0;
	return OK;	
} 

Status RPoland(char c[],char *s)
{
	//求逆波兰 
	CSqStack CS;
	InitCStack(CS);
	
	int j=0;
	char e;
	
	for(int i=0;i<strlen(c);i++)
	{
		
		if(isdigit(c[i]))//判断字符串里面是否有数字,有的话,把这个数字放入新的数组s里面 
		{
			s[j]=c[i];
			j++;
			if(isdigit(c[i+1]))
			{
				continue;
			}
			if(!CStackEmpty(CS))
			{
				CPop(CS,e);
				if(e=='*'||e=='/')
				{
					s[j]=',';
					j++;
					s[j]=e;
					j++;
					s[j]=',';
					j++;
					while(!CStackEmpty(CS))
					{
						CPop(CS,e);
						if(e!='(')
						{
							s[j]=e;
							j++;
						}
						else if(e=='(')
						{
							break;
						}
					}		
				}		
				else
				{
					CPush(CS,e);
				}
			}
		}
		else if(c[i]=='+'||c[i]=='-')
		{
			if(!CStackFull(CS))
			{
				CPush(CS,c[i]);
				s[j]=',';
				j++;
			}
		}
		else if(c[i]=='(')
		{
			if(!CStackFull(CS)&&c[i+1]!='-')
			{
				CPush(CS,c[i]);	
			}
			if(!CStackFull(CS)&&c[i+1]=='-')
			{
				CPush(CS,c[i]);
				s[j]='0';
				j++;	
			}	
		} 
		else if(c[i]==')')
		{
			do
			{
				CPop(CS,e);
				if(e!='(')
				{
					s[j]=',';
					j++;
					s[j]=e;
					j++;	
				}
				if(e=='(')
				{
					break;	
				} 
			}while(!CStackEmpty(CS)&&e!='(');
		}
		else if(c[i]=='*'||c[i]=='/')
		{		
			CPush(CS,c[i]);
			s[j]=',';
			j++; 
		}
	}
	while(!CStackEmpty(CS))
	{
		CPop(CS,e);
		s[j]=',';
		j++;
		s[j]=e;
		j++;
	}
	
	return OK;	
}

Status Evaluate(char s[])
{
	SqStack S;
	InitStack(S);
	
	
	int r=0;
	char str[N];
	SElemType e0,e1,e2;
	
	for(int k=0;k<strlen(s);k++)
	{   
		if (isdigit(s[k]))
		{
		
			str[r]=s[k];
			r++;
			//cout<<endl;
			//cout<<"r="<<r<<endl;
			if (s[k+1]==',')
			{
				str[r]='\0';
				Push(S,atoi(str));
				//cout<<endl;
				//cout<<"atoi(str)="<<atoi(str)<<endl; 
				r=0;
			}
			else
			{
				continue;
			}
		}
		if(s[k]=='+'||s[k]=='-'||s[k]=='*'||s[k]=='/')
		{
			if(s[k]=='+')
			{
				Pop(S,e1);
				Pop(S,e2);
				e0=e1+e2;
				Push(S,e0);
			}
			if(s[k]=='-')
			{
				
				Pop(S,e1);
				Pop(S,e2);
				cout<<endl;
				e0=e2-e1;
				Push(S,e0);
			}
			if(s[k]=='*')
			{
				
				Pop(S,e1);
				Pop(S,e2);
				e0=e1*e2;
				Push(S,e0);
			}
			if(s[k]=='/')
			{
				
				Pop(S,e1);
				Pop(S,e2);
				e0=e2/e1;
				Push(S,e0);
			}
		}
	}
	
	Pop(S,e0);
	printf("结果为:");
	printf("%d",e0);
	return OK;	
}
int main()
{
	char c[N];//存放中缀表达式 
	char s[N];//存放后缀表达式
	
	printf("请输入中缀表达式:");
	scanf("%s",c);
	
	RPoland(c,s);
	
	printf("输出后缀表达式:");
	for(int k=0;k<strlen(s)-1;k++)
	{
		printf("%c",s[k]);
	}
	
	printf("\n");
	Evaluate(s);
	return 0;
}


代码冗长,还有瑕疵,新手上路,多多关照,欢迎大家留言和私信!

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值