“字符串表达式求值的编程实现”
问题描述及求解过程
要求:给定一个含有字符 ‘0’-‘9’、小数点‘.’、加‘+’、乘‘*’、除‘/’、左括号‘(’、右括号‘)’以及空格的字符串,编写程序对其解析,并给出对应的数学表达式的值。
比如,对于字符串“(-3.5)+1.5/1.2*1.5”,计算结果应该为-1.625。
编程实现字符串表达式求值问题主要步骤如下:
1.解析输入字符串,将其转化为“中缀表达式”;
2.将“中缀表达式”转化为“后缀表达式”;
3.对转化得到的后缀表达式进行求值。
下面,将逐个分析各环节。
从输入到中缀表达式
“将输入的表达式字符串转化为中缀表达式”,这一步的主要工作有两个:
1.判断输入字符串的正确性及合法性;
2.将字符串分割成“原子”单位,即操作数(浮点数)和操作符,并依次压入某个栈中。
比如,字符串“(-3.5)+1.5/1.2*1.5”应该分割为:
( -3.5 ) + 1.5 / 1.2 * 1.5
其中,红色框与蓝色框分别指示其内容是“操作符”还是“操作数”。
一个表达式字符串是“合法”的,必须满足如下的条件:
1.‘+’、‘*’、‘/’以及‘-’作为减法操作符时,前后必须都是操作数。
2.操作数字符只能是‘0’-‘9’或者‘.’,规定负数必须有括号,例如(-3+5)*2、2*(-5)、(-5)*3合法,但是-3+5是不合法的。
3.每个操作数中‘.’最多只能出现一次。
4.操作数中不能出现空格,小数点后面不能出现空格,首字符不能含空格。
5.操作数与操作符之间、括号和操作数或操作符之间可以有空格。
6.操作数后面不能直接跟左括号‘(’。
7.左括号后不能直接跟‘+’、‘*’、‘/’、‘)’、‘.’,但能够跟(不超过一个)‘-’。
8.右括号后不能直接跟‘(’、‘.’、‘0’-‘9’。
9.整个表达式的左右括号数必须相等。
10.在表达式的任何位置,出现在其左边的左括号数不能小于出现在其左边的右括号数。
通过划分输入状态,得出下表:
当前状态state |
输入字符char |
下一状态nextstate |
动作 |
op |
"0,1,2...9" |
non_dot |
value+=char,polar=1 |
"+,-,*,/" |
wrong |
停机报错 |
|
"(" |
l_par |
par_num++;Stack.push(char) |
|
空格 |
non_dot |
|
|
其它 |
wrong |
停机报错 |
|
non_dot |
"." |