Perl中的子例程递归

时间:2015-09-15 21:03:12

标签: arrays perl subroutine

编辑:我很高兴没有人花时间指出第6行和第7行中的实际文本的数字与其各自函数调用的输入数字不同。最终我会为这两个数字(724和27)做这件事,但为了排除故障,我选择了数量更小的数字。所以,如果有人想知道,那就是为什么......

所以,我一直在学习Perl,而且对于一般的编程来说相对较新。我的主管有一套练习让我通过。当前的一个处理Hailstone序列,她希望我编写一个子程序来打印给定数字的序列。

我遇到的问题是,无论我尝试过什么,如果我不止一次调用该函数,它将产生我调用该函数的第一个数字的序列,但是第二次调用函数时,它会产生第一个调用的序列,然后是第二个调用的序列。所以,这段代码:

#!usr/bin/perl

use strict;
use warnings; 

print "\nThe hailstone sequence for 724 is:\n" . &hail(8) . "\n\n";
print "The hailstone sequence for 27 is:\n" . &hail(16) . "\n\n";

my $n;
my @seq;
sub hail {
    no warnings 'recursion';
    $n = $_[0];
    if ($n > 1) {
            push @seq, $n;
            if ($n % 2 == 0) {
                    $n = $n/2;
            } else {
                    $n = (3 * $n) + 1;
            }
            &hail($n);
    } else {
            push @seq, $n;
    }
    return "@seq";
}

产生

The hailstone sequence for 724 is:
8 4 2 1

The hailstone sequence for 27 is:
8 4 2 1 16 8 4 2 1

我知道这很可能是因为@seq每次子程序运行后都没有被清除,但我已经尝试了尽可能多的不同方式清除它以便每次调用子程序时,它只显示 - 该数字的序列,但它们都会导致我在此处显示的内容,或者显示任何内容。我如何每次清理阵列?

非常感谢。

7 个答案:

答案 0 :(得分:5)

这里你不需要递归。在我Mastering Perl中的斐波纳契示例中,我表明通过自己管理队列而不是使用调用堆栈来进行迭代,这样做更容易。

这是一个通用的迭代解决方案,它使用数组来跟踪剩下的工作:

use strict;
use warnings;
use v5.10;

say "The hailstone sequence for 724 is:\n\t" .
    join " ", hail(8);
say "The hailstone sequence for 27 is:\n\t"  .
    join " ", hail(16);


sub hail {
    my @queue    = ( $_[0] );
    my @sequence = ();

    while( my $next = shift @queue ) {
        if( $next > 1 ) {
            push @queue, do {
                if( $next % 2 == 0 ) { $next / 2 }
                else                 { 3*$next + 1 }
                };
            }

        push @sequence, $next;
        }

    @sequence;
    }

从那里,我可以添加缓存和其他东西,这样我就可以重复使用我已经生成的序列(即使没有展示一些令人兴奋的新Perl功能,例如subroutine signaturespostfix dereferencing我觉得很有趣):

use strict;
use warnings;
use v5.22;

use feature qw(signatures postderef);
no warnings qw(experimental::signatures experimental::postderef);

say "The hailstone sequence for 724 is:\n\t" .
    join " ", hail(8)->@*;
say "The hailstone sequence for 27 is:\n\t"  .
    join " ", hail(16)->@*;


sub hail ( $n ) {
    my @queue    = ( $_[0] );
    state $sequence = { 1 => [ 1 ] };

    return $sequence->{$n} if exists $sequence->{$n};

    my @sequence = ();

    while( my $next = shift @queue ) {
        say "Processing $next";  # to watch what happens
        if( exists $sequence->{$next} ) {
            push @sequence, $sequence->{$next}->@*;
            next;
            }

        push @queue, do {
            if( $next % 2 == 0 ) { $next / 2 }
            else                 { 3*$next + 1 }
            };

        push @sequence, $next;
        }

    $sequence->{$n} = \@sequence;
    }

我在那里扔了say以显示我处理的内容。您可以看到16,它不必超过8,因为它已经知道答案:

Processing 8
Processing 4
Processing 2
Processing 1
The hailstone sequence for 724 is:
    8 4 2 1
Processing 16
Processing 8
The hailstone sequence for 27 is:
    16 8 4 2 1

