首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >RPN计算器/后固定计算器

RPN计算器/后固定计算器
EN

Stack Overflow用户
提问于 2019-06-06 21:33:43
回答 1查看 269关注 0票数 0

所以,我必须做一个后缀计算器或RPN计算器,问题是

任务是编写一个只在整数上工作的简化计算器。您的代码必须提供一个名为called的函数,它接受一个参数: std::string,并返回一个整数。计算器必须以下列方式工作:

  1. 它逐字读取字符串,
  2. 如果它读取一个数字,它把它放在自己的内部堆栈中,
  3. 如果它读取一个空格,它必须忽略它,
  4. 如果它读取字符+、-、*或/它对堆栈的两个最顶层元素执行操作,删除它们并将结果放到堆栈上,
  5. 当它到达std::string参数的末尾时,它返回堆栈的顶部。

代码:

代码语言:javascript
复制
using namespace std;

int evaluate(string);
bool isdigit(char c);
bool isOp(char c);

bool isdigit(char c)
{
    if (c >= '0' && c <= '9')
    {
        return true;
    }
    return false;
}

int main()
{

    string str;
    cout << "\n Enter the input : ";
    cin >> str;

    evaluate(str);
}

int evaluate(string str)
{
    stack<int> mystack;
    stack<int> vals;

    for (int i = 0; i < str.size(); i++)
    {
        char c = str[i];
        if (isdigit(c))
        {
            vals.push(c);
        }
        else if (c == ' ')
        {
            c = ' ';
            cout << str;
        }
        else
        {
            int value1, value2, result;

            value2 = vals.top();
            vals.pop();

            value1 = vals.top();
            vals.pop();

            switch (str[i])
            {
                case '+':
                    result = value1 + value2;
                    mystack.push(result);
                    break;

                case '-':
                    result = value1 - value2;
                    mystack.push(result);
                    break;

                case '*':
                    result = value1 * value2;
                    mystack.push(result);
                    break;

                case '/':
                    result = value1 / value2;
                    mystack.push(result);

                    break;
            }

            cout << "result is " << mystack.top();

        }
    }
}

我希望得到实际的答案,但我想程序并没有忽略这个空间,而且当我输入没有空格的字符串时,仍然会出现错误的输出。

EN

回答 1

Stack Overflow用户

发布于 2019-06-06 23:38:40

请注意,所提供的算法只有在得到后缀表达式时才能工作,而不是infix表达式。

第一个问题:

现在,看一看下面的一行:

代码语言:javascript
复制
vals.push(c);

c是char,vals是整数stack。当c在代码中显示1时,c++编译器实际上看到了'0' + 1。例如:

对于输入的23+,您将得到结果: 101。为什么?'2' != 2'3' != 3。实际上计算是:'0' + 2 + '0' + 3,意思是48 + 2 + 48 + 3,因为在ascii代码中'0' == 48

要解决这个小问题,您所要做的就是将插入到vals堆栈中的值减少'0':

代码语言:javascript
复制
vals.push(c - '0');

现在输入23+的结果是: 5。

第二个问题:

您使用的是两个堆栈,而不是一个实际需要的堆栈。当您将结果值推入第二个堆栈(mystack)中时,当您获得表达式的另一部分时,实际上无法访问它(更确切地说,让它更复杂地使用它的值),例如:

代码语言:javascript
复制
23+5*

您可以调试这种情况(使用您正在使用的IDE的监视表/调试代码特性),并看到您正在尝试访问第一个结果中的5个,并且在第一个堆栈中一无所获,因为结果存储在第二个堆栈中。解决方案:使用单个堆栈。

代码语言:javascript
复制
case '+':
    result = value1 + value2;
    //mystack.push(result);
    vals.push(result);
    break;

一般改进

函数:等位数

我建议您做的第一件事是删除if语句--您不需要它。下面的代码将完成此任务:

代码语言:javascript
复制
bool isdigit(char c) {
    return c >= '0' && c <= '9';
}

如果这个句子给你true,这个函数将返回true,否则它将返回false

第二件事,就像注释说的那样,这个函数已经存在于标准的c++库中。只需使用:

代码语言:javascript
复制
#include <cctype>

并删除此函数的实现。相同名称的函数已经存在:http://www.cplusplus.com/reference/locale/isdigit/

重要!

之所以给出这个答案,是因为我生命中有额外的时间,我所处的环境也很无聊,但更重要的是,我认为它可以帮助我理解如何调试代码,并解决未来(以及更复杂)的问题。这类问题是Debug questions型的。实际上,您不必在这里查找答案,而是调试代码并查看错误所在。请明智地使用你在这里得到的工具,祝你好运!

编辑:

对于更多c++风格的解决方案,在更高的困难级别上,您可以看到以下解决方案(将其视为欢迎来自c++的评论):

代码语言:javascript
复制
int evaluate(string str) {
    // [] () -> {} ====> READ ABOUT: Lambda expressions
    
    stack<int> vals;

    /*
     * pop
     * ---
     * Returns the top value of a stack, and the pop it from the stack.
     */
    auto pop = [] (stack<int> &s) -> int {
        int res = s.top();
        s.pop();
        return res;
    };

    /*
     * op
     * --
     * Returns a function that execute the selected operator on two integers params.
     */
    auto op = [] (char op) -> std::function<int(int, int)> {
        switch (op) {
            case '+':
            default : return [] (int a, int b) -> int { return a + b; };
            case '-': return [] (int a, int b) -> int { return a - b; };
            case '*': return [] (int a, int b) -> int { return a * b; };
            case '/': return [] (int a, int b) -> int { return a / b; };
        }
    };

    /*
     * for_each is a loop implementation in c++ as part of the standard library (std).
     * It's get the first iterator place (str.begin()), end iterator place (str.end()), and function to execute on
     * each value in the collection (between start and end iterators).
     */
    std::for_each(str.begin(), str.end(), [&vals, pop, op] (char c) {
        if (isdigit(c)) vals.push(c - '0');
        else if (c != ' ') vals.push(op(c)(pop(vals), pop(vals)));
        // op(c) -> returns a function according to the operator
        // op(c)(n1, n2) -> use the returned operator on n1 and n2
        // pop(vals) -> function that returns the top value of the stack, and then pop it from the stack.
        // op(c)(pop(vals), pop(vals)) -> apply the selected op on the first two values in the stack
    });
    cout << "The result is: " << vals.top() << endl;
}
票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56485372

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档