- 论坛徽章:
- 0
|
回复 6# sy5tem - my @test_arr=(10,5,2,2);
- my @oprator_arr=('+', '-','*','/');
- perm(\@test_arr);
- rec_cala(\@test_arr);
- sub rec_cala
- {
- my ($arr_ref) = @_;
- my @input_arr = ();
- push @input_arr,@$arr_ref;
- if (scalar(@input_arr) <= 1)
- {
- #如果数组只有一个元素则计算表达式的值,等于24则显示
- $result = eval $input_arr[0];
- if ($result > 23.9 && $result < 24.1)
- {
- print $input_arr[0];
- print " = 24\n";
- }
- }
- else
- {
- #生成全排列
- my @perm_arr = perm(\@input_arr);
-
- foreach(@perm_arr)
- {
- my @next_arr = @$_;
- my $op1 = pop @next_arr;
- my $op2 = pop @next_arr;
- #取出2个元素,与符号生成一个表达式,然后递归
- foreach(@oprator_arr)
- {
- @op_expr_arr = @next_arr;
- push @op_expr_arr, "($op1 $_ $op2)";
- rec_cala(\@op_expr_arr);
- }
-
- }
- }
- }
- #排列生成器
- #方法是: "先选一个数 1, 然后第二个数 2 可以放在 1 的前面或是后面. 而每一个放法都会产生一个 2 位数, 对於每一个这样的两位数, 第三个数 3, 都可以放在它的前面, 中间, 或是最后; 如此产生一个 3 位数; 而每一个 3 位数, 第 4 位数都可以插入到这 3 个数的任何一个空位中, 如此类推.
- sub perm
- {
- my ($arr_ref)=@_;
- my @arr=@$arr_ref; #变成数组,引用会直接修改传入参数,而且用起来很麻烦
- my @result = []; #初始化一个空的数组的引用
-
- #每循环一次数组都会缩短,到0退出
- while(scalar(@arr))
- {
- my $curr_element = pop @arr; #拿出一个元素,前后无所谓咯,这个是用来插入的元素
- my @next_step = (); #每次用一个空的数组放结果
- foreach $curr_array (@result) #遍历要插入的数组,第一次这里有一个空的数组的引用,所以会进去
- {
- $curr_len = scalar(@$curr_array);
- for($i=0; $i<= $curr_len;$i++)
- {
- # 插入到数组的各个位置,每插入一次就加到@next_step去
- push @next_step,[ ( @$curr_array[0..$i], $curr_element,@$curr_array[$i+1..$curr_len ])];
- }
- }
- #插入完成后,把结果作为下一步要插入的数组
- @result = @next_step;
- }
- return @result;
- }
复制代码 加了些注释,应该容易看一点了吧
呵呵 |
|