我很好奇哪些数字可能会导致问题,因此我稍微修改了您的示例以返回列表,以便我可以轻松计算元素的数量。有几个数字产生了超过100个数字的序列:

use strict;
use warnings;
use v5.10;

foreach my $n ( 0 .. 100 ) {
    hail( $n, \my @seq );
    say "$n [" . @seq . "] @seq";
    }

sub hail {
    my $n = $_[0];
    my $s = $_[1];

    if ($n > 1) {
            push @$s, $n;
            if ($n % 2 == 0) {
                    $n = $n/2;
            } else {
                    $n = (3 * $n) + 1;
            }
            hail($n, $s);
    } else {
            push @$s, $n;
    }
}

输出,没有深度递归警告(应该提示不要这样做;):

0 [1] 0
1 [1] 1
2 [2] 2 1
3 [8] 3 10 5 16 8 4 2 1
4 [3] 4 2 1
5 [6] 5 16 8 4 2 1
6 [9] 6 3 10 5 16 8 4 2 1
7 [17] 7 22 11 34 17 52 26 13 40 20 10 5 16 8 4 2 1
8 [4] 8 4 2 1
9 [20] 9 28 14 7 22 11 34 17 52 26 13 40 20 10 5 16 8 4 2 1
10 [7] 10 5 16 8 4 2 1
11 [15] 11 34 17 52 26 13 40 20 10 5 16 8 4 2 1
12 [10] 12 6 3 10 5 16 8 4 2 1
13 [10] 13 40 20 10 5 16 8 4 2 1
14 [18] 14 7 22 11 34 17 52 26 13 40 20 10 5 16 8 4 2 1
15 [18] 15 46 23 70 35 106 53 160 80 40 20 10 5 16 8 4 2 1
16 [5] 16 8 4 2 1
17 [13] 17 52 26 13 40 20 10 5 16 8 4 2 1
18 [21] 18 9 28 14 7 22 11 34 17 52 26 13 40 20 10 5 16 8 4 2 1
19 [21] 19 58 29 88 44 22 11 34 17 52 26 13 40 20 10 5 16 8 4 2 1
20 [8] 20 10 5 16 8 4 2 1
21 [8] 21 64 32 16 8 4 2 1
22 [16] 22 11 34 17 52 26 13 40 20 10 5 16 8 4 2 1
23 [16] 23 70 35 106 53 160 80 40 20 10 5 16 8 4 2 1
24 [11] 24 12 6 3 10 5 16 8 4 2 1
25 [24] 25 76 38 19 58 29 88 44 22 11 34 17 52 26 13 40 20 10 5 16 8 4 2 1
26 [11] 26 13 40 20 10 5 16 8 4 2 1
27 [112] 27 82 41 124 62 31 94 47 142 71 214 107 322 161 484 242 121 364 182 91 274 137 412 206 103 310 155 466 233 700 350 175 526 263 790 395 1186 593 1780 890 445 1336 668 334 167 502 251 754 377 1132 566 283 850 425 1276 638 319 958 479 1438 719 2158 1079 3238 1619 4858 2429 7288 3644 1822 911 2734 1367 4102 2051 6154 3077 9232 4616 2308 1154 577 1732 866 433 1300 650 325 976 488 244 122 61 184 92 46 23 70 35 106 53 160 80 40 20 10 5 16 8 4 2 1
28 [19] 28 14 7 22 11 34 17 52 26 13 40 20 10 5 16 8 4 2 1
29 [19] 29 88 44 22 11 34 17 52 26 13 40 20 10 5 16 8 4 2 1
30 [19] 30 15 46 23 70 35 106 53 160 80 40 20 10 5 16 8 4 2 1
31 [107] 31 94 47 142 71 214 107 322 161 484 242 121 364 182 91 274 137 412 206 103 310 155 466 233 700 350 175 526 263 790 395 1186 593 1780 890 445 1336 668 334 167 502 251 754 377 1132 566 283 850 425 1276 638 319 958 479 1438 719 2158 1079 3238 1619 4858 2429 7288 3644 1822 911 2734 1367 4102 2051 6154 3077 9232 4616 2308 1154 577 1732 866 433 1300 650 325 976 488 244 122 61 184 92 46 23 70 35 106 53 160 80 40 20 10 5 16 8 4 2 1
32 [6] 32 16 8 4 2 1
33 [27] 33 100 50 25 76 38 19 58 29 88 44 22 11 34 17 52 26 13 40 20 10 5 16 8 4 2 1
34 [14] 34 17 52 26 13 40 20 10 5 16 8 4 2 1
35 [14] 35 106 53 160 80 40 20 10 5 16 8 4 2 1
36 [22] 36 18 9 28 14 7 22 11 34 17 52 26 13 40 20 10 5 16 8 4 2 1
37 [22] 37 112 56 28 14 7 22 11 34 17 52 26 13 40 20 10 5 16 8 4 2 1
38 [22] 38 19 58 29 88 44 22 11 34 17 52 26 13 40 20 10 5 16 8 4 2 1
39 [35] 39 118 59 178 89 268 134 67 202 101 304 152 76 38 19 58 29 88 44 22 11 34 17 52 26 13 40 20 10 5 16 8 4 2 1
40 [9] 40 20 10 5 16 8 4 2 1
41 [110] 41 124 62 31 94 47 142 71 214 107 322 161 484 242 121 364 182 91 274 137 412 206 103 310 155 466 233 700 350 175 526 263 790 395 1186 593 1780 890 445 1336 668 334 167 502 251 754 377 1132 566 283 850 425 1276 638 319 958 479 1438 719 2158 1079 3238 1619 4858 2429 7288 3644 1822 911 2734 1367 4102 2051 6154 3077 9232 4616 2308 1154 577 1732 866 433 1300 650 325 976 488 244 122 61 184 92 46 23 70 35 106 53 160 80 40 20 10 5 16 8 4 2 1
42 [9] 42 21 64 32 16 8 4 2 1
43 [30] 43 130 65 196 98 49 148 74 37 112 56 28 14 7 22 11 34 17 52 26 13 40 20 10 5 16 8 4 2 1
44 [17] 44 22 11 34 17 52 26 13 40 20 10 5 16 8 4 2 1
45 [17] 45 136 68 34 17 52 26 13 40 20 10 5 16 8 4 2 1
46 [17] 46 23 70 35 106 53 160 80 40 20 10 5 16 8 4 2 1
47 [105] 47 142 71 214 107 322 161 484 242 121 364 182 91 274 137 412 206 103 310 155 466 233 700 350 175 526 263 790 395 1186 593 1780 890 445 1336 668 334 167 502 251 754 377 1132 566 283 850 425 1276 638 319 958 479 1438 719 2158 1079 3238 1619 4858 2429 7288 3644 1822 911 2734 1367 4102 2051 6154 3077 9232 4616 2308 1154 577 1732 866 433 1300 650 325 976 488 244 122 61 184 92 46 23 70 35 106 53 160 80 40 20 10 5 16 8 4 2 1
48 [12] 48 24 12 6 3 10 5 16 8 4 2 1
49 [25] 49 148 74 37 112 56 28 14 7 22 11 34 17 52 26 13 40 20 10 5 16 8 4 2 1
50 [25] 50 25 76 38 19 58 29 88 44 22 11 34 17 52 26 13 40 20 10 5 16 8 4 2 1
51 [25] 51 154 77 232 116 58 29 88 44 22 11 34 17 52 26 13 40 20 10 5 16 8 4 2 1
52 [12] 52 26 13 40 20 10 5 16 8 4 2 1
53 [12] 53 160 80 40 20 10 5 16 8 4 2 1
54 [113] 54 27 82 41 124 62 31 94 47 142 71 214 107 322 161 484 242 121 364 182 91 274 137 412 206 103 310 155 466 233 700 350 175 526 263 790 395 1186 593 1780 890 445 1336 668 334 167 502 251 754 377 1132 566 283 850 425 1276 638 319 958 479 1438 719 2158 1079 3238 1619 4858 2429 7288 3644 1822 911 2734 1367 4102 2051 6154 3077 9232 4616 2308 1154 577 1732 866 433 1300 650 325 976 488 244 122 61 184 92 46 23 70 35 106 53 160 80 40 20 10 5 16 8 4 2 1
55 [113] 55 166 83 250 125 376 188 94 47 142 71 214 107 322 161 484 242 121 364 182 91 274 137 412 206 103 310 155 466 233 700 350 175 526 263 790 395 1186 593 1780 890 445 1336 668 334 167 502 251 754 377 1132 566 283 850 425 1276 638 319 958 479 1438 719 2158 1079 3238 1619 4858 2429 7288 3644 1822 911 2734 1367 4102 2051 6154 3077 9232 4616 2308 1154 577 1732 866 433 1300 650 325 976 488 244 122 61 184 92 46 23 70 35 106 53 160 80 40 20 10 5 16 8 4 2 1
56 [20] 56 28 14 7 22 11 34 17 52 26 13 40 20 10 5 16 8 4 2 1
57 [33] 57 172 86 43 130 65 196 98 49 148 74 37 112 56 28 14 7 22 11 34 17 52 26 13 40 20 10 5 16 8 4 2 1
58 [20] 58 29 88 44 22 11 34 17 52 26 13 40 20 10 5 16 8 4 2 1
59 [33] 59 178 89 268 134 67 202 101 304 152 76 38 19 58 29 88 44 22 11 34 17 52 26 13 40 20 10 5 16 8 4 2 1
60 [20] 60 30 15 46 23 70 35 106 53 160 80 40 20 10 5 16 8 4 2 1
61 [20] 61 184 92 46 23 70 35 106 53 160 80 40 20 10 5 16 8 4 2 1
62 [108] 62 31 94 47 142 71 214 107 322 161 484 242 121 364 182 91 274 137 412 206 103 310 155 466 233 700 350 175 526 263 790 395 1186 593 1780 890 445 1336 668 334 167 502 251 754 377 1132 566 283 850 425 1276 638 319 958 479 1438 719 2158 1079 3238 1619 4858 2429 7288 3644 1822 911 2734 1367 4102 2051 6154 3077 9232 4616 2308 1154 577 1732 866 433 1300 650 325 976 488 244 122 61 184 92 46 23 70 35 106 53 160 80 40 20 10 5 16 8 4 2 1
63 [108] 63 190 95 286 143 430 215 646 323 970 485 1456 728 364 182 91 274 137 412 206 103 310 155 466 233 700 350 175 526 263 790 395 1186 593 1780 890 445 1336 668 334 167 502 251 754 377 1132 566 283 850 425 1276 638 319 958 479 1438 719 2158 1079 3238 1619 4858 2429 7288 3644 1822 911 2734 1367 4102 2051 6154 3077 9232 4616 2308 1154 577 1732 866 433 1300 650 325 976 488 244 122 61 184 92 46 23 70 35 106 53 160 80 40 20 10 5 16 8 4 2 1
64 [7] 64 32 16 8 4 2 1
65 [28] 65 196 98 49 148 74 37 112 56 28 14 7 22 11 34 17 52 26 13 40 20 10 5 16 8 4 2 1
66 [28] 66 33 100 50 25 76 38 19 58 29 88 44 22 11 34 17 52 26 13 40 20 10 5 16 8 4 2 1
67 [28] 67 202 101 304 152 76 38 19 58 29 88 44 22 11 34 17 52 26 13 40 20 10 5 16 8 4 2 1
68 [15] 68 34 17 52 26 13 40 20 10 5 16 8 4 2 1
69 [15] 69 208 104 52 26 13 40 20 10 5 16 8 4 2 1
70 [15] 70 35 106 53 160 80 40 20 10 5 16 8 4 2 1
71 [103] 71 214 107 322 161 484 242 121 364 182 91 274 137 412 206 103 310 155 466 233 700 350 175 526 263 790 395 1186 593 1780 890 445 1336 668 334 167 502 251 754 377 1132 566 283 850 425 1276 638 319 958 479 1438 719 2158 1079 3238 1619 4858 2429 7288 3644 1822 911 2734 1367 4102 2051 6154 3077 9232 4616 2308 1154 577 1732 866 433 1300 650 325 976 488 244 122 61 184 92 46 23 70 35 106 53 160 80 40 20 10 5 16 8 4 2 1
72 [23] 72 36 18 9 28 14 7 22 11 34 17 52 26 13 40 20 10 5 16 8 4 2 1
73 [116] 73 220 110 55 166 83 250 125 376 188 94 47 142 71 214 107 322 161 484 242 121 364 182 91 274 137 412 206 103 310 155 466 233 700 350 175 526 263 790 395 1186 593 1780 890 445 1336 668 334 167 502 251 754 377 1132 566 283 850 425 1276 638 319 958 479 1438 719 2158 1079 3238 1619 4858 2429 7288 3644 1822 911 2734 1367 4102 2051 6154 3077 9232 4616 2308 1154 577 1732 866 433 1300 650 325 976 488 244 122 61 184 92 46 23 70 35 106 53 160 80 40 20 10 5 16 8 4 2 1
74 [23] 74 37 112 56 28 14 7 22 11 34 17 52 26 13 40 20 10 5 16 8 4 2 1
75 [15] 75 226 113 340 170 85 256 128 64 32 16 8 4 2 1
76 [23] 76 38 19 58 29 88 44 22 11 34 17 52 26 13 40 20 10 5 16 8 4 2 1
77 [23] 77 232 116 58 29 88 44 22 11 34 17 52 26 13 40 20 10 5 16 8 4 2 1
78 [36] 78 39 118 59 178 89 268 134 67 202 101 304 152 76 38 19 58 29 88 44 22 11 34 17 52 26 13 40 20 10 5 16 8 4 2 1
79 [36] 79 238 119 358 179 538 269 808 404 202 101 304 152 76 38 19 58 29 88 44 22 11 34 17 52 26 13 40 20 10 5 16 8 4 2 1
80 [10] 80 40 20 10 5 16 8 4 2 1
81 [23] 81 244 122 61 184 92 46 23 70 35 106 53 160 80 40 20 10 5 16 8 4 2 1
82 [111] 82 41 124 62 31 94 47 142 71 214 107 322 161 484 242 121 364 182 91 274 137 412 206 103 310 155 466 233 700 350 175 526 263 790 395 1186 593 1780 890 445 1336 668 334 167 502 251 754 377 1132 566 283 850 425 1276 638 319 958 479 1438 719 2158 1079 3238 1619 4858 2429 7288 3644 1822 911 2734 1367 4102 2051 6154 3077 9232 4616 2308 1154 577 1732 866 433 1300 650 325 976 488 244 122 61 184 92 46 23 70 35 106 53 160 80 40 20 10 5 16 8 4 2 1
83 [111] 83 250 125 376 188 94 47 142 71 214 107 322 161 484 242 121 364 182 91 274 137 412 206 103 310 155 466 233 700 350 175 526 263 790 395 1186 593 1780 890 445 1336 668 334 167 502 251 754 377 1132 566 283 850 425 1276 638 319 958 479 1438 719 2158 1079 3238 1619 4858 2429 7288 3644 1822 911 2734 1367 4102 2051 6154 3077 9232 4616 2308 1154 577 1732 866 433 1300 650 325 976 488 244 122 61 184 92 46 23 70 35 106 53 160 80 40 20 10 5 16 8 4 2 1
84 [10] 84 42 21 64 32 16 8 4 2 1
85 [10] 85 256 128 64 32 16 8 4 2 1
86 [31] 86 43 130 65 196 98 49 148 74 37 112 56 28 14 7 22 11 34 17 52 26 13 40 20 10 5 16 8 4 2 1
87 [31] 87 262 131 394 197 592 296 148 74 37 112 56 28 14 7 22 11 34 17 52 26 13 40 20 10 5 16 8 4 2 1
88 [18] 88 44 22 11 34 17 52 26 13 40 20 10 5 16 8 4 2 1
89 [31] 89 268 134 67 202 101 304 152 76 38 19 58 29 88 44 22 11 34 17 52 26 13 40 20 10 5 16 8 4 2 1
90 [18] 90 45 136 68 34 17 52 26 13 40 20 10 5 16 8 4 2 1
91 [93] 91 274 137 412 206 103 310 155 466 233 700 350 175 526 263 790 395 1186 593 1780 890 445 1336 668 334 167 502 251 754 377 1132 566 283 850 425 1276 638 319 958 479 1438 719 2158 1079 3238 1619 4858 2429 7288 3644 1822 911 2734 1367 4102 2051 6154 3077 9232 4616 2308 1154 577 1732 866 433 1300 650 325 976 488 244 122 61 184 92 46 23 70 35 106 53 160 80 40 20 10 5 16 8 4 2 1
92 [18] 92 46 23 70 35 106 53 160 80 40 20 10 5 16 8 4 2 1
93 [18] 93 280 140 70 35 106 53 160 80 40 20 10 5 16 8 4 2 1
94 [106] 94 47 142 71 214 107 322 161 484 242 121 364 182 91 274 137 412 206 103 310 155 466 233 700 350 175 526 263 790 395 1186 593 1780 890 445 1336 668 334 167 502 251 754 377 1132 566 283 850 425 1276 638 319 958 479 1438 719 2158 1079 3238 1619 4858 2429 7288 3644 1822 911 2734 1367 4102 2051 6154 3077 9232 4616 2308 1154 577 1732 866 433 1300 650 325 976 488 244 122 61 184 92 46 23 70 35 106 53 160 80 40 20 10 5 16 8 4 2 1
95 [106] 95 286 143 430 215 646 323 970 485 1456 728 364 182 91 274 137 412 206 103 310 155 466 233 700 350 175 526 263 790 395 1186 593 1780 890 445 1336 668 334 167 502 251 754 377 1132 566 283 850 425 1276 638 319 958 479 1438 719 2158 1079 3238 1619 4858 2429 7288 3644 1822 911 2734 1367 4102 2051 6154 3077 9232 4616 2308 1154 577 1732 866 433 1300 650 325 976 488 244 122 61 184 92 46 23 70 35 106 53 160 80 40 20 10 5 16 8 4 2 1
96 [13] 96 48 24 12 6 3 10 5 16 8 4 2 1
97 [119] 97 292 146 73 220 110 55 166 83 250 125 376 188 94 47 142 71 214 107 322 161 484 242 121 364 182 91 274 137 412 206 103 310 155 466 233 700 350 175 526 263 790 395 1186 593 1780 890 445 1336 668 334 167 502 251 754 377 1132 566 283 850 425 1276 638 319 958 479 1438 719 2158 1079 3238 1619 4858 2429 7288 3644 1822 911 2734 1367 4102 2051 6154 3077 9232 4616 2308 1154 577 1732 866 433 1300 650 325 976 488 244 122 61 184 92 46 23 70 35 106 53 160 80 40 20 10 5 16 8 4 2 1
98 [26] 98 49 148 74 37 112 56 28 14 7 22 11 34 17 52 26 13 40 20 10 5 16 8 4 2 1
99 [26] 99 298 149 448 224 112 56 28 14 7 22 11 34 17 52 26 13 40 20 10 5 16 8 4 2 1
100 [26] 100 50 25 76 38 19 58 29 88 44 22 11 34 17 52 26 13 40 20 10 5 16 8 4 2 1

