我已经编写了可以对输入字符串执行以下转换的代码
3(7x-1)+10x-4+3x=90x+1
(3*(7x-1)+10x-4+3x)-(90x+1)
37x1-*10x+4-3x+90x1+-
但现在,我有点坚持最后一个。我知道如何在不涉及 X 的情况下编写代码来解决 RPN。但是,我不确定如何使用所涉及的 x 来解析它。
EIDT:我已经修复了不正确的 RPN 错误,现在显示为
3 7 x * 1 - * 10 x * + 4 - 3 x * + 90 x * 1 + -
解析这个 RPN 字符串是我担心的。
RPN 的全部意义在于它不需要任何解析。您可以直接使用标记器的输出。
sub get_next_token {
/\G \s+ /xgc;
/\G \z /xgc && return [ 'EOF' ];
/\G ( [0-9]+ ) /xgc && return [ NUM => $1 ];
/\G ( [a-z] ) /xgc && return [ VAR => $1 ];
/\G ( [*+\-] ) /xgc && return [ $1 ];
die("Syntax error\n");
}
my %ops = (
EOF => sub { my $token = shift; ...; return 0; },
NUM => sub { my $token = shift; ...; return 1; },
VAR => sub { my $token = shift; ...; return 1; },
'*' => sub { my $token = shift; ...; return 1; },
'+' => sub { my $token = shift; ...; return 1; },
'-' => sub { my $token = shift; ...; return 1; },
);
for ($rpn) {
while (1) {
my $token = get_next_token();
my $op = $opts{$token}
or die("Internal error");
last if !$op->($token);
}
}
请注意,您没有有效的 RPN。
(3(7x-1)+10x-4+3x)-(90x+1)
应该导致
3 7 x * 1 - * 10 x * + 4 - 3 x * + 90 x * 1 + -
但是你有
37 x 1 - * 10 x + 4 - 3 x + 90 x 1 + -
你错过了一些乘法,你合并3
到.7
37
我不确定如何用所涉及的 x 来解析这个。
好像您已经编写了一个解析器来处理以下形式的语法:
stmt : expr '=' expr
expr : sum
sum : prod '+' sum
| prod '-' sum
| prod
prod : term prod
| term
term : '(' expr ')'
| NUM
您需要更改的只是term
.
term : '(' expr ')'
| NUM
| VAR
数学::RPN :
use Math::RPN; $value=rpn(expr...); @array=rpn(expr...);
expr... 是一个或多个标量或包含 RPN 表达式的标量列表。RPN 表达式是一系列以逗号分隔的数字和/或运算符。(逗号仅在标量中需要)。