4
use Modern::Perl;
use Algorithm::Permute;
use List::AllUtils qw/uniq/;

find_perms(1151);

sub find_perms { 
  my ($value) = @_;
  my @others;
  my @digits = split(//, $value);

  my $perm = Algorithm::Permute->new( \@digits );

  while (my @next = $perm->next()) { 
    my $number = join('', @next);
    push @others, $number;
  }
  @others = sort uniq @others;

  # this one works correctly
  # @others = sort ( uniq( @others ));

  say "FOUND @others";
}

Output:
FOUND 1115 1115 1115 1115 1115 1115 1151 1151 1151 1151 1151 1151 1511 1511 1511 1511 1511 1511 5111 5111 5111 5111 5111 5111

やあ、

Algorithm :: Permuteが重複を生成していることを発見した後、おそらく「1151」の「1」の量が原因で、を使用することにしましuniqた。ただしsort uniq、括弧なしで使用しても、期待した結果は得られません。しかし、sort(uniq(@x))そうです。何が得られますか?

4

3 に答える 3

6

perldoc -f sortsort関数の3つの構文をリストします。

sort SUBNAME LIST
sort BLOCK LIST
sort LIST

sort uniq @otherssort SUBNAME LISTsortの構文に一致します。uniqこれは、グローバル変数$aとを比較し、、$bを返す関数<0、またはとの相対的な順序を示す0関数であることが期待されます。>0$a$b

構文を期待して欲しかったようですsort LIST。これは、次のいずれかを言うと得られるものです。

sort(uniq(@others))
sort(uniq @others)
于 2012-06-27T22:00:37.873 に答える
5

Algorithm :: LoopsNextPermuteは重複を生成しないため、それらを取り除くためにメモリとCPUを費やす必要はありません。

use Algorithm::Loops qw( NextPermute );

sub find_perms { 
   my @rv;
   my @digits = sort split //, $_[0];
   do {
      push @rv, join '', @digits;
   } while NextPermute(@digits);
   return @rv;
}

say for find_perms(1151);

1115
1151
1511
5111
于 2012-06-28T05:06:38.007 に答える
4

@mobはあなたが尋ねた質問に答えましたが、私はあなたが道を進みたいかどうかわからないことを指摘したいと思いますsort uniq。本当に保存したくない要素をまだ保存しています。このような場合は、ハッシュを使用するのが最適です。

また、データが文字列である場合は、文字列を使用してください。からの出力はfind_perms(0345)あなたを驚かせるかもしれませんが、そうでfind_perms('0345')はありません。

最後Algorithm::Permute::permuteに非常に高速です。

これらの考慮事項を念頭に置いて、コードを次のように書き直します。

use strict; use warnings;
use Algorithm::Permute qw( permute );

my $uniq_perms = find_perms('115122345');

sub find_perms {
  my ($value) = @_;

  my @digits = split //, $value;
  my %uniq;

  permute { $uniq{join('', @digits)} = undef } @digits;

  return [ keys %uniq ];
}
于 2012-06-28T02:26:17.407 に答える