答案 1 :(得分:4)

你是否想要一个真正的功能 - 一个没有任何副作用的功能,因此没有任何问题 - 它看起来如下:

sub hail {
    no warnings qw( recursion );
    my ($n) = @_;
    if ($n > 1) {
        if ($n % 2 == 0) {
            return $n, hail($n/2);
        } else {
            return $n, hail(3*$n + 1);
        }
    } else {
        return $n;
    }
}

请注意,此处完全不需要递归,这会大大减慢程序速度并增加内存占用。以下是这样一个迭代解决方案:

sub hail {
    my ($n) = @_;
    my @rv;
    while (1) {
        push @rv, $n;
        last if $n <= 1;

        if ($n % 2 == 0) {
            $n = $n/2;
        } else {
            $n = 3*$n + 1;
        }
    }

    return @rv;
}

评论中提到了有关上述代码的问题。以下是答案:

last跳转到循环后的语句。

另一位程序员可能写了以下内容:

push @rv, $n;
while ($n > 1) {
   ...;
   push @rv, $n;
}

但这包含重复的代码。理想情况下,人们试图避免重复的代码。但是从那以后

while (EXPR) { STATEMENTS }

可以改写为

while (1) { last if !EXPR; STATEMENTS }

以及

push @rv, $n;
while ($n > 1) {
   ...;
   push @rv, $n;
}

