2023.04.10 定时测试随笔 T1

T1 表达式的转换

传送门:洛谷P1175

总结题意 :

  • 将中缀表达式转化为后缀表达式;

  • 再将后缀表达式中每一次的运算结果输出。

先解决第一个问题,如何转化表达式:

Q1:

我们先声明两个栈,一个是符号栈 \(sta\),一个是结果栈 \(a\);
那么遍历中缀表达式,

  • 对于每一个 '\(0\)'~'\(9\)' 的字符,直接进入结果栈;
  • 对于么一个运算符 ' + , - , * , / ' ,先把符号栈中所有优先级高于或的等于它的出栈并进入结果栈,再将它入栈;
  • 对于左括号 或 运算符 '^' (开始做的时候没注意到), 我们直接入符号栈;
  • 对于右括号,先把符号栈中所有的运算符出栈并进入结果栈,直到遇到一个左括号,左括号出栈;
  • 遍历完之后再将符号栈剩余的运算符都进入结果栈。

不理解的话可以拿一组样例手模一下


Q2:

第二问相对于第一问较简单,遍历结果串,如果是数字就存下,当遇到一个运算符时取出刚存下的两个树进行该运算,再将算出的数存下,这就是第一次运算的结果,输出存下的数字以及结果串剩下的字符,接着从刚刚的那个运算符的下一位继续遍历;
举个例子:结果串:8 2 3 2 * + 2 2 3 ^ ^ + * 9

i                     结果串                  存下的数
1			8			8
2			2			8 2
3			3			8 2 3
4			2			8 2 3 2
5			*			8 2 6
6			+			8 8
7			2			8 8 2
8			2			8 8 2 2
9			3			8 8 2 2 3
10			^			8 8 2 8
11			^			8 8 256
12			+			8 264
13			*			2112
14			9			2112 9
15			/			234

放代码:

#include <bits/stdc++.h>

using namespace std;

const int maxn = 100 + 5;
char c[maxn], a[maxn];
int n, tot;
char sta[maxn];
int top;

int query(char ch) {
   if (ch == '(' || ch == ')') return 0;
   if (ch == '+' || ch == '-') return 1;
   if (ch == '*' || ch == '/') return 2;
   if (ch == '^') return 3;
   return 1;
}

void stapush(char ch) {
   sta[++ top] = ch;
}

void stapop() {
   top --;
}

void Change() {
   for (int i = 1; i <= n; ++ i) {
   	if (c[i] <= '9' && c[i] >= '0')
   		a[++ tot] = c[i];
   	else if (c[i] == '^' || c[i] == '(')
   		stapush(c[i]);
   	else if (c[i] == '+' || c[i] == '-' || c[i] == '*' || c[i] == '/') {
   		int dat = query(c[i]);
   		for (int j = top; j >= 1; -- j) {
   			if (query(sta[j]) < dat) break;
   			a[++ tot] = sta[j];
   			stapop();
   		}
   		stapush(c[i]);
   	}
   	else if(c[i] == ')') {
   		for (int j = top; j >= 1; -- j) {
   			if (sta[j] == '(') {
   				stapop();
   				break;
   			}
   			a[++ tot] = sta[j];
   			stapop();
   		}
   	}
   }
   while (top) {
   	a[++ tot] = sta[top];
   	stapop();
   }
}

int b[maxn];
void read() {
   scanf("%s", c + 1);
   n = strlen(c + 1);
   Change();
   int ans = 0;
   for (int i = 1; i <= n; ++ i)
   	printf("%c ", a[i]);
   printf("\n");
   int j = 0;
   for (int i = 1; i <= tot; ++ i) {
   	if (a[i] <= '9' && a[i] >= '0')
   		b[++ j] = a[i] - 48;
   	else {
   		if (a[i] == '^')
   			ans = pow(b[j - 1], b[j]);
   		else if (a[i] == '+')
   			ans = b[j] + b[j - 1];
   		else if (a[i] == '-')
   			ans = b[j - 1] - b[j];
   		else if (a[i] == '*')
   			ans = b[j] * b[j - 1];
   		else
   			ans = b[j - 1] / b[j];
   		b[j - 1] = ans; j --;
   		for (int k = 1; k <= j; ++ k)
   			printf("%d ", b[k]);
   		for (int k = i + 1; k <= tot; ++ k)
   			printf("%c ", a[k]);
   		printf("\n");
   	}
   }
}

int main() {
   read();
   return 0;
}
posted @ 2023-04-10 15:55  florence25  阅读(40)  评论(0)    收藏  举报