前缀计算器——在某些情况下不起作用——C++

Posted

技术标签:

【中文标题】前缀计算器——在某些情况下不起作用——C++【英文标题】:Prefix Calculator -- won't work for some cases -- C++ 【发布时间】:2014-05-01 19:04:54 【问题描述】:

我正在创建一个前缀计算器,用户可以在其中输入前缀表达式,然后程序对其进行评估。它适用于某些情况,例如“+43”应该输出7,但是“/-421”输出“2”,当它应该输出“1”时,“/+421”输出“6”而不是“3”,诸如此类。有什么建议可以解决这个问题吗?稍后我将添加异常,因此暂时将它们注释掉。

前缀计算器.cpp

#pragma once

#include <sstream>

using namespace std;

template<class T>
class PrefixCalculator 
public:
PrefixCalculator(void)
    numOperator = 0;
    numOperand = 0;
;
~PrefixCalculator(void);

T eval(istringstream&);

int getNumOperator() 
    return numOperator;
;

int getNumOperand() 
    return numOperand;
;

private:
//if you feel you need private helper functions and/or helper data
int numOperator;
int numOperand;
;

template<class T>
T PrefixCalculator<T>::eval(istringstream& input)  
 //this function needs to throw an exception if there's a problem with the expression or operators
char nextChar = input.peek();

//this while loop skips over the spaces in the expression, if there are any
while(nextChar == ' ') 
    input.get();    //move past this space
    nextChar = input.peek(); //check the next character


if(nextChar == '+') 
    input.get();    //moves past the +
    numOperator++;
    return eval(input) + eval(input);   //recursively calculates the first expression, and adds it to the second expression, returning the result


/***** more operators here ******/
if(nextChar == '-') 
    input.get();
    numOperator++;
    return eval(input) - eval(input);


if(nextChar == '*') 
    input.get();
    numOperator++;
    return eval(input) * eval(input);


if(nextChar == '/') 
    input.get();
    numOperator++;
    return eval(input) / eval(input);
 

/******  BASE CASE HERE *******/
//it's not an operator, and it's not a space, so you must be reading an actual value (like '3' in "+ 3 6".  Use the >> operator of istringstream to pull in a T value!
input>>nextChar;
T digit = nextChar - '0';
numOperand++;
return digit;
//OR...there's bad input, in which case the reading would fail and you should throw an exception


驱动程序.cpp

#include <sstream>
#include <string>
#include <iostream>
#include "PrefixCalculator.h"

using namespace std;

int main(int argc, char** argv) 
PrefixCalculator<int> calc;

string expression;
cout << "Give a prefix expression to evaluate, or q to quit." << endl;
getline(cin,expression);

while(expression[0] != 'q') 
    //try 
        int result = calc.eval(istringstream(expression));
        cout << result << endl;
    //
    //catch  //will not compile, you have to finish this!
    //  
    //

    cout << "Give a prefix expression to evaluate or q to quit." << endl;
    getline(cin,expression);


return 0;
 

【问题讨论】:

那么,您在调试器中单步执行代码以查看其行为吗? Looks right to me。您首先执行最接近操作数的运算符。 @crashmstr:好的,当我切换运算符时,它可以工作。是否暗示用户将输入它们作为例如“-/”或“+/”而不是“/-”或“/+”,即这只是前缀评估的规则? 根据我对前缀符号的理解,它似乎按照它应该的方式工作。对我来说,/-421 等同于 scheme 或 lisp 中的 (/ (- 4 2) 1)。您在评估时从右到左工作,因此操作员在找到时会被“执行”,并且他们在右侧的操作数上工作。 @jordpw:前缀和后缀都不需要操作数的不同优先级,操作顺序由操作数/操作符的顺序定义 【参考方案1】:

我很困惑。从您提供的输出来看,您的程序运行正常,但您的期望不正确。

让我们计算表达式“/-421”: 1. 检测到运算符,'/',入栈:

+----+
| /  |
+====+

检测到运算符,'-',压入堆栈:

+---+  
| - |  
+---+  
| / |  
+===+  

检测到数字,由于前一个运算符需要 2 个参数,因此将其压入堆栈。

+---+
| 4 |
+---+
| - |
+---+
| / |
+===+

检测到的数字,两个运算符中的第二个。 将剩余的操作数从堆栈中弹出,4. 将操作从堆栈中弹出并使用参数进行评估:

result = 4 - 2 --> 1

将结果压入堆栈。

+---+
| 2 |
+---+
| / |
+===+

检测到的数字,除法运算符的第二个参数 2。 从堆栈中弹出数字,这将成为除法运算的第一个参数。 将操作从堆栈中弹出并使用参数进行评估:

result = 2 / 1 --> 2

将结果压入堆栈。

+---+
| 2 |
+===+

表达式结束,弹出结果并打印:

2

编辑 1:

在分析下一个标记之前,您可以通过打印堆栈(每行一项)来确认程序的操作。

【讨论】:

您说得对,我一开始对前缀评估的规则感到困惑,然后其他人的评论澄清了事情。谢谢! @jordpw 如果这个答案对你有帮助,请点击复选标记。

以上是关于前缀计算器——在某些情况下不起作用——C++的主要内容,如果未能解决你的问题,请参考以下文章

UIImageView autoresizingmask 在某些情况下不起作用

多个 OpenGL 纹理在某些情况下不起作用?

URP Shader Graph 着色器时间节点在某些情况下不起作用

QTabWidget 选项卡切换快捷方式在某些 Linux DE 下不起作用

为啥这个 if 语句在这种情况下不起作用? [关闭]

为啥 selectAnnotation 在这种情况下不起作用?