中缀表达式
中缀表达式是一种通用的算术或逻辑公式表示方法,操作符以中缀形式处于操作数的中间。中缀表达式是人类世界常用的算术表示方法。
例如:5+3*(2-7)
虽然人类可以很容易理解与分析中缀表达式,但对计算机来说中缀表达式却是很复杂的,但对计算机来说,计算前缀或后缀表达式的值非常简单。因此计算表达式的值时,通常需要先将中缀表达式转换为前缀或后缀表达式,然后再进行求值。
中缀表达式转换为后缀表达式求值
- 初始化OPTR栈和OPND栈,一个用来存储运算数字,一个用来存储运算符
- 扫描表达式,读入第一个字符ch,当输入的ch为‘==’时停止进栈。
- 若ch不是运算符,则压入OPND栈,读入下一个字符ch
- 若ch时运算符,则根据OPTR的栈顶元素和ch的优先级比较结果进行下一步操作。
-若是小于,则ch压入OPTR栈,读入下一个字符ch
–若是大于,则弹出OPTR栈顶的运算符,从OPND栈中弹出两个数,经行相应的运算,结果压入OPND栈
–若是等于,则OPTR的栈顶元素是“(”且ch是“)”,这时依次弹出“(”之上的运算符再从OPND栈中弹出两个数,经行相应的运算,结果压入OPND栈
3、OPND栈顶元素即为表达式求值结果,返回此元素
根据表格判断运算符的优先级
下面是由c++实现的代码:
#include<iostream>
#include<stdlib.h>
using namespace std;
#define MAXSIZE 5
typedef struct Stack {
char* base;
char* top;
int stacksizze;
}stack;
typedef struct opnd {
int* base;
int* top;
int stacksizze;
}OPND;
void init_stack(stack& pt);//初始化栈
void init_OPND(OPND& pd);
void push_stack(stack& pt, char c);//运算符入栈
void push_OPND(OPND& pd, int c);//数字入栈
char pop_stack(stack& pt);//运算符出栈
int pop_opnd(OPND& pd);//运算数字出栈
int empty_stack(stack& pt);//判断栈是否为空
void Matching(stack& pt);
int in_stack(char c);//判断读入的ch是否为运算符
char gettop(stack& pt);//获取栈顶元素
int get_OPND(OPND& pd);//获取运算数栈顶元素
char precede(char a, char b);//判断运算符优先级
int Operate(int a, char b, int c);//经行运算
int EvaluateExpression(stack& pt, OPND& pd);//表达式求值
void main() {
stack pt;
OPND pd;
init_stack(pt);
init_OPND(pd);
cout << "最终结果是:" << EvaluateExpression(pt, pd);
}
int get_OPND(OPND& pd) {
int ch;
ch = *(pd.top - 1);
return ch;
}
void init_stack(stack& pt) {
pt.base = new char[MAXSIZE];
pt.top = pt.base;
pt.stacksizze = MAXSIZE;
}
void init_OPND(OPND& pd) {
pd.base = new int[MAXSIZE];
pd.top = pd.base;
pd.stacksizze = MAXSIZE;
}
void push_stack(stack& pt, char c) {
if ((pt.top - pt.base) == pt.stacksizze) {//判断栈是否已满
cout << "栈已满!操作失败!";
exit(-1);
}
else {
*(pt.top++) = c;
}
}
char pop_stack(stack& pt) {
char c;
if (pt.top == pt.base) {//判断栈是否为空
cout << "pt栈为空!操作失败!";
exit(-1);
}
else {
c = *(--pt.top);
return c;
}
}
int empty_stack(stack& pt) {
if (pt.base == pt.top) {//判断栈为空与否
return 0;
}
else {
return 1;
}
}
void Matching(stack& pt) {//括号匹配
int flag = 1;
char ch;
cout << "请输入字符:";
cin >> ch;
while (ch != '#' && flag) {
switch (ch) {
case '(':
case '[':
push_stack(pt, ch); break;
case ')':
if (empty_stack(pt) && pop_stack(pt) == '(') {
flag = 0;
}
break;
case ']':
if (empty_stack(pt) && pop_stack(pt) == ']') {
flag = 0;
}
break;
}
printf("请继续输入一个字符: (结束请输入:'#')");
cin >> ch;
}
if (flag) {
printf("匹配失败!");
}
else {
printf("匹配成功!");
}
}
int in_stack(char c) {
if ('0' <= c && c <= '9') {
return 1;
}
else
{
return 0;
}
}
char gettop(stack& pt) {
char ch;
ch = *(pt.top - 1);
return ch;
}
char precede(char ch, char c) {//判断运算符优先级
switch (c)
{
case '+':
if (ch == '+')return '>';
if (ch == '-')return '>';
if (ch == '*')return '>';
if (ch == '(')return '<';
if (ch == ')')return '>';
if (ch == '#')return '<';
case '-':
if (ch == '+')return '>';
if (ch == '-')return '>';
if (ch == '*')return '>';
if (ch == '(')return '<';
if (ch == ')')return '>';
if (ch == '#')return '<';
case '*':
if (ch == '+')return '<';
if (ch == '-')return '<';
if (ch == '*')return '>';
if (ch == '/')return '>';
if (ch == '(')return '<';
if (ch == ')')return '>';
if (ch == '#')return '>';
case '/':
if (ch == '+')return '<';
if (ch == '-')return '<';
if (ch == '*')return '>';
if (ch == '(')return '<';
if (ch == ')')return '>';
if (ch == '#')return '<';
case '(':
if (ch == '+')return '<';
if (ch == '-')return '<';
if (ch == '*')return '<';
if (ch == '(')return '<';
if (ch == ')')return '=';
if (ch == '#')return ' ';
case ')':
if (ch == '+')return ')';
if (ch == '-')return ')';
if (ch == '*')return ')';
if (ch == '(')return ')';
if (ch == ')')return ')';
if (ch == '#')return ')';
case '#':
if (ch == '+')return '>';
if (ch == '-')return '>';
if (ch == '*')return '>';
if (ch == '/')return '>';
if (ch == '(')return '<';
if (ch == ')')return ' ';
if (ch == '#')return '=';
}
}
int Operate(int a, char b, int c) {
switch (b) {
case '+':return a + c;
case '-':return a - c;
case '*':return a * c;
case '/':return a / c;
}
}
int EvaluateExpression(stack& pt, OPND& pd) {
char ch;
int temp;
int flag = 0;
int a, b;
cout << "请开始输入表达式(输入'='结束):";
cin >> ch;
while (ch != '=')
{
if (in_stack(ch)) {
/*cout << "请再输入一次数据:" << endl;
cin >> temp;
int int_data = (int)(str_data - '0');*/
temp = (int)(ch - '0');
push_OPND(pd, temp);//此时的ch为char型()
cout << "请继续输入:";
cin >> ch;
}
else {//当ch为运算符时
if (!empty_stack(pt)) {
push_stack(pt, ch);
cout << "请继续输入:";
cin >> ch;
}
else{
switch (precede(gettop(pt), ch))
{
case '<':
push_stack(pt, ch);
cout << "请继续输入:";
cin >> ch; break;
case '>':
a = pop_opnd(pd);
b = pop_opnd(pd);
push_OPND(pd, Operate(b, pop_stack(pt), a));//把运算后的结果入数字栈
push_stack(pt, ch);//把运算符入栈
cout << "请继续输入:";
cin >> ch;
break;
case ')':
while (gettop(pt) !='(') {
int c = pop_opnd(pd);
int d = pop_opnd(pd);
push_OPND(pd, Operate(d, pop_stack(pt), c));//把运算后的结果入数字栈
}
pop_stack(pt);//把左括号出栈
cout << "请继续输入:";
cin >> ch;
break;
}
}
}
}
while (empty_stack(pt)) {//把符号栈中的元素全部出栈,并进行运算
int a = pop_opnd(pd);
int b = pop_opnd(pd);
push_OPND(pd, Operate(b, pop_stack(pt), a));
}
return get_OPND(pd);
}
void push_OPND(OPND& pd, int c) {
if ((pd.top - pd.base) == pd.stacksizze) {//判断栈是否已满
cout << "栈已满!操作失败!";
exit(-1);
}
else {
*(pd.top++) = c;
}
}
int pop_opnd(OPND& pd) {
int c;
if (pd.top == pd.base) {//判断栈是否为空
cout << "pd栈为空!操作失败!";
exit(-1);
}
else {
c = *--pd.top;
return c;
}
}
感谢观看!
有不懂的地方,欢迎评论区交流。