可以改写为

push @rv, $n;
while (1) {
   last if $n <= 1;
   ...;
   push @rv, $n;
}

我们可以删除重复的代码,如下所示:

while (1) {
   push @rv, $n;
   last if $n <= 1;
   ...;
}

答案 2 :(得分:0)

不确定perl,但我会用其他语言

sub hail {
    my @seq;
    return hailRecursive(\@seq, $_[0])
}

然后根据数组ref和$ n

实现hailRecursive

答案 3 :(得分:0)

因此,完整的任务是打印任何数字的序列&lt;我选择100000,打印27的序列,然后找到数字&lt; 100000具有最长的序列,并打印序列中的元素数量(但不是序列本身)我非常感谢每个人提供的关于制作更有效的子程序的帮助,我真的会通过不同的建议来学习不同的每个人的提示和技巧。为了练习,我没有过多修改我的主子程序代码以使其更符合我的(当前)风格。 (我的主管不在乎我得到了帮助,但它仍然感觉...... - 只是复制其他人的代码而不知道我能用自己的头发弄明白 - 脑筋急转弯的想法,以及使用递归子程序的建议。

我接受了一个人的建议,不将数组作为一个字符串返回,这有助于我最初没有提及的练习部分,但后来我不得不重新编写我打印实际序列的方式这似乎很容易。除了学习更有效的子程序之外,我主要担心的是清除数组。有人建议在每个实例之后放置@seq = (),这样可行。我想知道的是为什么我实际在代码中运行的代码(##### - 后代码的代码行)每次都清除数组,但为什么它不能简单地清除在我在子程序中返回它之后将数组输出,就像我在注释掉的行中一样。每次调用子例程时,它仍会聚合序列。

#!usr/bin/perl

use strict;
use warnings;

my $num_win = 0;
my $elem_win = 0;
my @seq;
my $elements;

print "\nThe hailstone sequence for 724 is:\n";
&sequence(&hail(724));
@seq = ();      #####

print "\n\nThe hailstone sequence for 27 is:\n";
&sequence(&hail(27));
@seq = ();      #####

for (my $i=1; $i<100000; $i++) {
    $elements = &hail($i);
    if ($elements > $elem_win) {
            $elem_win = $elements;
            $num_win = $i;
    }
    @seq = ();      #####
}

print "\n\nThe number with the largest sequence is: $num_win\n";
print "The number of elements in $num_win is: $elem_win\n\n";

my $n;
sub hail {
    no warnings 'recursion';
    $n = $_[0];
    if ($n > 1) {
            push @seq, $n;
            if ($n % 2 == 0) {
                    $n = $n/2;
            } else {
                    $n = (3 * $n) + 1;
            }
            &hail($n);
    } else {
            push @seq, $n;
    }
    return @seq;
#####   @seq = ();
}

sub sequence {
    my @hail_seq = @_;
    foreach (@hail_seq) {
            my $number = $_;
            print "$number, ";
    }
}

结果:

The hailstone sequence for 724 is:
724, 362, 181, 544, 272, 136, 68, 34, 17, 52, 26, 13, 40, 20, 10, 5, 16, 8, 4, 2, 1, 

The hailstone sequence for 27 is:
27, 82, 41, 124, 62, 31, 94, 47, 142, 71, 214, 107, 322, 161, 484, 242, 121, 364, 182, 91, 274, 137, 412, 206, 103, 310, 155, 466, 233, 700, 350, 175, 526, 263, 790, 395, 1186, 593, 1780, 890, 445, 1336, 668, 334, 167, 502, 251, 754, 377, 1132, 566, 283, 850, 425, 1276, 638, 319, 958, 479, 1438, 719, 2158, 1079, 3238, 1619, 4858, 2429, 7288, 3644, 1822, 911, 2734, 1367, 4102, 2051, 6154, 3077, 9232, 4616, 2308, 1154, 577, 1732, 866, 433, 1300, 650, 325, 976, 488, 244, 122, 61, 184, 92, 46, 23, 70, 35, 106, 53, 160, 80, 40, 20, 10, 5, 16, 8, 4, 2, 1, 

The number with the largest sequence is: 77031
The number of elements in 77031 is: 351

答案 4 :(得分:-1)

将第二个else块更改为此块,并在该块之后删除return语句。

else {
    push @seq, $n;
    my $seq = "@seq";
    undef @seq;
    return $seq;
}

答案 5 :(得分:-1)

您需要在第二次调用hail子例程之前初始化数组@seq。试试这个......

my @seq;
print "\nThe hailstone sequence for 724 is:\n" . &hail(8) . "\n\n";
@seq = ();
print "The hailstone sequence for 27 is:\n" . &hail(16) . "\n\n";

my $n;

答案 6 :(得分:-1)

与其他人发布的内容类似。

sub hailstone {
    my $n = shift;
    return if $n == 1;
    if ( $n % 2 == 0 ){
        $n = $n / 2;
    } else {
        $n = ( $n * 3 ) + 1;
    }
    return $n."\n",hailstone($n)
}

调用子程序时:

say hailstone(5);
16
8
4
2
1