Stack Postfix Notation evaluation equals 与中缀计算得到的不同
Stack Postfix Notation evaluation equals different to what infix calc gets
我在使用 Flex 开发一种简单的 1 文件语言时遇到了一个问题。
中缀计算器表达式为:1 + 2 * 5 -32
,在计算器上等于-21
。
我的后缀计算器表达式是:1 2 5 32 - * +
,用我的计算器等于 55
。
这是我的 Flex 代码:
%{
#include <cstdio>
#include <cstdlib>
#include <string>
#include <iostream>
#include <stack>
using namespace std;
stack<int> numberStack;
int a;
int b;
extern "C" int yywrap() { }
%}
%%
[ \t\n] ;
[0-9]+ numberStack.push(atoi(yytext));
"+" a = numberStack.top(); numberStack.pop(); b = numberStack.top(); numberStack.pop(); numberStack.push(a+b);
"-" a = numberStack.top(); numberStack.pop(); b = numberStack.top(); numberStack.pop(); numberStack.push(a-b);
"*" a = numberStack.top(); numberStack.pop(); b = numberStack.top(); numberStack.pop(); numberStack.push(a*b);
"/" a = numberStack.top(); numberStack.pop(); b = numberStack.top(); numberStack.pop(); numberStack.push(a/b);
%%
int main(int argc, char *argv[])
{
yyin = fopen(argv[1], "r");
yylex();
fclose(yyin);
cout << numberStack.top() << endl;
numberStack.pop();
return 0;
}
请原谅我的做事方式(尤其是复制粘贴的 C 代码,因为我对 Flex 有点生疏),我刚刚看到一个关于波兰反向表示法及其对堆栈的引用的视频,所以我想做一个使用它的脚本语言,我花了大约 5 分钟的时间来制作。
我已经知道我不能做除法(但我把它留在里面了)因为它很可能 return 浮点数将显示为 0 因为堆栈的类型是 int
.
谁能解释为什么我的波兰语逆向表示法计算器脚本语言将 1 2 5 32 - * +
计算为 55
,而不是正确答案 -21
?
您的代码结果(几乎)没有任何问题。
1 + 2 * 5 - 32
(根据通常的运算符优先级规则)到 RPN 的正确翻译是:1 2 5 * + 32 -
。 RPN 1 2 5 32 - * +
是 1 + 2 * (5 - 32)
的翻译
您的代码的一个问题是您计算的是正确函数的逆函数。也就是说,5 32 -
返回 27 而不是 -27(并且 32 5 -
正在计算 -27 而不是 27)。 /
也会出现类似的问题。 (因为 +
和 *
是可交换的,所以问题没有被注意到)。
所以在所有的动作中,a
和b
应该互换。
也不需要使用全局变量a
和b
:
"-" { int right = numberStack.top();
numberStack.pop();
int left = numberStack.top();
numberStack.pop();
numberStack.push(left - right);
}
显然,在调用.top()
.
之前检查堆栈是否为空会更好
我在使用 Flex 开发一种简单的 1 文件语言时遇到了一个问题。
中缀计算器表达式为:1 + 2 * 5 -32
,在计算器上等于-21
。
我的后缀计算器表达式是:1 2 5 32 - * +
,用我的计算器等于 55
。
这是我的 Flex 代码:
%{
#include <cstdio>
#include <cstdlib>
#include <string>
#include <iostream>
#include <stack>
using namespace std;
stack<int> numberStack;
int a;
int b;
extern "C" int yywrap() { }
%}
%%
[ \t\n] ;
[0-9]+ numberStack.push(atoi(yytext));
"+" a = numberStack.top(); numberStack.pop(); b = numberStack.top(); numberStack.pop(); numberStack.push(a+b);
"-" a = numberStack.top(); numberStack.pop(); b = numberStack.top(); numberStack.pop(); numberStack.push(a-b);
"*" a = numberStack.top(); numberStack.pop(); b = numberStack.top(); numberStack.pop(); numberStack.push(a*b);
"/" a = numberStack.top(); numberStack.pop(); b = numberStack.top(); numberStack.pop(); numberStack.push(a/b);
%%
int main(int argc, char *argv[])
{
yyin = fopen(argv[1], "r");
yylex();
fclose(yyin);
cout << numberStack.top() << endl;
numberStack.pop();
return 0;
}
请原谅我的做事方式(尤其是复制粘贴的 C 代码,因为我对 Flex 有点生疏),我刚刚看到一个关于波兰反向表示法及其对堆栈的引用的视频,所以我想做一个使用它的脚本语言,我花了大约 5 分钟的时间来制作。
我已经知道我不能做除法(但我把它留在里面了)因为它很可能 return 浮点数将显示为 0 因为堆栈的类型是 int
.
谁能解释为什么我的波兰语逆向表示法计算器脚本语言将 1 2 5 32 - * +
计算为 55
,而不是正确答案 -21
?
您的代码结果(几乎)没有任何问题。
1 + 2 * 5 - 32
(根据通常的运算符优先级规则)到 RPN 的正确翻译是:1 2 5 * + 32 -
。 RPN 1 2 5 32 - * +
是 1 + 2 * (5 - 32)
您的代码的一个问题是您计算的是正确函数的逆函数。也就是说,5 32 -
返回 27 而不是 -27(并且 32 5 -
正在计算 -27 而不是 27)。 /
也会出现类似的问题。 (因为 +
和 *
是可交换的,所以问题没有被注意到)。
所以在所有的动作中,a
和b
应该互换。
也不需要使用全局变量a
和b
:
"-" { int right = numberStack.top();
numberStack.pop();
int left = numberStack.top();
numberStack.pop();
numberStack.push(left - right);
}
显然,在调用.top()
.