中缀表达式的计算主要要转换为后缀表达式。
例如 中缀表达式->(1+2)*3-4 转换为后缀表达式 12+3*4-
至于后缀表达式的计算就很容易了 设定一个栈,然后后缀表达式从左到右一次进栈,如果当前的入栈的是数字就将其压入栈中,
如果是运算符,就从栈中弹出两个数字进行相应的运算,然后将运算后的数字压回栈中。当字符串完全处理之后,栈顶就是运算结果
PS:输入的后缀表达式是合法的才行。
那么中缀表达式如何转换为后缀表达式?(ch接受中缀表达式传递过来的字符)
1:ch 是'(' 放入栈;
2: ch 是 ‘)’一次输入栈中的运算符,直到遇到‘(’为止
3:如果ch是其它的合法字符,将ch与当前栈顶比较
a:ch优先级高于栈顶元素,ch入栈
b:ch 优先级低于或者等于 栈顶元素,输出栈顶元素,ch入栈
4:如果中缀表达式读取完成,依次输出栈中的元素直到栈空
举个例子:
对于中缀表达式 (A-B)/C+D
1 : '('进栈
2:A->压入输出字符
3:- 入栈
4:B 压入输出字符串
5: ')'一次输出栈里面的字符到输出字符串
6: ‘/’ 入栈
7: C 压入字符串
8: ’+‘ ’/‘出栈 然后’+‘入栈
9: D 压入输出字符串
10: 将栈中剩下的字符串依次输出
// calc.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" #include<stdio.h> #include<stdlib.h> #include<string.h> #define MAX_STACK_SIZE 100 #define MAX_EXPR_SIZE 100 void postfix(char *expr, char *outstr); int eval(char *outstr); typedef enum { lparen, rparen, pluss, minuss, timess, divide, mod, eos, operand } precedence; int stack_int[MAX_STACK_SIZE]; precedence stack_prece[MAX_STACK_SIZE]; char expr[MAX_EXPR_SIZE]; int isp[] = { 1, 19, 12, 12, 13, 13, 13, 0 }; int icp[] = { 20, 19, 12, 12, 13, 13, 13, 0 }; #define INT_ITEM 1 #define PRECE_ITEM 2 //入栈 void push(int *top, int a, precedence b, int flag) { if (*top >= MAX_STACK_SIZE - 1) { printf("stack overflow.\n"); exit(1); } //不同类型的元素进入不同的栈 if (flag == INT_ITEM) stack_int[++*top] = a; else if (flag == PRECE_ITEM) stack_prece[++ *top] = b; } //出栈 void pop(int *top, int *a, precedence *b, int flag) { if (*top < 0) { printf("stack overflow.\n"); exit(1); } //函数传进来的 a 和 b 分别接受不同的数值 if (flag == INT_ITEM) *a = stack_int[(*top)--]; else if (flag == PRECE_ITEM) *b = stack_prece[(*top)--]; } //将运算符号转换为特定的符号 precedence get_token(char *symbol, int *n, char *expr) { *symbol = expr[(*n)++]; // n 表示的是位置 switch (*symbol) { case '(': return lparen; case ')': return rparen; case '+': return pluss; case '-': return minuss; case '*': return timess; case '/': return divide; case '%': return mod; case '\0': return eos; default: return operand; //数字即被操作的符号 } } //特定的符号转换为运算符号 char precedencetochar(precedence token) { switch (token) { case pluss: return '+'; case minuss: return '-'; case divide: return '/'; case timess: return '*'; case mod: return '%'; case eos: return '\0'; //结束符号 default: return operand; //数字 } } //将中缀表达式转换为后缀表达式 void postfix(char *expr, char *outstr) { char symbol; precedence token, precevalue; int n = 0; int intvalue; int i = 0; int top = -1; stack_prece[0] = eos; for (token = get_token(&symbol, &n, expr); token != eos; token = get_token(&symbol, &n, expr)) { //如果取得的栈顶元素是数字存到新的数组中 if (token == operand) outstr[i++] = symbol; //如果遇到括号 else if (token == rparen){ while (stack_prece[top] != lparen) { pop(&top, &intvalue, &precevalue, PRECE_ITEM); outstr[i++] = precedencetochar(precevalue); } pop(&top, &intvalue, &precevalue, PRECE_ITEM); } //如果入栈的运算符优先级比当前栈顶的优先级低,弹出当前栈顶 else { if (top >= 0) while (isp[stack_prece[top]] >= icp[token]) { pop(&top, &intvalue, &precevalue, PRECE_ITEM); outstr[i++] = precedencetochar(precevalue); } push(&top, 0, token, PRECE_ITEM); } } while (top >= 0) { pop(&top, &intvalue, &precevalue, PRECE_ITEM); outstr[i++] = precedencetochar(precevalue); } outstr[i] = '\0'; } //计算后缀表达式 int eval(char *outstr) { precedence token, precevalue; char symbol; int op1, op2, result; int n = 0; int top = -1; token = get_token(&symbol, &n, outstr); precevalue = token; while (token != eos) { if (token == operand) { push(&top, symbol - '0', precevalue, INT_ITEM); } else { pop(&top, &op2, &precevalue, INT_ITEM); pop(&top, &op1, &precevalue, INT_ITEM); switch (token) { case pluss: push(&top, op1 + op2, precevalue, INT_ITEM); break; case minuss: push(&top, op1 - op2, precevalue, INT_ITEM); break; case timess: push(&top, op1*op2, precevalue, INT_ITEM); break; case divide: push(&top, op1 / op2, precevalue, INT_ITEM); break; case mod: push(&top, op1%op2, precevalue, INT_ITEM); break; default: break; } } token = get_token(&symbol, &n, outstr); } pop(&top, &result, &precevalue, INT_ITEM); return result; } int _tmain(int argc, _TCHAR* argv[]) { char expr[100], outstr[100]; int result; gets(expr); //输入的字符串 postfix(expr, outstr); result = eval(outstr); printf("the result is %d\n", result); return 0; }