从前缀表示法转换为前缀表示法


12

给定一个算术表达式,可以包括括号(()),指数(^),除法(/)和乘法(*),加法(+)和减法(-)(按该操作顺序),例如

a ^ (2 / 3) * 9 * 3 - 4 * 6

以前缀表示法输出相同的表达式。

(- (* (* (^ a (/ 2 3)) 9) 3) (* 4 6))

输入和输出中的空格都是可选的。您可以假定所有运算符都是左关联的,并且表达式中的所有数字都是一位整数(即[0-9])。

这是一场代码挑战赛,因此最短的解决方案将获胜。


1
+和-是相同的优先级,还是+高于-?即,是3+4-5+6 = (((3+4)-5)+6)还是((3+4)-(5+6))
基思·兰德尔

另外,您在操作列表中省略了除法。
PhiNotPi 2012年

括号在输出中是可选的吗?
Ali1S232

@KeithRandall *和amd /具有相同的优先级。+-
彼得·奥尔森

@Gajet不,不是。
彼得·奥尔森

Answers:


13

红宝石1.9-134

%w[** / * + -].map{|o|String.send(:define_method,o){|n|"(#{o=='**'??^:o} #{self} #{n})"}}
puts eval gets.gsub(/\w/,'?\0').gsub ?^,'**'

很邪恶,但它可以工作:

$ echo 'a ^ (2 / 3) * 9 * 3 - 4 * 6' | ruby sol.rb
(- (* (* (^ a (/ 2 3)) 9) 3) (* 4 6))

3

Python,222个字符

class A:
 def __init__(s,x):s.v=x
for x in('pow^','mul*','div/','add+','sub-'):exec('A.__'+x[:3]+'__=lambda s,y:A("('+x[3]+'"+s.v+y.v+")")')
import re
print eval(re.sub('(\\w)','A("\\1")',raw_input().replace('^','**'))).v

与Ruby类似,不同之处在于Python不允许您重新定义全局操作,而只能重新定义类的操作。


2

Perl 6(146 | 150)

最简单的方法是将实现操作符的子例程换成新的子例程。

sub infix:«+»   ($a,$b) { "(+ $a $b)" }
sub infix:«-»   ($a,$b) { "(- $a $b)" }
sub infix:«*»   ($a,$b) { "(* $a $b)" }
sub infix:['/'] ($a,$b) { "(/ $a $b)" } # stupid highlighter
sub infix:«**»  ($a,$b) { "(^ $a $b)" }

# currently there seems to be a bug that
# prevents this from modifying the parser correctly
# probably because there is already a different operator with this name
# which has nothing to do with exponentiation
my &infix:«^» := &[**];

say 'a' ** (2 / 3) * 9 * 3 - 4 * 6;
# (- (* (* (^ a (/ 2 3)) 9) 3) (* 4 6))␤

这样做的绝对最小字节数是:

sub infix:<+>{"(+ $^a $^b)"}␤  #   29
sub infix:<->{"(- $^a $^b)"}␤  # + 29
sub infix:<*>{"(* $^a $^b)"}␤  # + 29
sub infix:<**>{"(^ $^a $^b)"}␤ # + 30
sub infix:</>{"(/ $^a $^b)"}␤  # + 29

146个字节,尽管在Perl 6中对字素进行计数更有意义。

假定“ 以前缀表示法输出相同的表达式 ”仅可以引用表达式的结果,而不必引用程序的输出。

您必须say 在表达式前面添加以使程序将其打印到STDOUT。(150字节)


0

Unix TMG,189字节

p:ignore(<< >>)parse(e);e:q(t,a);t:q(x,m);x:q(r,h);q:proc(x,y)x k:y/d x={<(>2 3 1<)>}b\k;r:o(!<<+-*/^()>>)|<(>e<)>;a:o(<<+->>);m:o(<<*/>>);h:o(<<^>>);o:proc(n)smark any(n)scopy;d:;b:bundle;

该解决方案几乎与语言手册直接相关,仅具有基本的高尔夫功能。

展开:

prog:  ignore(<< >>) parse(expr);
expr:  q(term, addop);
term:  q(fact, mulop);
fact:  q(prim, expop);
q:     proc(x,y) x k: y/done x ={ <(> 2 3 1 <)> } b\k;
prim:  op(!<<+-*/^()>>) | <(> expr <)>;
addop: op(<<+->>);
mulop: op(<<*/>>);
expop: op(<<^>>);
op:    proc(n) smark any(n) scopy;
done:  ;
b:     bundle;
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.