您的位置:首页 > 其它

开篇词,贴一个刚写的24点牌程序作为实验

2012-12-25 11:08 302 查看
前几天突然决定在CSDN开一个博客。以前在其它地方也开过,可都无疾而终。最近大半年在CSDN看过很多朋友写的技术帖,深羡慕之,遂也决定自己开个一亩三分地。一来,将自己学到的一些东西做一个整理,二来,也可与大家分享。

前几天决定认真学习一下perl语言。以前也看过几页书,但一直都没有很严肃地去学,多是三天打鱼,两天晒网。人说要想学好一门语言,必须亲手写代码,而且要多写。我深以为然,所以这次用perl写了个算24点牌的程序。程序很简单,没什么可多说的,也没什么技术可言,纯属熟悉语言。另外,一个更重要的目的是来试试这个新博客的排版。

代码如下:

#!/usr/bin/perl -w

use strict;
use warnings;

sub build_new_array {
(my $i, my $j, my @nums) = @_;

my @new_array;
for (my $k = 0; $k < @nums; $k ++) {
if ($k != $i && $k != $j) {
push @new_array, $nums[$k];
}
}

return @new_array;
}

# do_cacl(n, numbers)
sub do_calc {
(my $n, my @numbers) = @_;

my $err = 0.00001;
if (scalar @numbers == 1) {
if ($n < $numbers[0]{"num"} - $err || $n > $numbers[0]{"num"} + $err) {
return undef;
} else {
return $numbers[0]{"expr"};
}
}

# if more than one numbers, try
for (my $i = 0; $i < @numbers - 1; $i ++) {
for (my $j = $i + 1; $j < @numbers; $j ++) {
my $a = $numbers[$i]{"num"};
my $b = $numbers[$j]{"num"};
my $expra = $numbers[$i]{"expr"};
my $exprb = $numbers[$j]{"expr"};

my @new_num = build_new_array($i, $j, @numbers);

# try plus
push @new_num, { "num" => $a + $b, "expr" => "$expra $exprb +" };
my $result = do_calc($n, @new_num);
return $result if defined $result;
pop @new_num;

# try minus
if ($a > $b) {
push @new_num, { "num" => $a - $b, "expr" => "$expra $exprb -" };
} else {
push @new_num, { "num" => $b - $a, "expr" => "$exprb $expra -" };
}
$result = do_calc($n, @new_num);
return $result if defined $result;
pop @new_num;

# try multiplication
push @new_num, { "num" => $a * $b, "expr" => "$expra $exprb *" };
$result = do_calc($n, @new_num);
return $result if defined $result;
pop @new_num;

# try dividend
if ($b > $err) {
push @new_num, { "num" => $a / $b, "expr" => "$expra $exprb /" };
$result = do_calc($n, @new_num);
return $result if defined $result;
pop @new_num;
}

if ($a > $err) {
push @new_num, { "num" => $b / $a, "expr" => "$exprb $expra /" };
$result = do_calc($n, @new_num);
return $result if defined $result;
}

}
}
return undef;
}

sub convert {
my $postfix = shift;
my @tokens = split /\s+/, $postfix;
my @expr_stack = ();
my @priority_stack = ();    # priority of ADD and SUB is 1 and priority of MUL and DIV is 2

foreach my $token (@tokens) {
# if the token is a operator
if ($token =~ /[+\-*\/]/) {
my $rhs_expr = pop @expr_stack;
my $rhs_pri = pop @priority_stack;
my $lhs_expr = pop @expr_stack;
my $lhs_pri = pop @priority_stack;

my $expr;
my $pri;

if ($token =~ /[*\/]/) {
if ($lhs_pri == 1) {
$lhs_expr = "($lhs_expr)";
}
if ($rhs_pri == 1 || ($rhs_pri == 2 && $token eq "/")) {
$rhs_expr = "($rhs_expr)";
}
$pri = 2;
} else {
if ($rhs_pri == 1 && $token eq "-") {
$rhs_expr = "($rhs_expr)";
}
$pri = 1;
}
$expr = "$lhs_expr $token $rhs_expr";

push @expr_stack, $expr;
push @priority_stack, $pri;
} else {
push @expr_stack, $token;
push @priority_stack, 0;
}
}

return $expr_stack[0];
}

while (defined(my $n = <STDIN>)) {
chomp $n;
$n =~ s/^\s+//;
$n =~ s/\s+$//;
my @n = split /\s+/, $n;

next if scalar @n == 0;

my @numbers;

foreach my $one (@n) {
push @numbers, { "num" => $one, "expr" => "$one" };
}

my $seq = do_calc(24, @numbers);
if (defined $seq) {
print convert($seq), "\n";
} else {
print "No answer!\n";
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