递归调用不会在perl中打印字符串的预期组合

时间:2015-07-29 09:43:27

标签: perl recursion perl-module perl-data-structures

下面的程序是打印字符串的所有可能的排列。我在Perl中试过这个。但输出似乎不是预期的输出。有人可以帮忙吗?

print "Enter string ";
chomp( $str = <STDIN> );

$n = length($str);

&combi( $str, 0, ( $n - 1 ) );

sub combi {
    $l = $_[1];
    $r = $_[2];
    if ( $l == $r ) {
        print( $_[0], "\n" );
    }
    else {
        @char = split( "", $_[0] );

        for ( $i = $l; $i <= $r; $i++ ) {
            &swap( $char[ $_[1] ], $char[$i] );
            $res = join( "", @char );
            &combi( $res, ( ( $_[1] ) + 1 ), $r );
            &swap( $char[ $_[1] ], $char[$i] );
        }
    }
}

sub swap {
    $temp = $_[0];
    $_[0] = $_[1];
    $_[1] = $temp;
}

该计划的输出:

Enter String: abc
abc
acb

2 个答案:

答案 0 :(得分:3)

您可以使用CPAN模块List::Permutor打印所有可能的排列。

例如:

use List::Permutor;
my $perm = new List::Permutor qw/ fred barney betty /;
while (my @set = $perm->next) {
  print "One order is @set.\n";
}

另一个模块是Algorithm::Permute - 具有面向对象接口的方便快速的排列。

答案 1 :(得分:2)

我很难理解你的代码,但我认为你的问题是 - 你正在尝试做一个非常重的方法,但重要的是 - 你实际&#39;放卷&#39;递归的尾巴。

递归算法的要点是您遍历深度但整理结果。

所以我会像这样处理你的问题:

#!/usr/bin/env perl
use strict;
use warnings;

my $str = 'abcde';

sub combinations {
    my ($string) = @_;

    print "Starting combinations with \"$string\"\n";
    if ( length($string) == 1 ) {
        return ($string);
    }
    my @combinations;
    for my $index ( 0 .. length($string) - 1 ) {
        my @chars = split( //, $string );
        my $firstletter = splice( @chars, $index, 1 );
        print "Keeping: $firstletter combining @chars\n";
        foreach my $combination ( combinations( join( "", @chars ) ) ) {
            print "Got for @chars $combination\n";
            push( @combinations, $firstletter . $combination );
        }
    }
    return (@combinations);
}

print join( "\n", combinations($str) );

我们有一个递归程序,给出了&#39;一个字符串。它迭代该字符串中的每个字母 - 挑出第一个字母&#39;并将剩余的字母交给递归调用来做同样的事情。

然而它又一直坚持着#39;通话结果,列出“结果”列表&#39; - 因为每个级别&#39;呼叫应该生成一些答案,然后返回到更高级别的呼叫等。

注意 - 我也是:

  • 启用了strictwarnings - 这在编写代码时非常重要。
  • 在子调用中未使用&前缀。这很少是你想要做的事情。
  • 未引用$_[0] - 作为样式点,您应该避免使用隐式变量显式。为你的args命名,给他们一些明确的名字。