Hi, I've finished it using recursion.
#!/usr/bin/perl -w use strict; use Data::Dumper; #不检查输入算式是否正确 print "输入自然数算式(只允许加法、乘法、括号)\n"; print "输入完成按回车确认,退出请输入0\n\n"; while (1) { print "Enter the expression : "; chomp($_ = <STDIN>); last if not $_; my @tree = grow($_); print Dumper(\@tree); my $result = calculate(\@tree); print "\nresult\=$result\n\n"; my $answer = eval "$_"; print "Still have bug,the correct answer is $answer\n" if ($answer != $result); sub grow { my $expr = $_[0]; my ($part, @part, $node); if ($expr =~ /\(/){ @part = ($expr =~ / \( (?:(?>[^()]+) | (?R))* \) /xg); #提取括号中内容 foreach $part (@part) { $part =~ s/^\(|\)$//g; my @temp = grow($part); #递归调用 $part = \@temp; } $expr =~ s/\( ((?>[^()]+) | (?R))* \)/tag/xg; #原式中括号内容暂时用字符“tag”替代 } my @node= ($expr =~ /\d+|tag/g); #从算式中提取数字 my $i = 0; foreach $node (@node) { if ($node eq "tag"){ #tag内容还原成生成的树 $node = $part[$i]; $i++; } } my @op=($expr =~ /[+*()]/g); #从算式中提取算符 return basic (\@node, \@op); } sub basic { #将不含括号的算式转成树 my($a, $b, $i); ($a, $b) = @_; my @node = @$a; my @op = @$b; for($i = 0; $i < @op; $i++){ #转换乘法 if ($op[$i] eq "*"){ my $end = $i+1; while (defined($op[$end])&&($op[$end] eq "*")){ $end++ if $end < @op; } my $t = $end - $i; my @new = @node[$i..$end]; unshift (@new, "*"); splice(@node, $i, $t+1, \@new); splice(@op, $i, $t,); } } if (@op){ unshift (@node, "+"); }else{ @node=@{$node[0]}; } return @node; } sub calculate{ my $a = $_[0]; return $a if ref($a) ne "ARRAY"; my @tree = @$a; my $tree; my $result = 0; if ($tree[0] eq "+"){ shift @tree; foreach $tree(@tree){ $result = $result + calculate($tree); } } elsif ($tree[0] eq "*"){ $result = 1; shift @tree; foreach $tree(@tree){ $result = $result * calculate($tree); } } return $result; } } 1;
08300720014-07.pl
Description: Binary data
-- To unsubscribe, e-mail: beginners-unsubscr...@perl.org For additional commands, e-mail: beginners-h...@perl.org http://learn.perl.org/