清风莫追 2022-09-15 13:34 采纳率: 66.7%
浏览 60
已结题

有个带函数的表达式前加负号无效

描述

在递归对逆波兰求值时,有个表达式前加负号无效(加与不加都将输出不加时的结果)
我想知道为什么会出现这样的问题。

我在devc++5.11和codeblocks上运行都会存在这样的问题,而在我的visual studio 2019上并不会出现问题。

系统:win10

问题代码

t 后面的负号没有完成它的任务

else if(x == '-'){
    int t = -(nbl(s.top()) - nbl(s.top()));
    cout<<"t: "<<t<<endl;
    return t;
}

我还尝试了一些其它的写法,例如下面这样是有效的:

else if(x == '-'){
    int t = (nbl(s.top()) - nbl(s.top()));
    t = -t;
    cout<<"t: "<<t<<endl;
    return t;
}
else if(x == '-'){
    int a = -1;
    int t = a * (nbl(s.top()) - nbl(s.top()));
    cout<<"t: "<<t<<endl;
    return t;
}

而类似下面这些是仍然无效的:

else if(x == '-'){
    int t = (-1)*(nbl(s.top()) - nbl(s.top()));
    cout<<"t: "<<t<<endl;
    return t;
}
else if(x == '-'){
    int t = (nbl(s.top()) - nbl(s.top())) / (-1);
    cout<<"t: "<<t<<endl;
    return t;
}

而且我发现无效的仅仅是那个负号,例如下面的代码中乘 -2 得到的结果就只乘了 2

else if(x == '-'){
    int t = (-2) * (nbl(s.top()) - nbl(s.top()));
    cout<<"t: "<<t<<endl;
    return t;
}

完整代码

输入中 点号 表示一个操作数的结束,@表示整个表达式输入的结束

//逆波兰表达式——递归 
#include<iostream>
#include<cstdio>
#include<stack>
using namespace std;
stack<char> s;

int get_num(){//从栈中返回一个整型数字 
    char t=0;
    int sum=0;
    for(int i=1; ! s.empty(); i *= 10){
        t = s.top();
        if('0' <= t && t <= '9'){
            s.pop();
            sum += (t - '0') * i;
        }
        else break;
    }
    cout<<"sum "<<sum<<endl;
    return sum;
}

int nbl(char x){//对逆波兰表达式求值 
    if(x == '+' || x == '-' || x == '*' || x == '/'){
        s.pop();
        if(x == '+'){
            int t = nbl(s.top()) + nbl(s.top());
            cout<<"t: "<<t<<endl;
            return t;
        }
        else if(x == '-'){
            int t = -(nbl(s.top()) - nbl(s.top()));
            cout<<"t: "<<t<<endl;
            return t;
        }
        else if(x == '*'){
            int t = nbl(s.top()) * nbl(s.top());
            cout<<"t: "<<t<<endl;
            return t;
        }
        else if(x == '/'){
            int t = (int)(1 / ((double)nbl(s.top()) / nbl(s.top())));
            cout<<"t: "<<t<<endl;
            return t;
        }
    }
    else if(x == '.'){
        s.pop();
        return get_num();
    }
}

int main(){
    char t='0';
    while(true){
        cin >> t;
        if(t == '@') break;
        s.push(t);
    }
    
//    while(! s.empty()){
//        cout<<s.top();
//        s.pop();
//    }
//    cout<<endl;
    
    if(s.empty()){
        cout<<"表达式为空"<<endl;
    }
    else cout<<nbl(s.top());
    return 0;
}

/*
测试数据
3.5.2.-*7.+@
10.28.30./*7.-6.+@
1000.1000./5.-6.*@
*/


  • 写回答

2条回答 默认 最新

  • 於黾 2022-09-15 13:58
    关注

    你连续两次调用s.top(),最好先另存到一个变量,然后打印出来看里面到底是个什么玩意
    连原始数据都没搞清到底传值了个什么,就讨论成负号有用没用,我觉得你步子迈的太大了

    评论

报告相同问题?

问题事件

  • 已结题 (查看结题原因) 10月17日
  • 修改了问题 9月15日
  • 修改了问题 9月15日
  • 创建了问题 9月15日

悬赏问题

  • ¥15 Stata链式中介效应代码修改
  • ¥15 latex投稿显示click download
  • ¥15 请问读取环境变量文件失败是什么原因?
  • ¥15 在若依框架下实现人脸识别
  • ¥15 添加组件无法加载页面,某块加载卡住
  • ¥15 网络科学导论,网络控制
  • ¥15 利用Sentinel-2和Landsat8做一个水库的长时序NDVI的对比,为什么Snetinel-2计算的结果最小值特别小,而Lansat8就很平均
  • ¥15 metadata提取的PDF元数据,如何转换为一个Excel
  • ¥15 关于arduino编程toCharArray()函数的使用
  • ¥100 vc++混合CEF采用CLR方式编译报错