利用栈实现表达式求值(含C/C++实现)

中缀表达式转后缀表达式的算法规则:
在这里插入图片描述
先将这个用C/C++实现一下:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

#define MaxSize 100
#define ElemType char
typedef struct{
	ElemType data[MaxSize];
	int top;
}SqStack;

//顺序栈的初始化:
void InitStack(SqStack &S)
{
	memset(S.data,'\0',MaxSize);
	S.top=-1;
}

//获取栈顶元素(不是出栈操作!!)
bool GetTop(SqStack &S,ElemType &x)
{
	if(S.top==-1)return false;
	x=S.data[S.top];
	return true;
}

//入栈操作:
bool Push(SqStack &S,ElemType x)
{
	if(S.top==(MaxSize-1))return false;
	S.data[++S.top]=x;
	return true;
}

//出栈操作:
bool Pop(SqStack &S,ElemType &x)
{
	if(S.top==-1)return false;
	x=S.data[S.top--];
	return true;
}

//用于判断运算符优先级的高低,优先级高于或等于就返回true,否则为false 
bool Priority(char a,char b)
{
	if((a=='+'||a=='-')&&(b=='+'||b=='-'||b=='*'||b=='/'))
	{
		return true;
	}
	else if((a=='*'||a=='/')&&(b=='*'||b=='/'))
	{
		return true;
	}
	return false;
}

//将中缀表达式转化为后缀表达式: 
void ChangeToRPN(ElemType str[],int length,ElemType* &str1) //RPN指逆波兰式,也就是后缀表达式 
{
	int j=0;
	str1=(char*)malloc(sizeof(char)*MaxSize); //str1是字符数组,用于存放处理后的后缀表达式 
	memset(str1,' ',MaxSize);
	ElemType topElem;
	SqStack S;  //定义一个栈 
	InitStack(S); //初始化栈 
	for(int i=0;i<length;i++)
	{
		if(str[i]>='0'&&str[i]<='9') //遇到操作数 
		{
			while(1)
			{
			    str1[j]=str[i];
			    if(str[i+1]>='0'&&str[i+1]<='9'){
			    	j=j+1;
			    	i++;
				}
				else{
					j=j+2;
					break;
			    }
			}
		}
		else if(str[i]!=')') //遇到运算符或左括号 
		{
			if(str[i]=='(')
			{
				if(!Push(S,str[i]))printf("Your input is too long!!\n");
				continue;
			}  
			else while(GetTop(S,topElem)&&topElem!='('&&Priority(str[i],topElem)) 
			{   //Priority是用于判断运算符优先级的自定义函数 
				Pop(S,topElem);
				str1[j]=topElem;
				j=j+2;
			}
			Push(S,str[i]);
		}
		else{ //遇到右括号 
			while(GetTop(S,topElem))
			{
				Pop(S,topElem);
				if(topElem=='(')break;
				str1[j]=topElem;
				j=j+2;
			}
		}
	}
    //将栈中剩下的运算符弹出 
	while(Pop(S,topElem)){
		str1[j]=topElem;
		j=j+2;
	}
	return;
}

int main()
{
	char str[50];
	char *str1;
	memset(str,'\0',50);
	
	printf("\n请输入要转化的中缀表达式:\n");
	scanf("%s",str);
	ChangeToRPN(str,strlen(str),str1);
	printf("\n输出结果:\n");
	printf("%s\n",str1);
	
	free(str1);
	return 0;
}

接着就是让计算机实现中缀表达式的计算:
在算法思想上,该算法结合了中缀转后缀和后缀表达式求值两:个算法的思想,参考我自己之前的笔记:利用栈实现表达式求值(理论分析)
总的算法思想:
在这里插入图片描述
我的代码实现:

//这个算法针对只含有正整数数的表达式计算
#include<stdio.h>
#include<stdlib.h>
#include<string.h>

#define MaxSize 100

//用于存放运算符的栈的数据类型定义及基本操作:

