表达式求值

问题描述:使用键盘输入表达式,计算表达式的值并输出;将表达式转化成后缀表达式输出,利用后缀表达式求表达式的值并输出。

测试数据:

3*(7-2)

2*(6+2*(3+6*(6+6)))+(6+6)*3+2

8/(9-9)


#include<stdio.h>
#include<stdlib.h>
#define MAX 30
typedef struct tagNode{
	char data;
	struct tagNode *next;
}Node,*LinkList;
//用结构体数组实现顺序栈
typedef struct tagStack1{
	char S[MAX];
	int top;
}Stack1;   //存储运算符
typedef struct tagStack2{
	float S[MAX];
	int top;
}Stack2;   //存储运算数
int SEmpty1(Stack1 s)     //判运算符栈空
{
    if(s.top==-1)return 1;
    else return 0;
}//SEmpty1
int SEmpty2(Stack2 s)     //判运算数栈空
{
    if(s.top==-1)return 1;
    else return 0;
}//SEmpty2 

int Push1(Stack1 *s,char x)     //运算符入栈
{
    if(s->top==MAX-1)return 0;   //栈满不能入栈,返回0
    else{
        s->top++;
        s->S[s->top]=x;         //栈不满则压入数据x
        return 1;               //进栈成功,返回1
    } 
}//Push1
int Push2(Stack2 *s,float x)     //运算数入栈
{
    if(s->top==MAX-1)return 0;  
    else{
        s->top++;
        s->S[s->top]=x;   
        return 1;          
    } 
}//Push2

int Pop1(Stack1 *s,char *x)       //运算符出栈
{
    if(SEmpty1(*s))return 0;      //若栈空不能出栈,返回0
    else{
		*x=s->S[s->top];
        s->top--;
        return 1;                 //出栈成功,返回1
    }
}//Pop1
int Pop2(Stack2 *s,float *x)      //运算数出栈
{
    if(SEmpty2(*s))return 0;      
    else{
		*x=s->S[s->top];
        s->top--;
        return 1;
    }
}//Pop2

char Precede(char a,char b)        //优先级判断
{
	int i,c,d;
	static char bijiao[7][7]={'>','>','<','<','<','>','>',
                              '>','>','<','<','<','>','>',
                              '>','>','>','>','<','>','>',
                              '>','>','>','>','<','>','>',
                              '<','<','<','<','<','=',' ',
                              '>','>','>','>',' ','>','>',
                              '<','<','<','<','<',' ','='};
	char h[7]={'+','-','*','/','(',')','#'};
	for(i=0;i<=6;i++){
		if(a==h[i])
			c=i;
		if(b==h[i])
			d=i;
	}
	return bijiao[c][d];
}//Precede

char ReadTop1(Stack1 s)        //读运算符栈顶元素
{
    if(SEmpty1(s))return 0;
    else return s.S[s.top];    //读栈顶元素,但指针没有移动
}//ReadTop1

float ReadTop2(Stack2 s)       //读运算数栈顶元素
{
    if(SEmpty2(s))return 0;
    else return s.S[s.top];
}//ReadTop1

float Count(float m,char the,float n,int *d)      //运算函数
{
	switch(the){
	case '*':return m*n;
	case '+':return m+n;
	case '-':return m-n;
	case '/':if(n!=0)return m/n;
		else *d=*d+1;
		break;
	}//switch
	return 0;
}//Count


void Operate1(LinkList L)
{
	int d=0;
	char x,theta;float a,b;
	LinkList p=L->next;
	Stack1 OPTR;Stack2 OPND;         //OPTR为运算符栈,OPND为操作数栈
 	OPTR.top=0;OPND.top=-1;
	OPTR.S[0]='#';
	while(p->data!='#'||ReadTop1(OPTR)!='#'){
		if(p->data>='0'&&p->data<='9'){
			Push2(&OPND,(float)(p->data-48));p=p->next;
		}//if
		else{
            switch(Precede(ReadTop1(OPTR),p->data)){
			case '<'://栈顶元素优先级低
				Push1(&OPTR,p->data);p=p->next;break;
			case '='://脱括号
				Pop1(&OPTR,&x);p=p->next;break;
			case '>'://退栈并将运算结果入栈
				Pop1(&OPTR,&theta);
				Pop2(&OPND,&b);Pop2(&OPND,&a);
				Push2(&OPND,Count(a,theta,b,&d));
				break;
			}//switch
		}//else
	}//while
	if(d!=0){printf("ERROR!!!\n");return;}
	else printf("=%.2f\n",ReadTop2(OPND));
}//Operate1

void Operate2(LinkList L)
{
	int i,j,d=0;
	float a,b;
	Stack1 OPTR1;Stack2 OPND1,OPND3;//OPND3用作对后缀表达式求值
	LinkList p=L->next;
	OPTR1.top=0;OPND1.top=-1,OPND3.top=-1;
	OPTR1.S[0]='#';
	while(p->data!='#'||ReadTop1(OPTR1)!='#'){
		if(p->data>='0'&&p->data<='9'){
			Push2(&OPND1,(float)(p->data-48));
			Push2(&OPND3,(float)(p->data-48));
			p=p->next;
		}//if
		else{
            switch(Precede(ReadTop1(OPTR1),p->data)){
			case '<'://栈顶元素优先级低
				Push1(&OPTR1,p->data);p=p->next;break;
			case ' ':p=p->next;break;
			case '>'://输出栈中元素,并将栈清空
				for(i=0;i<=OPND1.top;i++)
					printf("%.0f ",OPND1.S[i]);
				OPND1.top=-1;
				if(p->data==')'&&(p->next->data=='*'||p->next->data=='/')){
					j=OPTR1.top;
					while(OPTR1.S[j]!='('){
						printf("%c ",OPTR1.S[j]);
						Pop2(&OPND3,&b);Pop2(&OPND3,&a);//对后缀表达式进行求值
				        Push2(&OPND3,Count(a,OPTR1.S[j],b,&d));
						j--;
					}//while
					OPTR1.top=j-1;
				}//if
				else{
				    for(j=OPTR1.top;j>=1;j--){
						if(OPTR1.S[j]!='('){
					        printf("%c ",OPTR1.S[j]);
					        Pop2(&OPND3,&b);Pop2(&OPND3,&a);//对后缀表达式进行求值
						    Push2(&OPND3,Count(a,OPTR1.S[j],b,&d));
						}
					}//for
				    OPTR1.top=0;
				}//else
				if(p->data!=')')Push1(&OPTR1,p->data);
				if(p->data!='#')p=p->next;
				break;
			}//switch
		}//else
	}//while
	if(d!=0){printf("ERROR!!!\n");return;}
    else printf("=%.2f\n",ReadTop2(OPND3));
}//Operate2

int main()
{
	char i;
	LinkList L,p,s;
	p=L=(LinkList)malloc(sizeof(Node));
	printf("请输入中缀表达式(以#结束):\n");
	while(p->data!='#'){
		s=(LinkList)malloc(sizeof(Node));
		scanf("%c",&s->data);
		p->next=s;p=s;
	}
	p->next=NULL;
	p=L->next;
	while(p->data!='#'){printf("%c",p->data);p=p->next;}
	scanf("%c",&i);
	Operate1(L);
	printf("转化为后缀表达式并求值为(输入Y or N):\n");
	scanf("%c",&i);
	switch(i){
	    case 'Y':Operate2(L);break;
		case 'N':printf("谢谢使用!\n");break;
	}
	return 0;
}//main


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值