2020-11-01

将中缀表达式转换为后缀表达式,然后进行整数的四则运算。

1.定义栈的基本操作。

#include<iostream>

using namespace std;
struct StackRecord;
typedef struct StackRecord* PtrToNode;
typedef PtrToNode Stack;


int IsEmpty(Stack S);//jian yan zhan shi fou wei kong
//int IsFull(Stack S);//jian yan zhan shi fou wei man
Stack CreatStack(void);//chuangjianzhan
void DisposeStack(Stack S);//shi fang zhan
void MakeEmpty(Stack S);//chuang jian  kong zhan
void Push(int X, Stack S);//jin zhan
int Top(Stack S);//fan hui zhan ding yuan  su
void Pop(Stack S);// shan chu zhan ding 
//int TopAndPop(Stack S);
void Tranformed(int X[],int length,int Lodge[],int* q);//X表示主函数中的a;length表示a的长度,
//Lodge用于存放逆波兰表达式,*q则表示逆波兰表达式的长度。
int IsSign(int X);//用于判断X是否为标识符。
int SignCmp(int X, int Y);//比较加减乘除以及括号的优先级。
int Calculate(int A[],int* q);//A逆波兰表达式
#include"stack.h"
struct StackRecord {
	int Element;
	PtrToNode Next;
}Node;


int IsEmpty(Stack S)
{
	return S->Next == NULL;
}

//int IsFull(Stack S) 


Stack CreatStack(void)
{
	Stack S;

	S = (Stack)malloc(sizeof(struct StackRecord));
	if (S == NULL)
		exit(-1);

	S->Next = NULL;
	MakeEmpty(S);
	return S;
}

void DisposeStack(Stack S) {
	Stack Temp;
	while (S)
	{
		Temp = S->Next;
		free(S);
		S = Temp;
	}
}

void MakeEmpty(Stack S)
{
	if (S == NULL)
	{
		fprintf(stderr, "Must use CreateStack first");
		exit(-1);
	}
	else
	{
		while (!IsEmpty(S))//S为空不执行此操作,否则执行pop(弹出元素);
			Pop(S);
	}
}

void Push(int X, Stack S) {
	PtrToNode NewStack;

	NewStack = (PtrToNode)malloc(sizeof(struct StackRecord));
	if (NewStack == NULL) {

		fprintf(stderr, "Out of space!!");
		exit(-1);
	}
	else
	{
		NewStack->Element = X;
		NewStack->Next = S->Next;
		S->Next = NewStack;
	}
}

int Top(Stack S) {
	if (!IsEmpty(S))
		return S->Next->Element;
	fprintf(stderr, "Empty Stack");
	return 0;
}

void Pop(Stack S) {
	PtrToNode FirstCell;

	if (IsEmpty(S))
	{
		fprintf(stderr, "Empty Stack");
		exit(-2);
	}
	else
	{
		FirstCell = S->Next;
		S->Next = S->Next->Next;
		free(FirstCell);
	}
}

2.表达式转换

//中缀表达式转换为后缀表达式。
#include"stack.h"
int IsSign(int X)
{
	if (X == '+' || X == '-' || X == '*' || X == '/' || X == '(' || X == ')')
		return 1;
	else return 0;
}
int SignCmp(int X, int Y)
{
	if (X == '+' || X == '-')
		X = 1;
	else if (X == '*' || X == '/')
		X = 2;
	else if (X == '(')
		X = 0;
	if (Y == '+' || Y == '-')
		Y = 1;
	else if (Y == '*' || Y == '/')
		Y = 2;
	else if (Y == '(')
		Y = 0;
	if (X < Y) return 0;
	else return 1;

}
void Tranformed(int X[],int length,int A[],int *q)
{
	Stack T = CreatStack();
	int i = 0, j = 0;
	int flag = 0;
	while (flag<length)
	{
		if (IsSign(X[i]))
		{
			if (IsEmpty(T))
				Push(X[i], T);
			else if (X[i] == '(')
			{
				Push(X[i], T);
			}
			else if (X[i] == ')')
			{
				if (Top(T) == '(')
					Pop(T);
				else 
					while (1)
				{
					A[j] = Top(T); j++;
					Pop(T);
					if (Top(T) == '(')
					{
						Pop(T); break;
					}
				}
			}
			else
			{
				while (1)
				{
					if (IsEmpty(T))
					{
						Push(X[i], T);
						break;
					}
					if (!SignCmp(Top(T), X[i]))
					{
						Push(X[i], T); break;
					}
					else
					{
						A[j] = Top(T); j++;
						Pop(T);
					}
				}
			}
		}
		else
		{
			A[j] = X[i]; j++;
		}
		i++; flag++;
	}
	while (!IsEmpty(T))
	{
		A[j] = Top(T); j++;
		Pop(T);
	}
	printf("\n转换为逆波兰:");
	for (int m = 0;m<j; m++)
	{
		if (A[m] == '+') printf("+");
		else if (A[m] == '-') printf("-");
		else if (A[m] == '*') printf("*");
		else if (A[m] == '/') printf("/");
		else printf("%d", A[m]);
		printf(" ");
	}
	*q = j;

}

