Ich habe einen Weg gefunden, der zwar nicht perfekt ist, aber meinen bescheidenen Bedürfnissen vorerst genügt.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
#!/usr/bin/perl
use strict;
use warnings;
#use Data::Dumper;
my $operators = {
'+' => sub { my $i = shift @_; $i += $_ for @_; return $i },
'-' => sub { my $i = shift @_; $i -= $_ for @_; return $i },
'*' => sub { my $i = shift @_; $i *= $_ for @_; return $i },
'/' => sub { my $i = shift @_; $i /= $_ for @_; return $i },
};
my $task = "( + 3 4 ( * 2 7 ( + 1 1 ) ) ( / 6 2 ) )";
print calculate( split /\s+/, $task ), "\n";
exit;
sub solve {
my ( $op, @vals ) = @_;
die "solve(): wrong operator or to less values"
unless ( exists $operators->{$op} && $#vals >= 1 );
return $operators->{$op}(@vals);
}
sub calculate {
my @ops = @_;
@ops = @ops[ 1 .. $#ops - 1 ]
if $ops[0] eq '('
and $ops[-1] eq ')'; # remove leading and trailing brackets
my $marker = -1;
my $begin = undef;
my $end = undef;
my @marked = ();
for ( 0 .. $#ops ) {
$begin = $_ if $ops[$_] eq '(' && ++$marker == 0;
$end = $_ if $ops[$_] eq ')' && $marker-- == 0;
if ( defined $begin && defined $end ) {
push @marked, { begin => $begin,
end => $end }; # find balanced brackets on this level
$marker = -1;
$begin = undef;
$end = undef;
}
}
while (@marked) {
my $current = pop @marked;
splice @ops, $current->{begin}, # recursively solve inner brackets
$current->{end} - $current->{begin} + 1,
calculate( @ops[ $current->{begin} .. $current->{end} ] );
}
#print Dumper \@ops;
return solve(@ops);
}
\n\n
<!--EDIT|Ronnie|1117968563-->