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;

Attachment: 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/

Reply via email to