表达式计算:中辍转后辍,一元操作符运算
中缀转后缀需要处理的有:
1. 操作数,操作符的提取
2. 括号等关系到运算符优先级的符号
3. 一元操作符(如 +(正), -(负)) 等
4. 操作符和操作数的匹配,括号的匹配
基本思路如下:
用一个链表 std::list<ExpressionToken> 储存将要生成的后缀表达式
用一个栈 std::stack<OperatorType> 储存操作符
判断当前节点,如果是操作数,直接加入后缀表达式中,如果是操作符,则比较前一个操作符和当前操作符的优先级,如果前一个操作符优先级较高,则将前一个操作符加入后缀表达式中,否则将操作符压入操作符栈,如果遇到反括号 ')', 则在操作符栈中反向搜索,直到遇到匹配的正括号为止,将中间的操作符依次加到后缀表达式中。
我的问题:如何处理一元操作符,包括 + - ! ?
比如表达式:(-2 - 1) + !((+3 + !0) - -2) || 1
按上面的思路,如何生成后缀表达式?
[解决办法]
偶看你满闲的, 去学一下编译原理吧, 真的.... 实在没空, 看看bison入门文档, 看个两天, 这些都不是问题....
[解决办法]
膜拜牛人,顺便接分
[解决办法]
老邓,没事看看the c++ programming language,里面c++之父写了个计算器,里面实现有你想要的。
最近写ssh的业务代码有个表达式解析的,直接改成java的了~~~
[解决办法]
接个分吧……
[解决办法]
我也推荐用Yacc之类的语法写。呵呵。
[解决办法]
这个看编译原理是怎么解决一元运算符的,忘了。
我当时写作业的时候,专门判断是不是正负号,没有处理其他的!等一元运算符。比如-3+2,最后后缀表达式是-32+,而且像3*-2这种是写成3*(-2)的,后缀应该是3-2*。处理符号的时候直接和数字计算了,+3直接处理成3了,这样可能不好。如果想输出,就在处理符号的时候不能计算。
步骤:
表达式栈:3
符号栈:
表达式栈:3
符号栈:*
表达式栈:3
符号栈:*(
表达式栈:3
符号栈:*(-
表达式栈:3 2
符号栈:*(-
表达式栈:3 -2
符号栈:*
表达式栈:3 -2 *
符号栈:
当时写的比较笨,不知道能不能通用,编译原理肯定有一个通用的解决方法。
可以保存一个一元运算符表,遇到一元运算符,将当前的表达式和符号栈都pop,然后将pop出来的符号和数字压入表达式栈栈。具体的再验证一下
[解决办法]
来接各分,老邓研究的很猛啊~
[解决办法]
不学lex/yacc而自己写,还真得穷折腾啊。
速而不达。
[解决办法]
这个以前实现过,不知道代码还在不在,给你找找
[解决办法]
那个。。。
你要是单纯地把中缀改为后缀式的话呢
你可以试试二叉树
这个思路很不错的吧
无论是波兰式还是逆波兰式
都是二叉树各种遍历形成的
单目运算符的话
也可以的
作为左子树的话就可以了
试试吧
你都这么大的级别了
应该没问题的吧
[解决办法]
以前我写过一个计算器,能够处理想SIN,COS,X!这种一元的操作符
想法是将一元的操作符的优先级置为最高,出栈时用不同于二元操作符的规则来进计算。
不过像+,-这种两种身份的操作符还得另外考虑,这个没试过
要是做计算器的话可不可以在把表达式压入栈中的时候判断一下,如果有两个这样的操作符一起进栈立即判断,然后合并成一个运算符重新压入栈中
如果你想求表达式,我还真不会这种表达式该如何写,可不可以添0啊
[解决办法]
(-2 - 1) + !((+3 + !0) - -2) || 1
按照我的理解,后缀表达式为:
2-1-3+0!+2-2-!+1||
操作符要记录属性:是否为一元操作符。
致于是否为一元操符的判断,那就要根据上下文来判断了。
[解决办法]
我觉得在两个+,-之间可以填0,用个特殊字符表示,出栈时将此字符忽略。
入栈时设个标识FLAG,连续压入两个+,-或者+,-前没有数字就添个0。
至于一元操作符,还和我刚才说的一样,置一个最高的优先级,出栈另设规则。
((-2 - 1) + !((+3 + !0) - -2))|| 1
就变成(零 - 2 - 1)+ !((零 + 3 + !0) - 零 - 2) || 1
波兰式好像是 2零-1-零3+0!+零-2-!+1||
去掉零就是 2-1-3+0!+-2-!+1||
[解决办法]
楼上的几个台强悍了! 代码都出来了!
这里我就简单说一下算法的数据结构吧:
比较 - + * ! 等运算符 课先给它们定一个权值weight 优先级大的weight大
如:* weight=2 > + weight=1
然后把数和运算符一起放到排序二叉树中 提取时按中序遍历
之后就是 计算了 这里我就不说了 相信你会 !
[解决办法]
小弟以为,生成逆波兰式,只需要判断操作符优先级就行了。一元操作符应该是最高优先级吧?直接入栈。
比如(~a|x)&~(y|z) 的逆波兰式为 a~x|yz|~&
老邓是否以为然?
[解决办法]
表达式分析的题,不用看了,直接上Boost.Spirit。
Spirit.Qi + Spirit.Karma双剑合璧,完美解决此类问题。
中缀转后缀的示例代码:
[url=http://www.boost.org/doc/libs/1_42_0/libs/spirit/example/karma/calc2_ast.hpp]
[解决办法]
我觉的要判断一元操作符的话就要把一元操作符存贮起来,每次碰到操作附的时候看是不是一元操作符,
每个一元操作符都有单独的处理,这样句可以解决,当然这样的话代码就很长
[解决办法]
哦,! 是取反啊,呵呵,我还以为是阶乘呢。
(-2 - 1) + !((+3 + !0) - -2) || 1
如果 || 的优先级比 ! 小,比 + 大的话:-2 1 - +3 0 ! + -2 - ! 1 || +
如果 || 的优先级比 ! 小,比 + 小的话:-2 1 - +3 0 ! + -2 - ! + 1 ||
[解决办法]
中序遍历表达式树得到中缀,后序遍历表达式树就得到后缀