中缀表达式就是我们平时运算表达式,其特点是运算符总是处于两个运算对象之间。但是该表达式计算机处理起来较为麻烦,会将其转写成后缀表达式(具体如何通过后缀表达式求解见:C++栈的应用——后缀表达式求解),后缀表达式也叫逆波兰表达式,后缀表达式的特点是每个运算符都置于两个运算对象之后。

那么中缀表达式如何转为后缀表达式呢?

将中缀表达式:“2*(9+6/3-5)+4”从左往右逐个字符进行遍历获得操作符,同时建立一个空栈stack。

一、当操作符为数字时,直接打印输出

二、当操作符为左括号时,将其存储到栈stack中成为元素符

三、当操作符为右括号为,从栈stack中弹出栈顶元素符,并输出,直到匹配到左括号为止

四、当操作符为运算符时,需要将其与栈顶元素符优先级做一个比较

1、当操作符优先级大于栈顶元素符优先级的时候,直接入栈

2、当操作符优先级小于或等于栈顶元素优先级的时候,弹出栈顶元素符并打印,并继续与下 一个栈顶元素符做比较,直到操作符优先级大于栈顶元素优先级或栈为空为止,这时操作符入栈。

运算符优先级:

优先级最高 优先级其次 优先级最低
*     / +      - (     )

中缀转后缀的理论就介绍到这儿,那它如何通过代码实现的呢?这里栈选用链式存储的栈,具体介绍可见C++实现栈的顺序存储与链式存储。

1、首先提供栈的基本操作函数

/有关栈的基本操作
//节点
class linknode
{
public:linknode* next;
};
//自定义数据
class my_data
{
public:linknode* node;char c;
};
//链式栈
class linkstack
{
public:linknode head;int size;
};
//初始化栈
linkstack* init_linkstack()
{linkstack* stack=new linkstack;stack->head.next=NULL;stack->size=0;return stack;
}
//入栈
void push_linkstack(linkstack* stack,linknode* data)
{data->next=stack->head.next;stack->head.next=data;stack->size++;
}
//出栈
void pop_linkstack(linkstack* stack)
{stack->head.next=stack->head.next->next;stack->size--;
}
//返回栈顶元素
linknode* top_linkstack(linkstack* stack)
{return stack->head.next;
}

2、一些判断函数

//判断字符是否为数字
int isnumber(char c)
{return c>='0' && c<='9';
}
//判断是否为左括号
int isleft(char c)
{return c=='(';
}
//判断是否为右括号
int isright(char c)
{return c==')';
}
//判断是否为运算赋
int isoperator(char c)
{return c=='+' || c=='-' || c=='*' || c=='/';
}
//判断运算符优先级
int getpriority(char c)
{if (c=='*' || c=='/'){return 2;}if (c=='+' || c=='-'){return 1;}if (c=='(' || c==')'){return 0;}return -1;
}

3、按转换规则的实现代码

int main()
{linkstack* stack=init_linkstack();char str[]="2*(9+6/3-5)+4";for (int i = 0; i < sizeof(str)/sizeof(char); i++) //逐字符遍历str获得操作符;{my_data* data=new my_data;data->node=NULL;data->c=str[i];if (isnumber(str[i])) //如果操作符为数字,直接输出{cout<<str[i]<<"\t";}if (isleft(str[i]))  //如果操作符为左括号,直接进栈{push_linkstack(stack,(linknode*)data);}if (isright(str[i])) //如果操作符为右括号从栈里往外弹元素直到弹出左括号为止{while (stack->size>0){char* c=&((my_data*)top_linkstack(stack))->c;if (isleft(*c))     //匹配到左括号弹出{pop_linkstack(stack);break;}//匹配到运算符,打印运算符并弹出运算符cout<<*c<<"\t";pop_linkstack(stack);}}//如果操作符是运算符if (isoperator(str[i])){if (stack->size==0)   //如果栈为空,操作符直接入栈{push_linkstack(stack,(linknode*)data);}else  //不是空栈则需要进行优先级比较{while (stack->size>0)  //操作符与栈中元素符号优先级比较{char* c=&((my_data*)top_linkstack(stack))->c; //栈顶元素符号if (getpriority(data->c)>getpriority(*c)) //操作符符优先级高于栈中top元素符号,操作符入栈{push_linkstack(stack,(linknode*)data);break;}if (getpriority(data->c)<=getpriority(*c)) //操作符优先级低于或等于栈中top元素符号,并打印并弹出栈中top元素{cout<<((my_data*)top_linkstack(stack))->c<<"\t";pop_linkstack(stack);if (stack->size==0)  //弹出top元素后栈为空,操作符直接入栈{push_linkstack(stack,(linknode*)data);break;}}}}}}//如果str遍历完了,但栈中还有元素符号,将其逐个输出,直到栈空为止while (stack->size>0){cout<<((my_data*)top_linkstack(stack))->c<<"\t";pop_linkstack(stack);}cout<<endl;system("pause");return 0;
}

4、结果

