【应用】浮点数四则运算器 Part2:转化模块的编写

【应用】浮点数四则运算器 Part2:转化模块的编写


根据在 【应用】浮点数四则运算器 Part1:输入模块的编写 中的规划,有如下思路:

需要计算的部分实际上是flag=0的部分,其余部分都有其他对应的操作。

当flag=0时,

1.扫描all全部数据,找到其中字母元x,检查是否有对应值。

若没有:返回error code 3: undefined ‘x’,x是字母元的名称。继续输入下一组数据

若全部有对应值,将其转化为其对应值。

这样就得到了完全又数字和操作符组成的表达式,同时完成了期望3.能够识别没有赋初值的字母元。

这里用到的是map的函数find()。
number.find();
空返回number.end(),不空返回这个值。

2.识别错误类型:是否缺少或多余运算符。

缺少或多余运算符的特征有以下几种:

1)数字的下一个是数字或括号’(’。数字的上一个是括号’)’。

2)操作符的下一个是操作符或空串。操作符的上一个是空串。

可以将数字编为1,括号’(‘编为2,括号’)'编为3,操作符编为4。

若当前位置编码为1,当上一个为3时输出error code 4: operation after ‘)’ needed

若当前位置编码为1,当下一个为2时输出error code 5: operation before ‘(’ needed

若当前位置编码为1,当下一个为1时输出error code 6: operation after ‘x’ needed,x为当前位置的数据

若当前位置编码为4,当下一个为4时输出error code 7: double operation ‘x’ ‘y’,x为当前操作符,y为下一个

若当前位置编码为4,当下一个不存在时输出error code 8: extra end operation ‘x’,x为当前操作符

若当前位置编码为4,当上一个不存在时输出error code 9: extra start operation ‘x’,x为当前操作符

继续输入下一组数据

3.若没有错误,则证明是正确的格式。那么就开始运算。

1)首先是表达式的转化,将中缀表达式转化为后缀表达式。

2)利用后缀表达式的计算函数计算结果。但需注意:

当调用’/'是需检测除数是否为0。

若为0,则输出error code 10:‘0’ under ‘/’

为了实现这一功能,使用递归的后缀表达式计算函数难以操作,需要考虑新的操作方法。

已知完整的后缀表达式存放在一个栈中,可以创建一个新栈,数据时存入,操作符时操作后压入栈顶,为’/'时检测栈顶是否为0。

最后输出栈顶元素。正常情况下输出后栈应该只有一个元素。若栈中有多个元素:

extra code 11:BUG SHOWED!DAMN!!!

由于错误判断有很多,决定定义一个全局变量Error用来保存是否出现了问题。

在这里发现了新的问题。之前的文章中转化为后缀表达式方式无法兼容识别负数,于是增加了一些内容用于识别负数。

以上是计算思路。

下面是计算函数的代码实现:

1.首先是用数据串替换字母串。

int Error=0;

void givenum(){
    Error=0;
    for (int i=0;i<=x;i++){
        if ((all[i][0]>='0'&&all[i][0]<='9')||
            all[i]=="("||
            all[i]==")"||
            all[i][0]=='+'||
            all[i][0]=='-'||
            all[i]=="*"||
            all[i]=="/"){
            continue;
        }
        if (cnt.find(all[i])!=cnt.end()){
            all[i]=cnt[all[i]];
        }
        else{
            printf("out>>error code 3: undefined '%s'\n",all[i].c_str());
            Error=1;
            break;
        }
    }
}

2.检查表达式合法性。