//数据类型定义 
#define ElemType1 char
typedef struct{
	ElemType1 data[MaxSize];
	int top; 
}SqStack1;

//运算符栈的初始化操作:
void InitStack_1(SqStack1 &S)
{
	memset(S.data,'\0',MaxSize);
	S.top=-1;
}

//取运算符栈的栈顶元素:
bool GetTop_1(SqStack1 &S,ElemType1 &x)
{
	if(S.top==-1)return false;
	x=S.data[S.top];
	return true;
}

//运算符栈入栈操作:
bool Push_1(SqStack1 &S,ElemType1 x)
{
	if(S.top==(MaxSize-1))return false;
	S.data[++S.top]=x;
	return true;
}

//运算符栈出栈操作:
bool Pop_1(SqStack1 &S,ElemType1 &x)
{
	if(S.top==-1)return false;
	x=S.data[S.top--];
	return true;
}

//用于存放操作数的栈的数据类型定义及基本类型操作

//数据类型定义 
#define ElemType2 float
typedef struct{
	ElemType2 data[MaxSize];
	int top; 
}SqStack2;

//操作数栈的初始化操作:
void InitStack_2(SqStack2 &S)
{
	S.top=-1;
}

//取操作数栈的栈顶元素:
bool GetTop_2(SqStack2 &S,ElemType2 &x)
{
	if(S.top==-1)return false;
	x=S.data[S.top];
	return true;
}

//操作数栈入栈操作:
bool Push_2(SqStack2 &S,ElemType2 x)
{
	if(S.top==(MaxSize-1))return false;
	S.data[++S.top]=x;
	return true;
}

//操作数栈出栈操作:
bool Pop_2(SqStack2 &S,ElemType2 &x)
{
	if(S.top==-1)return false;
	x=S.data[S.top--];
	return true;
}

//用于判断运算符优先级的高低,优先级高于或等于就返回true,否则为false 
bool Priority(char a,char b)
{
	if((a=='+'||a=='-')&&(b=='+'||b=='-'||b=='*'||b=='/'))
	{
		return true;
	}
	else if((a=='*'||a=='/')&&(b=='*'||b=='/'))
	{
		return true;
	}
	return false;
}

//用于两个操作数之间的计算 
ElemType2 CalculateTwo(ElemType2 n1,ElemType2 n2,ElemType1 t)
{   //n1是右操作数,n2是左操作数
	if(t=='+')return n1+n2;
	if(t=='-')return n2-n1;
	if(t=='/')return n2/n1;
	if(t=='*')return n2*n1;
}

//计算中缀表达式的算法: 
void Calculate(ElemType1 str[],ElemType2 &e)
{
	SqStack1 S1;//S1是运算符栈
	SqStack2 S2;//S2是操作数栈 
	InitStack_1(S1);//初始化S1 
	InitStack_2(S2);//初始化S2
	float n=0; 
	ElemType2 n1,n2;
    ElemType1 t; 
	for(unsigned int i=0;i<strlen(str);i++)
	{
		if(str[i]>='0'&&str[i]<='9')
		{   
			while(1){ //这个循环的存在是因为操作数的位数是不确定的 
				n*=10;
				n+=(str[i]-'0');
				if(str[i+1]>='0'&&str[i+1]<='9')i++;
				else break;
			}
			Push_2(S2,n);
			n=0;
		}
		else if(str[i]!=')')
		{
			while(GetTop_1(S1,t)&&t!='('&&Priority(str[i],t))
			{
				Pop_1(S1,t);
				Pop_2(S2,n1); //n1是右操作数 
				Pop_2(S2,n2); //n2是左操作数 
				Push_2(S2,CalculateTwo(n1,n2,t));
			}
			Push_1(S1,str[i]);
		}
		else
		{
			while(Pop_1(S1,t))
			{
				if(t=='(')break;
				Pop_2(S2,n1);  //n1是右操作数
				Pop_2(S2,n2); //n2是左操作数 
				Push_2(S2,CalculateTwo(n1,n2,t));
			}
		}
	}
	while(Pop_1(S1,t)&&Pop_2(S2,n1)&&Pop_2(S2,n2))
	{
		Push_2(S2,CalculateTwo(n1,n2,t));
	}
	Pop_2(S2,e);
}

