[C#笔记]实现四则运算

前置知识:人类使用的表达式一般为中缀表达式,这种表达式容易被人类理解,但不适合于机器计算。1920年,波兰科学家扬·武卡谢维奇(Jan ukasiewicz)发明了一种不需要括号的计算表达式的表示法将操作符号写在操作数之前,也就是前缀表达式,即波兰式(Polish Notation, PN)。将波兰式倒转,即逆波兰式,广泛用于使用堆栈的程序语言中。
Tips:源码在文章最底下。
↓--------------------正文--------------------↓
对于四则运算来说,程序的基本顺序为:输入->获取token->转换为逆波兰式->运算结果->输出。
--------------------输入--------------------
输入:这部分很简单,这里不细讲。
--------------------转化为逆波兰式--------------------
获取token:在四则运算中,为了方便获取,我们可以人为地定义一些符号的类型:
number : "0","1","2","3","4","5","6","7","8","9","."
left_bracket : "("
right_bracket : ")"
multiplication : "*"
division : "/"
addition : "+"
subtraction : "-"
这部分最复杂的地方在于"-",因为在数字中,它既表示负号,又表示减号,所以要在这个阶段就把负号连带数字一起提取出来。
对于负号,它有两种情况成立:
如果负号成立,那么可以把"-"当做number,加入到number中。
处理完数字后,开始处理操作符,即"+" , "-" , "*" , "/" , "(" , ")"
对于数字和操作符的处理,网上有详尽的规则:
例如:
检测"*",栈顶为"+",入栈;
检测"*",栈顶为"/",依次弹栈,直到栈空或栈顶为"("、"+"、"-",停止弹栈,"*"压栈;
检测"+",栈顶为"*",依次弹栈,直到栈空或栈顶为"(",停止弹栈,"+"压栈;
检测"+",栈顶为"-",依次弹栈,直到栈空或栈顶为"(",停止弹栈,"+"压栈;
检测到")",依次弹栈,直到栈顶为"(","("弹栈剔除,")"压栈。
为了debug方便,我选择为操作符分别创建分支。
--------------------运算结果--------------------
对于有堆栈的语言来说,逆波兰式的计算很好理解,即:
从头开始,遇到数字入栈,遇到操作符,弹出栈顶的两个数字进行计算,计算结果压栈,运行到表达式结束后,栈顶即运算结果。
有个小细节是,假如弹栈的数字按顺序分别是n1和n2,则n2为被减(除)数,n1是减(除)数。
--------------------输出--------------------
这部分同样很简单,就不提了。
--------------------总结--------------------
像我这种代码新手,最难处理的部分反而是控制循环下的分支,其次才是数据结构,所以我用了看起来非常弱智的方式来写分支:
也就是
去除了else,加入了continue后,每一个分支的入口都被显式控制了,debug效率倒是方便了不少,就是老程序员乍一眼看到嵌套地狱估计会高血压。
--------------------代码示例--------------------
最后附上测试结果和源码,平台是linqpad,主程序部分如果要用在控制台或者winform还得自行修改。
debug结果示例:
源代码: