中缀转后缀:
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;
}