所以,我必须要制作一个后缀计算器或RPN计算器,问题就像
任务是编写仅对整数有效的简化计算器。您的代码必须提供一个称为评估的函数,该函数带有一个参数: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();
}
}
}
我期望实际的答案,但是我想程序并没有忽略 空间,当我输入不带空格的字符串时,仍然有一个 错误的输出
答案 0 :(得分:-1)
请注意,所提供的算法仅在获得后缀表达式而不是中缀表达式时才有效。
第一个问题:
现在,请看以下一行:
vals.push(c);
c
是一个字符,而vals
是一个整数stack
。当c在您的代码中显示1时,c ++编译器实际上看到'0' + 1
。例如:
对于输入23+
,您将获得结果:101。为什么?
'2' != 2
和'3' != 3
。实际上计算是:
'0' + 2 + '0' + 3
,意思是48 + 2 + 48 + 3
,因为'0' == 48
在ASCII代码中。
要解决这个小问题,您要做的就是将插入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;
}