arrays - Perl中的子程序递归

标签 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每次子程序运行后都不会被清除,但我已经尝试了尽可能多的不同方法来清除它,这样每次我调用子程序时,它都会显示-仅-那个数字的序列但它们要么导致我在这里展示的东西,要么什么也不展示。我如何每次都清除数组?

非常感谢。

最佳答案

这里不需要递归。在我的 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

关于arrays - Perl中的子程序递归,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32595581/

相关文章:

c++ - 我的粒子数组不工作(C++/粒子系统)

regex - 为什么我的 Perl 正则表达式会导致无限循环?

string - 在 Perl 中将所有参数作为字符串传递给子例程

javascript - 关于 C3.js 图表数据拆分

php - php array_column 函数的逆函数?

perl - 使用包时全局使用工具位置

debugging - Fortran 是否通过子程序多次调用修改输入参数?

在c中计算数组中的相对位置

perl - 如何将内置函数作为回调参数传递?