逆波兰表达式

中缀转后缀:

1.遇到操作数:直接输出(添加到后缀表达式中)
2.栈为空时,遇到运算符,直接入栈
3.遇到左括号:将其入栈
4.遇到右括号:执行出栈操作,并将出栈的元素输出,直到弹出栈的是左括号,左括号不输出。
5.遇到其他运算符:加减乘除:弹出所有优先级大于或者等于该运算符的栈顶元素,然后将该运算符入栈
6.最终将栈中的元素依次出栈,输出。

特殊:^ 乘方运算   直接入栈

算符‘+’和‘(’的优先关系应是取决于它们出现的位置


中缀转后缀

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <stack>
#define maxn 100005
typedef long long ll;

using namespace std;


int ch(char c)
{
	if (c == '+') return 1;
	if (c == '-') return 1;
	if (c == '*') return 2;
	if (c == '/') return 2;
	if (c == '^') return 3;
	if (c == '(') return 0;
}
int main()
{
//	freopen("input.txt", "r", stdin);
	int n, top = 0;
	char c, op[maxn];

	scanf("%d", &n);
	while (n--) {
	    getchar();
		while (1) {
			c = getchar();
			if (c == '#') 
				break;
			if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'))
				printf("%c", c);
			else if (c == '(' || top == 0)
				op[++top] = c;
			else if (c == ')') {
				while (op[top] != '(') {
					printf("%c", op[top]);
					top--;
				}
				top--;
			}
			else {
				//'^'和'('直接压栈不用判断
				while (top != 0 && ch(op[top]) >= ch(c) && op[top] != '(' && c != '^') {
					printf("%c", op[top]);
					top--;
				}
				op[++top] = c;
			}
		}
		while (top) {
			printf("%c", op[top]);
			top--;
		}
		printf("\n");
	}
	return 0;
}

表达式求值:有正负数并判断是否为合法表达式

#include <cstdio>
#include <cstring>
#include <algorithm>
#define maxn 100005
typedef long long ll;

using namespace std;

int n, ls, numtop, optop, ans;
char s[maxn], op[maxn];
int num[maxn];
bool neg, dig;
int flag;
int ch(char c)
{
	if (c == '+') return 1;
	if (c == '-') return 1;
	if (c == '*') return 2;
	if (c == '/') return 2;
	if (c == '^') return 3;
	if (c == '(') return 0;
}
bool check(char c)
{
	if (c == '+' || c == '-' || c == '*' || c == '/'
		|| c == '^' || c == '%' || c == '(') return true;
	return false;
}
void NumtoStack(int x)
{
	if (neg) num[++numtop] = -x;
	else  num[++numtop] = x;
	dig = false;
	neg = false;
}
bool Cal(int x, char c, int y)
{
	if (c == '+') ans = x + y;
	else if (c == '-') ans = x - y;
	else if (c == '*') ans = x*y;
	else if (c == '/') {
		if (y == 0) return false;
		ans = x / y;
	}
	else if (c == '%') {
		if (y == 0) return false;
		ans = x % y;
	}
	else if (c == '^') {
		ans = 1;
		for (int i = 1; i <= y; i++)
			ans *= x;
	}
	return true;
}
int Bracket()
{
	while (optop != 0 && op[optop] != '(') {
		if (numtop < 2)   //error
			return 1;
		int sec = num[numtop], fir = num[numtop - 1];
		numtop -= 2;
		if (op[optop] == '^' && sec < 0) return 1;
		if (!Cal(fir, op[optop], sec))
			return 2;  //div 0
		num[++numtop] = ans;
		optop--;
	}
	if (optop == 0) return 1;
	optop--;
	return 0;
}
int Operator(char c)
{
	while (optop != 0 && ch(op[optop]) >= ch(c)) {
		if (numtop < 2) return 1;
		int sec = num[numtop], fir = num[numtop - 1];
		numtop -= 2;
		if (op[optop] == '^' && sec < 0) return 1;
		if (!Cal(fir, op[optop], sec)) return 2;
		num[++numtop] = ans;
		optop--;
	}
	op[++optop] = c;
	return 0;
}
int Finish()
{
	while (optop != 0) {
		if (numtop < 2) return 1;
		int sec = num[numtop], fir = num[numtop - 1];
		numtop -= 2;
		if (op[optop] == '^' && sec < 0) return 1;
		if (!Cal(fir, op[optop], sec)) return 2;
		num[++numtop] = ans;
		optop--;
	}
	if (numtop != 1) return 1;
	return 0;
}
int main()
{
	//freopen("input.txt", "r", stdin);
	scanf("%d", &n);
	while (n--) {
		numtop = 0; optop = 0;
		scanf("%s", s);
		ls = strlen(s);
		int x = 0; 
		neg = false; dig = false; flag = 0;
		for (int i = 0; i < ls; i++) {
			if (s[i] == '-' && (i == 0 || check(s[i - 1])))  //负数
				neg = true;
			else if (s[i] >= '0' && s[i] <= '9') {
				x = x * 10 + s[i] - '0';
				dig = true;
				continue;
			}
			else {  //遇到操作符
				if (s[i - 1] == '(' && s[i] != '(') {
					flag = 1;
					break;
				}
				if (dig) {  //之前的数字进栈
					NumtoStack(x);
					x = 0;
				}
				if (s[i] == '(' || s[i] == '^' || optop == 0)
					op[++optop] = s[i];
				else if (s[i] == ')') {
					flag = Bracket();
					if (flag == 1 || flag == 2) break;
				}
				else {
					flag = Operator(s[i]);
					if (flag == 1 || flag == 2) break;
				}
			}
		}
		if (dig) NumtoStack(x);
		if (flag == 0)
            flag = Finish();
		if (flag == 1) printf("error.\n");
		else if (flag == 2) printf("Divide 0.\n");
		else printf("%d\n", num[numtop]);
	}
	return 0;
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值