0

特定の電話番号に対して可能なすべての単語を生成する簡単な perl スクリプトを書きたいと思います。

私は配列の定義から始めました:

my @nums = (
    ['0'],
    ['1'],
    ['2', 'a', 'b', 'c'],
    ['3', 'd', 'e', 'f'],
    ['4', 'g', 'h', 'i'],
    ['5', 'j', 'k', 'l'],
    ['6', 'm', 'n', 'o'],
    ['7', 'p', 'q', 'r', 's'],
    ['8', 't', 'u', 'v'],
    ['9', 'w', 'x', 'y', 'z']
);

最終的なスクリプトは、次の出力を生成する必要があります。

$ num2word 12
12
1a
1b
1c

$ num2word 213
213
21d
21e
21f
a13
a1d
a1e
a1f
b13
b1d
b1e
b1f
c13
c1d
c1e
c1f

仕事の大部分を実行できるモジュールを探しています (List::Permutor のようなもので、このタスクに適していないようです)。

ヒントはありますか?ありがとう!

4

7 に答える 7

4

私たち自身の @brian d foy が彼のSet::CrossProductモジュールでこの問題を解決しました。

use Set::CrossProduct;
my $iterator = Set::CrossProduct->new(
    [ [ qw(8 t u v) ], [ qw(0) ], [ qw(7 p q r s) ] ] );
print "@$_\n" for $iterator->combinations;

出力:

8 0 7
8 0 p
8 0 q
8 0 r
8 0 s
t 0 7
t 0 p
t 0 q
t 0 r
t 0 s
u 0 7
u 0 p
u 0 q
u 0 r
u 0 s
v 0 7
v 0 p
v 0 q
v 0 r
v 0 s
于 2013-06-17T15:03:34.913 に答える
3

これはあなたが求めることを行います。

use strict;
use warnings;

my @nums = (
    [ qw/ 0 / ],
    [ qw/ 1 / ],
    [ qw /2 a b c / ],
    [ qw /3 d e f / ],
    [ qw /4 g h i / ],
    [ qw /5 j k l / ],
    [ qw /6 m n o / ],
    [ qw /7 p q r s / ],
    [ qw /8 t u v / ],
    [ qw /9 w x y z / ],
);

list_matching('12');
list_matching('213');

sub list_matching {

  my ($num) = @_;
  my @num = $num =~ /\d/g;
  my @map = (0) x @num;

  do {
    print join('', map { $nums[$num[$_]][$map[$_]] } 0 .. $#num), "\n";
    my $i = $#map;
    while ($i >= 0) {
      last if ++$map[$i] < @{ $nums[$num[$i]] };
      $map[$i--] = 0;
    }
  } while grep $_, @map; 
}

出力

12
1a
1b
1c
213
21d
21e
21f
a13
a1d
a1e
a1f
b13
b1d
b1e
b1f
c13
c1d
c1e
c1f
于 2013-06-17T13:21:59.087 に答える
0
use strict;
use warnings;
my @nums = (
    ['0'], ['1'], ['2', 'a', 'b', 'c'],
    ['3', 'd', 'e', 'f'], ['4', 'g', 'h', 'i'],
    ['5', 'j', 'k', 'l'], ['6', 'm', 'n', 'o'],
    ['7', 'p', 'q', 'r', 's'],  ['8', 't', 'u', 'v'],
    ['9', 'w', 'x', 'y', 'z']);

num2word(12);
num2word(213);

sub num2word {
    my ($i, $n, $t) = ($_[0]=~/(.)(.*)/, $_[1]);
    for (@{$nums[$i]}) {
        print "$t$_\n" and next if !length($n);
        num2word($n, defined $t ? $t.$_ : $_);
    }   
}
于 2013-06-18T07:07:54.697 に答える