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 sort列出了sort函数的三种语法:

sort SUBNAME LIST
sort BLOCK LIST
sort LIST

sort uniq @others匹配sort SUBNAME LIST排序的语法。它期望uniq是一个比较全局变量$aand的函数$b,并返回<0,0或以指示and>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 回答