【应用】浮点数四则运算器 Part1:输入模块的编写
下面首先记录浮点数四则运算器输入模块的编写。
思路和要求记录如下:
全局变量:
string dat--保存正在输入的串
string all[]--保存输入完成的串
map用于计数
flag用于记录应该执行哪一种输出模式
x用于记录已经输入的数据的个数
一、对输入数据的预处理。
用getchar输入,保存到string中。会出现以下一些情况:
1.输入了' ':一个串输入完成,保存,清空后输入新的串。
2.输入了\n':输入完成了一个表达式,本次输入结束。
3.过程中输入了'=':说明这是变量赋值语句,应该输出变量的值。
4.输入的串为"exit":说明计算完成,程序停止。
5.其他情况则保存字符。
其中,1. 2. 4. 5.都易于实现,而对于3. 可以采用将等号之前的部分保存为一个串,等号之后的部分保存为另一个串,后续使用map处理。
!6.这里可以进行的表达式错误类型判断:括号的匹配。
可这样进行:令code=0,当输入'('时code1++;当输入')'时code--; 用这样的逻辑,我们可以区分出以下情况:
1)任何输入时flag<0,说明有')'多余,flag=1,记为error code 1:extra ')'。
2)输入结束时flag>0,说明有‘('多余,flag=2,记为error code 2:extra '('。
输入模块(包括头文件)代码尝试编写:
1 void Getdata(){ 2 x=0; 3 flag=0; 4 dat=""; 5 for (int i=0;i<100;i++){ 6 all[i]=""; 7 } 8 int code=0; 9 char a=0; 10 cout<<"in>>"; 11 while (1){ 12 a=getchar(); 13 if (a=='('){ 14 code++; 15 } 16 if (a==')'){ 17 code--; 18 } 19 if (code<0){ 20 flag=1; 21 } 22 if (a==' '){ 23 all[x]=dat; 24 x++; 25 dat=""; 26 continue; 27 } 28 if (a=='\n'){ 29 all[x]=dat; 30 dat=""; 31 if (flag==3){ 32 for (int i=0;i<x;i++){ 33 cnt[all[i]]=all[x]; 34 } 35 } 36 if (all[x]=="exit"&&x==0){ 37 flag=4; 38 } 39 if (code>0){ 40 flag=2; 41 } 42 return ; 43 } 44 if (a=='='){ 45 flag=3; 46 all[x]=dat; 47 x++; 48 dat=""; 49 continue; 50 } 51 dat+=a; 52 } 53 }
测试这一段输入模块的测试用主程序:
1 int main(){ 2 while (1){ 3 Getdata(); 4 if (flag==1){ 5 printf("out>>error code 1:extra ')'\n"); 6 continue; 7 } 8 if (flag==2){ 9 printf("out>>error code 2:extra '('\n"); 10 continue; 11 } 12 if (flag==3){ 13 printf("out>>%s\n",cnt[all[x-1]].c_str()); 14 continue; 15 } 16 if (flag==4){ 17 break; 18 } 19 if (flag==0){ 20 printf("out>>"); 21 for (int i=0;i<x;i++){ 22 printf("%s ",all[i].c_str()); 23 } 24 printf("%s\n",all[x].c_str()); 25 continue; 26 } 27 } 28 return 0; 29 }
运行结果与预期相同。
这里意识到可以增加运算器的功能——给多个变量名赋同一个值。
于是将输入模块代码中的第45行到47行修改为:
1 if (flag==3){ 2 for (int i=0;i<x;i++){ 3 cnt[all[i]]=all[x]; 4 } 5 }
这样就同时给多个同样数值的变量赋了同一个值。
(我喜欢写每一行内容很少行数很多的代码……捂脸……因为看起来整齐)
二、对输入数据的运算过程。(初步规划)
首先记录一下已经输入好的数据的保存位置。
·cnt[all[i]]保存了在exit之前的所有的变量值,以最后一次输入为准。 map类
·all[300]中保存了每一次输入后所有的数据。 string类
·x记录了all中数据的个数,一直到all[x]都有数据填充。 int类
现在all[300]中保存了可能含有字母元的中缀表达式,可以将其转化为后缀表达式后运算输出结果。
到这里已经基本结束了,转化方法和运算方法在 【数据结构】栈与队列Part2:栈的应用之表达式转换 已经有所操作。
但是还有一个遗留的问题:错误类型的判断。
期望能做到的有:
1.能够识别除数是否为0。
2.能够识别是否出现了不合法运算式,比如5 6 * 3,这里5和6中间缺少运算符。
PLUS:能够识别缺少运算符的位置。
3.能够识别没有赋初值的字母元。
由于数据的保存方式,2和3都很容易实现,但1的识别依然是一个难点。
想到的解决方式是运算过程遇到'/'时检测被除数。
这样基本就可以编辑出完整的浮点数四则运算器。
Part2将会是运算输出模块的编写和运行。