逆波兰表达式

来源:互联网 发布:55267网络电视直播 编辑:程序博客网 时间:2024/05/21 17:05

中缀转后缀:

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

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

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


中缀转后缀

#include <cstdio>#include <cstring>#include <algorithm>#include <stack>#define maxn 100005typedef 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 100005typedef 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)   //errorreturn 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 0num[++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;}


原创粉丝点击