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

前几天突然决定在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";
    }
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值