(C语言/C++)将运算表达式转为后缀表达式

先看一段代码:

#include<iostream>
#include<cstring>
using namespace std;
int main() {
	char s[105], t[105][105];
	cin>>(s);
	int h = 0, p = 0;
	for (int i = 0; s[i]; i++) {
		if (!(s[i] >= '0' && s[i] <= '9')) {
			int k = 0;
			if (h != i) {
				for (int j = h; j < i; j++)t[p][k++] = s[j];
				t[p++][k++] = '\0';
				t[p][0] = s[i]; t[p++][1] = '\0';
			}
			else {
				t[p][0] = s[i];
				t[p++][1] = '\0';
			}
			h = i + 1;
		}
		if (s[i + 1] == '\0') {
			int k = 0;
			for (int j = h; s[j]; j++)t[p][k++] = s[j];
			t[p++][k++] = '\0';
		}
	}
	for (int i = 0; i < p; i++)
		cout << t[i] << endl;
	return 0;
}

运行结果:

 这是我写的一个不论表达式中的数是多少位,都可以将其分割的程序(这个其实跟将一句英语中的单词分开差不多)

后面转换为后缀表达式的时候,将会用到这个原理进行处理

后面这里就直接上代码:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
typedef char ElementType;
typedef struct SNode {//定义结构体
	ElementType Data;
	struct SNode* Next;
}*Stack;
Stack CreateStack() {//创建堆栈
	Stack S = (Stack)malloc(sizeof(struct SNode));
	S->Next = NULL;
	return S;
}
bool IsEmpty(Stack S) {//判断堆栈是否为空,空则返回真值
	return (S->Next == NULL);
}
Stack Push(Stack S, int x) {//堆栈是要求后入先出,所以用头插法
	Stack p = (Stack)malloc(sizeof(struct SNode));
	p->Data = x;
	p->Next = S->Next;
	S->Next = p;
	return S;
}
ElementType Pop(Stack S) {//将栈顶元素返回并将其删除
	if (IsEmpty(S)) {
		//printf("堆栈为空\n");
		return 0;
	}
	Stack p = S->Next;
	ElementType x = p->Data;
	S->Next = p->Next;
	free(p);
	return x;
}
void Change(char s[]) {//将中序表达式转为后缀表达式(读取的是一行字符串)
	//首先将输入的字符串处理一下
	for (int i = 0; s[i]; i++) { //进行判断,字符串中是否存在除空格、数字和四则运算符以及括号外的字符
		if (s[i] != ' ' && !(s[i] >= '0' && s[i] <= '9')
			&& !(s[i] == '+' || s[i] == '-' || s[i] == '*' || s[i] == '/') && !(s[i] == '(' || s[i] == ')')) {
			printf("表达式错误!\n");
			return;
		}
	}
	int i = 0;
	while (s[i]) {//将字符串中的空格全部删去
		if (s[i] == ' ')for (int j = i; s[j]; j++)s[j] = s[j + 1];
		else i++;
	}
	char t[105][105];
	int h = 0, p = 0;
	for (int i = 0; s[i]; i++) {
		if (!(s[i] >= '0' && s[i] <= '9')) {
			int k = 0;
			if (h != i) {
				for (int j = h; j < i; j++)t[p][k++] = s[j];
				t[p++][k++] = '\0';
				t[p][0] = s[i]; t[p++][1] = '\0';
			}
			else {
				t[p][0] = s[i];
				t[p++][1] = '\0';
			}
			h = i + 1;
		}
		if (s[i + 1] == '\0') {
			int k = 0;
			for (int j = h; s[j]; j++)t[p][k++] = s[j];
			t[p++][k++] = '\0';
		}
	}
	Stack S = CreateStack();//创建堆栈,用来存运算符
	for (int i = 0; i < p; i++) {
		if (t[i][0] >= '0' && t[i][0] <= '9') {//是数字,直接输出
			printf("%s ", t[i]);
			//要说的是,因为数字可能是多位的,为了方便,统一隔开一个空格
		}
		else if (t[i][0] == '(' || IsEmpty(S)) {//'('直接入栈,栈为空也直接入栈
			char b = t[i][0];
			S = Push(S, b);
		}
		else if (t[i][0] == ')') {// ')' 将符号栈中的元素依次出栈并输出, 直到 “(“, “(“只出栈, 不输出
			//有')'出现,则一定有'('出现
			char b = Pop(S);
			while (b != '(') {
				printf("%c ", b);
				b = Pop(S);
			}
			//if (b != '(') S = Push(S, b);
		}
		else {
			char b = t[i][0];
			char c = Pop(S);//将栈顶元素取出
			//当新的运算符的优先级小于等与栈顶元素,将栈顶元素输出,而后往下继续判断
			if (c == '+' || c == '-') {
				if (b == '+' || b == '-') {//优先级等于栈顶元素
					printf("%c ", c);
					c = Pop(S);//往后继续判断
					while (c != '(' && !IsEmpty(S)) {
						//因为加法与减法优先级最小,所以不用进行判断,直接输出
						printf("%c ", c);
						c = Pop(S);
					}
				}
			}
			else if (c == '/' || c == '*') {//因为最大的优先级就是乘法和除法
				if (b == '/' || b == '*') {
					printf("%c ", c);
					c = Pop(S);
					while (c != '-' && c != '+' && !IsEmpty(S)) {
						printf("%c ", c);
						c = Pop(S);
					}
				}
				else if (b == '+' || b == '-') {
					printf("%c ", c);
					c = Pop(S);//往后继续判断
					while (c != '(' && !IsEmpty(S)) {
						printf("%c ", c);
						c = Pop(S);
					}
				}
			}
			S = Push(S, c);//将c重新压回堆栈
			S = Push(S, b);//将新的运算符压栈
		}
	}
	//将输入的数组遍历一遍后,将栈中的元素全部输出
	while (!IsEmpty(S)) printf("%c ", Pop(S));
	printf("\n");
}

int main() {
	char s[1005];
	while (gets_s(s)) {
		Change(s);
		printf("\n");
	}
	return 0;
}
/*
测试样例一:
输入:2*(9+6/3-5)+4
输出:2 9 6 3 / + 5 - * 4 +
测试样例二:
输入:16568*(9846+666/333-984)+4562
输出:16568 9846 666 333 / + 984 - * 4562 +
测试样例三:
输入:5+6/2-3*4
输出:5 6 2 / 3 4 * - +
测试样例四:
输入:3+(2-5)*6/3
输出: 3 2 5 - 6 * 3 / +
测试样例五:
输入:(3+4)*5-6
输出:3 4 + 5 * 6 -
*/

运行结果:

堆栈的实现是挺简单的,比较难的是对字符串的操作,博主也是调了挺久的bug

嗯,再代码的最后有测试样例,都是博主亲自运行过了,就比较懒,不想贴图了

如果大家拿代码去运行出现什么bug的话,欢迎评论哦!

因为本来是想将求得的后缀表达式变成一个字符串进行输出的,但是估计比较复杂,而且没多少时间来琢磨这个,后面有时间会再写一遍博客,将它真正的按字符串输出顺便进行计算。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

xiaoyuer2815

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值