void check(){
    Error=0;
    int code[x+10];
    for (int i=0;i<=x;i++){
        if (all[i]=="+"||
            all[i]=="-"||
            all[i]=="*"||
            all[i]=="/"){
            code[i]=4;
            continue;
        }
        if (all[i][0]=='('){
            code[i]=2;
            continue;
        }
        if (all[i][0]==')'){
            code[i]=3;
            continue;
        }
        code[i]=1;
    }
    if (code[0]==4){
        printf("out>>error code 9: extra start operation '%s'\n",all[0].c_str());
        Error=1;
    }
    for (int i=0;i<=x;i++){
        if (i>0&&
            code[i]==1&&
            code[i-1]==3){
            printf("out>>error code 4: operation after ')' needed\n");
            Error=1;
        }
        if (i<x&&
            code[i]==1&&
            code[i+1]==2){
            printf("out>>error code 5: operation before '(' needed\n");
            Error=1;
        }
        if (i<x&&
            code[i]==1&&
            code[i+1]==1){
            printf("out>>error code 6: operation after '%s' needed\n",all[i].c_str());
            Error=1;
        }
        if (i<x&&
            code[i]==4&&
            code[i+1]==4){
            printf("out>>error code 7: double operation '%s' '%s'\n",all[i].c_str(),all[i+1].c_str());
            Error=1;
        }
    }
    if (code[x]==4){
        printf("out>>error code 8: extra end operation '%s'\n",all[x].c_str());
        Error=1;
    }
}

3.转化表达式。

stack<string> fx1;
stack<string> fx2;

int level(string buffer){
    switch (buffer[0]){
        case '+': return 1;
        case '-': return 1;
        case '*': return 2;
        case '/': return 2;
        default:  return 0;
    }
}

void change(){
    while (fx1.empty()!=1){
        fx1.pop();
    }
    while (fx2.empty()!=1){
        fx2.pop();
    }
    int m=0;
    while (m<=x){
        if (all[m]=="+"||
            all[m]=="-"||
            all[m]=="*"||
            all[m]=="/"){
            if (fx1.empty()==1||
                fx1.top()=="("){
                fx1.push(all[m]);
                m++;
                continue;
            }
            else{
                if (level(fx1.top())<=level(all[m])){
                    fx1.push(all[m]);
                    m++;
                    continue;
                }
                else{
                    while (fx1.empty()!=1&&
                           fx1.top()!="("&&
                           level(fx1.top())>level(all[m])){
                        fx2.push(fx1.top());
                        fx1.pop();
                    }
                    fx1.push(all[m]);
                    m++;
                    continue;
                }
            }
        }
        if (all[m][0]=='('||
            all[m][0]==')'){
            if (all[m][0]=='('){
                fx1.push(all[m]);
                m++;
                continue;
            }
            if (all[m][0]==')'){
                while (fx1.empty()!=1&&
                       fx1.top()!="("){
                    fx2.push(fx1.top());
                    fx1.pop();
                }
                fx1.pop();
                m++;
                continue;
            }
        }
        fx2.push(all[m]);
        m++;
    }
    while (fx1.empty()!=1){
        fx2.push(fx1.top());
        fx1.pop();
    }
    while (fx2.empty()!=1){
         fx1.push(fx2.top());
         fx2.pop();
    }
}

测试:

int main(){
    while (1){
        Getdata();
        if (flag==1){
            printf("out>>error code 1:extra ')'\n");
            continue;
        }
        if (flag==2){
            printf("out>>error code 2:extra '('\n");
            continue;
        }
        if (flag==3){
            printf("out>>%s\n",cnt[all[x-1]].c_str());
            continue;
        }
        if (flag==4){
            break;
        }
        if (flag==0){
            printf("out>>");
            for (int i=0;i<x;i++){
                printf("%s ",all[i].c_str());
            }
            printf("%s\n",all[x].c_str());
            givenum();
            if (Error==1){
                continue;
            }
            check();
            if (Error==1){
                continue;
            }
            change();
            while (fx1.empty()!=1){
                printf("%s",fx1.top().c_str());
                printf(" ");
                fx1.pop();
            }
            printf("\n");
            continue;
        }
    }
    return 0;
}

运行结果与预期相同。

到这里已经达成的目的是将表达式转化为完整无误的后缀表达式。

输出时要注意是否有除数为0的情况出现。

在Part 3中记录计算输出结果的模块。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值