C++栈的应用——中缀转后缀相关推荐

  1. 使用栈结构实现中缀转后缀算法(python)

    看了网上的中缀变后缀的python算法,感觉都没北大陈斌老师讲的好,最近又在解决密码学的问题,现在遇到算式里含有自变量没办法解决,害,python学的太菜也不知道咋解决.但觉得有必要和大家分享用栈来解 ...

  2. 栈应用:中缀转后缀,中缀转前缀

    中缀转后缀转换过程需要用到栈,具体过程如下: 从左到右扫描字符串 1)如果遇到操作数,我们就直接将其输出(输出我们用队列保存). 2)如果遇到操作符,当栈为空直接进栈,不为空,判断栈顶元素操作符优先级 ...

  3. 用栈实现中缀转后缀(c++)

    用栈实现表达式中缀转后缀 栈的特点是先进后出,可以用来将中缀表达式转换成后缀表达式,在本程序中对表达式进行了限制,数字0-9,运算符只有±*/(),缩小了问题规模. 转换思路:将表达式输入,全部数据以 ...

  4. C语言实现中缀转后缀并计算表达式结果

    文章目录 一.问题描述 二.AC代码 三.注意点 四.实现思路/代码解析 一.问题描述 [问题描述] 从标准输入中读入一个整数算术运算表达式,如5 - 1 * 2 * 3 + 12 / 2 / 2   ...

  5. 数据结构:用栈实现表达式的转换(文字描述+详细步骤示例)——中缀转后缀

    中缀转后缀 从左到右扫描这个中缀表达式,如果遇到操作数,就直接写出来:如果遇到运算符,就将其入栈. 入栈之前,首先将当前运算符与栈顶运算符比较优先级,如果当前运算符优先级小于等于栈顶运算符的优先级,则 ...

  6. 栈应用(中缀表达式转后缀表达式并计算后缀表达式的值)

    [0]README 0.1) 本文旨在总结 中缀表达式转后缀表达式并计算后缀表达式的值 的步骤,并给出源代码实现: 0.2) 本文中涉及到的源代码均为原创,是对中缀转后缀和计算后缀的简单实现,(旨在理 ...

  7. 数据结构之栈实现中缀转后缀并计算结果

    一.中缀变后缀过程分析 给定一个中缀,最后变为后缀的过程其实并不算复杂,下面分析一下过程: 1. 首先面对一个中缀表达式,我们需要两个栈,一个用来存放运算符,即符号栈 operatorstack,一个 ...

  8. 数据结构 - 栈 (逆波兰计算器)(栈的三种表达式)(前缀、中缀和后缀表达式,后缀也叫逆波兰表达式)(中缀表达式转后缀表达式实现步骤及完整代码)

    栈的三种表达式:前缀.中缀和后缀表达式,后缀也叫逆波兰表达式 前缀(波兰表达式) 中缀(对人来讲很好理解,对于计算机来讲就方便了,一般会把中缀表达式转换成后缀表达式) 后缀(逆波兰表达式) 计算过程 ...

  9. (王道408考研数据结构)第三章栈和队列-第三节1:栈的应用之括号匹配问题和表达式问题(前缀、中缀和后缀)

    前面我们就说过,栈是一种先进后出的线性表,这种先进后出的特性就决定了它在一类场合或问题中会经常被用到--递归.考研数据结构中所涉及的利用栈结构解决递归问题或者考察栈结构特性的问题主要有这么几类 括号匹 ...

最新文章

  1. 一个Apache CollectionUtils.intersection 方法的简单问题
  2. Module Zero之用户管理
  3. lstm 根据前文预测词_干货 | Pytorch实现基于LSTM的单词检测器
  4. 双目视觉几何框架详解(玉米专栏8篇汇总)
  5. linux+top+常用参数,linux的top命令参数详细说明
  6. 收藏 | 详解PyTorch中的ModuleList和Sequential
  7. linux 脚本在哪里编写,Linux 脚本编写基础(一)
  8. VS2010编译驱动程序
  9. After Effects报警最后日志消息是:<760504><SonyRawDecoder><5>
  10. php opendir 相对路径,我是wamp环境,怎么样让php的opendir函数可以接受相对路径?...
  11. 不可逆调速matlab,双闭环不可逆直流调速系统课程设计(matlab仿真设计)
  12. IT创业项目-赚钱项目-网赚项目:月入2W+的视频号创业项目
  13. poi在Excel中创建折线图
  14. 第5章 SIM卡锁定PIN解锁流程
  15. 项目落地 - 智能焊机,钢塑管(物联网技术应用)
  16. 微信小程序版的登录注册
  17. 大数据下数据频次计算问题与排序问题
  18. 大数据架构师技能图谱
  19. Unity实战 RTS3D即时战略游戏开发(十二) 战斗AI的控制
  20. 近期AI创业公司总结

热门文章

  1. AWS API gateway api CORS错误处理方法
  2. Xen中,使用XL还是XM?
  3. Stable Diffusion XL:更快,更强
  4. 贪心法 第4关:找到出现次数最多的数
  5. 中国电影百年经典台词100句
  6. 项目1在线交流平台-3.开发交流社区核心功能模块-7.显示私信信息
  7. c# jarray 快速提取_C#编程之C# JArray与JObject 的使用
  8. speedoffice(Excel)如何对图片进行旋转
  9. MySQL底层执行原理详解
  10. 方正SOA中间件的平台发展史