3.计算后缀表达式

#include"stack.h"

int Calculate( int A[],int *q)
{
	Stack C = CreatStack();
	int i = 0;
	while (i<*q)
	{
		if (!(A[i] == '+' || A[i] == '-' || A[i] == '*' || A[i] == '/' || A[i] == '(' || A[i] == ')'))
			Push(A[i], C);
		else if (A[i] == '+')
		{
			int tem = Top(C);
			Pop(C);
			int Tem = Top(C);
			Pop(C);
			Push(tem + Tem, C);
		}
		else if (A[i] == '-')
		{
			int tem = Top(C);
			Pop(C);
			int Tem = Top(C);
			Pop(C);
			Push(Tem - tem, C);
		}
		else if (A[i] == '*')
		{
			int tem = Top(C);
			Pop(C);
			int Tem = Top(C);
			Pop(C);
			Push(tem * Tem, C);
		}
		else if (A[i] == '/')
		{
			int tem = Top(C);
			Pop(C);
			int Tem = Top(C);
			Pop(C);
			Push(Tem / tem, C);
		}
		i++;
	}
	return Top(C);
}

4.主函数以及输入表达式

#include"stack.h"

int main()
{
	printf("提示:若输入一个负数请加上括号\n");
	printf("请输入一个表达式:");
	char s[100];
	gets_s(s);
	int a[100] ;
	int i, j = 0;
	for (i = 0; s[i] != '\0'; )//将字符串转换为整型数字并储存到数组a;
	{
		if (s[i]=='-'&&s[i-1]=='(')
		{
			i++;
			int tem = 0;
			while (s[i] >= '0' && s[i] <= '9')
			{
				s[i] = s[i] - '0';
				tem = tem * 10 + s[i];
				i++;
			}
			a[j] = 0 - tem; j++;
		}

		else if ((s[i] >= '0' && s[i] <= '9')&& (s[i+1] >= '0' && s[i+1] <= '9'))
		{
			int tem = 0;
			while (s[i] >= '0' && s[i] <= '9')
			{
				s[i] = s[i] - '0';
				tem = tem * 10 + s[i];
				i++;
			}//(;40		);41	+:43	*:42	-:45	/:47
			if (tem == '+' || tem == '-' || tem == '*' || tem == '/' || tem == '(' || tem == ')')
			{
				a[j++] = '('; a[j++] = 65; a[j++] = '-'; a[j++] = 65 - tem; a[j++] = ')';
			}
			else a[j++] = tem;
		}
		
		else if((s[i] >= '0' && s[i] <= '9')&&(s[i+1] == '+' || s[i+1] == '-' || s[i+1] == '*' || s[i+1] == '/' || s[i+1] == '(' || s[i+1] == ')')) {
			a[j++] = s[i]-'0'; i++;
		}
		else if (s[i] == '+' || s[i] == '-' || s[i] == '*' || s[i] == '/' || s[i] == '(' || s[i] == ')')
		{
			a[j] = s[i]; i++;
			j++;
		}
		else if (s[i] >= '0' && s[i] <= '9' && s[i + 1] == '\0')
		{
			a[j++] = s[i] - '0'; i++;
		}
	}
	printf("存放到整形数组中为:");
	for (int m = 0; m < j; m++)
	{
		if (a[m] == '+') printf("+");
		else if (a[m] == '-') printf("-");
		else if (a[m] == '*') printf("*");
		else if (a[m] == '/') printf("/");
		else if (a[m] == '(') printf("(");
		else if (a[m] == ')') printf(")");
		else printf("%d", a[m]);
		printf(" ");
	}
		
	int* q=(int*)malloc(sizeof(int));
	int Lodge[100] = { 0 };
	Tranformed(a,j,Lodge,q);
	printf("\n该逆波兰表达式占用的数组长度:%d\n", *q);
	
	
	int result = (Calculate(Lodge, q));

	printf("\n结果为:%d", result);

	return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值