所以,我必须做一个后缀计算器或RPN计算器,问题是
任务是编写一个只在整数上工作的简化计算器。您的代码必须提供一个名为called的函数,它接受一个参数: std::string,并返回一个整数。计算器必须以下列方式工作:
代码:
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();
}
}
}我希望得到实际的答案,但我想程序并没有忽略这个空间,而且当我输入没有空格的字符串时,仍然会出现错误的输出。
发布于 2019-06-06 23:38:40
请注意,所提供的算法只有在得到后缀表达式时才能工作,而不是infix表达式。
第一个问题:
现在,看一看下面的一行:
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':
vals.push(c - '0');现在输入23+的结果是: 5。
第二个问题:
您使用的是两个堆栈,而不是一个实际需要的堆栈。当您将结果值推入第二个堆栈(mystack)中时,当您获得表达式的另一部分时,实际上无法访问它(更确切地说,让它更复杂地使用它的值),例如:
23+5*您可以调试这种情况(使用您正在使用的IDE的监视表/调试代码特性),并看到您正在尝试访问第一个结果中的5个,并且在第一个堆栈中一无所获,因为结果存储在第二个堆栈中。解决方案:使用单个堆栈。
case '+':
result = value1 + value2;
//mystack.push(result);
vals.push(result);
break;一般改进
函数:等位数
我建议您做的第一件事是删除if语句--您不需要它。下面的代码将完成此任务:
bool isdigit(char c) {
return c >= '0' && c <= '9';
}如果这个句子给你true,这个函数将返回true,否则它将返回false。
第二件事,就像注释说的那样,这个函数已经存在于标准的c++库中。只需使用:
#include <cctype>并删除此函数的实现。相同名称的函数已经存在:http://www.cplusplus.com/reference/locale/isdigit/
重要!
之所以给出这个答案,是因为我生命中有额外的时间,我所处的环境也很无聊,但更重要的是,我认为它可以帮助我理解如何调试代码,并解决未来(以及更复杂)的问题。这类问题是Debug questions型的。实际上,您不必在这里查找答案,而是调试代码并查看错误所在。请明智地使用你在这里得到的工具,祝你好运!
编辑:
对于更多c++风格的解决方案,在更高的困难级别上,您可以看到以下解决方案(将其视为欢迎来自c++的评论):
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;
}https://stackoverflow.com/questions/56485372
复制相似问题