int main()
{
	ElemType1 str[MaxSize];
	ElemType2 e;
	memset(str,'\0',MaxSize);
	
	printf("\n请输入要计算的表达式:\n");
	scanf("%s",str);
	printf("\n计算并输出结果:\n");
	Calculate(str,e);
	printf("%f\n",e);
	return 0;
}

其中放操作数的栈和放运算符的栈用了两种数据类型定义。

  • 12
    点赞
  • 68
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
以下是利用实现表达式求值的 C 代码: ```c #include <stdio.h> #include <stdlib.h> #include <ctype.h> #define MAX_STACK_SIZE 100 typedef struct { int top; int data[MAX_STACK_SIZE]; } Stack; void initStack(Stack *s) { s->top = -1; } int isEmpty(Stack *s) { return s->top == -1; } int isFull(Stack *s) { return s->top == MAX_STACK_SIZE - 1; } void push(Stack *s, int value) { if (isFull(s)) { printf("Stack is full!\n"); exit(1); } s->data[++s->top] = value; } int pop(Stack *s) { if (isEmpty(s)) { printf("Stack is empty!\n"); exit(1); } return s->data[s->top--]; } int peek(Stack *s) { if (isEmpty(s)) { printf("Stack is empty!\n"); exit(1); } return s->data[s->top]; } int evaluate(char *expr) { Stack operandStack; initStack(&operandStack); Stack operatorStack; initStack(&operatorStack); int i = 0; while (expr[i] != '\0') { if (isdigit(expr[i])) { int value = 0; while (isdigit(expr[i])) { value = value * 10 + (expr[i] - '0'); i++; } push(&operandStack, value); } else if (expr[i] == '+' || expr[i] == '-' || expr[i] == '*' || expr[i] == '/') { while (!isEmpty(&operatorStack) && peek(&operatorStack) != '(' && ((expr[i] == '*' || expr[i] == '/') || (expr[i] == '+' || expr[i] == '-') && (peek(&operatorStack) == '*' || peek(&operatorStack) == '/'))) { int op1 = pop(&operandStack); int op2 = pop(&operandStack); char op = pop(&operatorStack); int result; switch (op) { case '+': result = op2 + op1; break; case '-': result = op2 - op1; break; case '*': result = op2 * op1; break; case '/': result = op2 / op1; break; } push(&operandStack, result); } push(&operatorStack, expr[i]); i++; } else if (expr[i] == '(') { push(&operatorStack, expr[i]); i++; } else if (expr[i] == ')') { while (!isEmpty(&operatorStack) && peek(&operatorStack) != '(') { int op1 = pop(&operandStack); int op2 = pop(&operandStack); char op = pop(&operatorStack); int result; switch (op) { case '+': result = op2 + op1; break; case '-': result = op2 - op1; break; case '*': result = op2 * op1; break; case '/': result = op2 / op1; break; } push(&operandStack, result); } if (!isEmpty(&operatorStack) && peek(&operatorStack) == '(') { pop(&operatorStack); } i++; } else { printf("Invalid character: %c\n", expr[i]); exit(1); } } while (!isEmpty(&operatorStack)) { int op1 = pop(&operandStack); int op2 = pop(&operandStack); char op = pop(&operatorStack); int result; switch (op) { case '+': result = op2 + op1; break; case '-': result = op2 - op1; break; case '*': result = op2 * op1; break; case '/': result = op2 / op1; break; } push(&operandStack, result); } return pop(&operandStack); } int main() { char expr[100]; printf("Enter an expression: "); scanf("%s", expr); int result = evaluate(expr); printf("Result: %d\n", result); return 0; } ``` 注意:这段代码只能处理整数的四则运算表达式,不支持浮点数和括号内的表达式优先级。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值