1. 前期准备
对于括号有这样的规则:
——只有( 可以多于) 的个数,此时在行尾补) 。
——取模|...|不能嵌套。(在casio中没有这个问题,因为每按一次取模键,你会得到两个|,所以可以定义他们的大小)
——无论是圆括号还是取模号,后面不能直接跟数字: )23 -> WRONG
计算器有以下的功能:
——基本的加减乘除:1+2, 3/4
——幂次: 3^2 (我懒得支持sqrt()和1x102的功能了)
——取模:|-2|
——虚数i:2i
——取共轭、幅角:cjg(), arg()
——三角函数sin cos tan
——多表达式分隔:2+3:
——变量与存值:A+3, 2+3>A
——答案自动存值:3+2:ans-4 (==1)
除此之外,计算器还有以下的robust功能:
——对于数字前的正负号,可以判断多个正负号结合的结果:++++--+---+ -> -
——对于括号前的数字和字母,可以判断是一种优先的乘法:8 / 2 (5) -> 8 / (2 (5))
——对于多个因子,视为它们的积:ii -> -1
分析方法
我们可以将一个数分为四个部分:
——正负号部分:[++--+-++-]
——数字部分:[215.2145]
——变量与虚数单位部分:[ansansABAiiianscjg(...)arg(...)],这里都是相乘的。对于一个“数”,第二或第三部分必须出现一次,否则就报错。
——运算符部分:+, *, ^, :...在处理时将:视为表达式终止符,人为添加方便判断;但是用户自己不能以:作为结尾。
这样处理有一个好处:通过这种归类,你只需要考虑四种字符(其实还有括号,原因是空字符串)后面应该跟随什么类型的字符——如果后缀字符无效,就可以返回一个错误。
处理方法
逐字符,调度场,这些就不赘述了。
关于报错,肯定要指出错误位置。这个准备采用一个变量来记数。
2. 重新构思
这几天想了一下,发现不能局限在casio的函数之内,应该要做到模块化。或者做成一个parser。
首先,把运算组件分为以下几部分:
——数字:string.digit+'.'
——左右的双目运算符:+-*/^
——单目运算符:>
——函数:func(expA, expB,...)
——变量:ABCD Ans
——括号:() || (有可能的话,可能会在内部处理的时候把取模号作为单目运算符使用)