【先着1,000名様!】1,000円分をプレゼント!

「アルファベットを格納した配列」と「文字列長」を引数として与えると、全ての組み合せの文字列を返してくれるサブルーチンを定義するにはどうすればよろしいでしょうか?
「文字列長」が2や3の場合には以下のようにforeach文を入れ子にしていますが、「文字列長」の変化に対応できるようなサブルーチンを定義したいと考えます。

@cc = qw(a b c d); # アルファベットを格納した配列

「文字列長」が2の場合、
foreach my $c1 (@cc){
foreach my $c2 (@cc){
push(@str, $c1.$c2);
}
}

aa ab ac ad ba bb bc bd ca cb cc cd da db dc dd

「文字列長」が3の場合、
foreach my $c1 (@cc){
foreach my $c2 (@cc){
foreach my $c3 (@cc){
push(@str, $c1.$c2.$c3);
}
}
}

aaa aab aac aad aba abb abc abd aca acb acc acd ada adb adc add baa bab bac bad bba bbb bbc bbd bca bcb bcc bcd bda bdb bdc bdd caa cab cac cad cba cbb cbc cbd cca ccb ccc ccd cda cdb cdc cdd daa dab dac dad dba dbb dbc dbd dca dcb dcc dcd dda ddb ddc ddd

アドバイスをよろしくお願いします。

このQ&Aに関連する最新のQ&A

A 回答 (4件)

No.1です.


問題を誤読してました.
順列ではないですね.
問題は,文字が``N''種類あるときに
n桁の文字列を生成するということでした.

N進数のn桁の数をすべて列挙するのと同じなので
例えば以下のようにできます.

use strict;
use warnings;

use strict;
use warnings;

sub to_N_pos{
my ($n,$N,$L)=@_;
my @result;
for my $i (1..$L){
unshift @result, $n % $N;
$n = int($n / $N);
}
return $n ? () : @result;
}

sub listup{
my ($list,$L)=@_;
my @result;
my $N=scalar @{$list};
my $n=0;
while(my @r = to_N_pos($n,$N,$L)){
my $result;
for my $i (@r){
$result = $result.$list->[$i];
}
push @result, $result;
$n++;
}
return @result;
}

$,=", ";
print listup(['a'..'d'],2);

listupは
文字のリストのリファレンス,文字列の長さ
を引数として,
結果を配列として出力します.
    • good
    • 0
この回答へのお礼

迅速なアドバイスをいただき心より感謝申し上げます。

お礼日時:2007/07/15 04:03

試していないので無保証ですが, 再帰を使わずがんばってみる:


sub allstring(\@$) {
my ($alphabet, $count) = @_;
my @ans = ();
for my $i (1 .. $count) {
my @tmp = ();
for my $ch (@$alphabet) {
push @tmp, map { $_ . $ch } @ans;
}
@ans = @tmp;
}
@ans;
}
例:
$, = ',';
print allstring(['a' .. 'd'], 2), "\n";

この回答への補足

回答ありがとうございました。以下のエラーが出力されました
Type of arg 1 to main::allstring must be array (not single ref constructor) at Tacosan.pl line 15, near "2)"
Execution of Tacosan.pl aborted due to compilation errors.

補足日時:2007/07/15 04:12
    • good
    • 0

再帰呼び出しを使った方法です。



use strict;
my @cc = qw(a b c d);
my $n = 3; # 文字列長を指定
my @result; my @work = ();

search(@cc);

sub search {
my @list = @_;
foreach my $item (@list) {
if (@work == ($n - 1)) {
push @result, join('', @work, $item);
} else {
push @work, $item;
search(@list);
pop @work;
}
}
}

print "@result\n";
    • good
    • 0
この回答へのお礼

再帰呼び出しを使った方法は大変勉強になりました。ありがとうございました。

お礼日時:2007/07/15 04:06

http://faq.perl.org/perlfaq4.html
↑で
How do I permute N elements of a list?
という項目を見ましょう.

MJDの``Higher-Order Perl''という書籍では
4.3.1節にかなり詳細にでています.
コードそのものは http://hop.perl.plover.com/Examples/
の``permuteなんちゃらら''というものです.
何種類かあります.

一般的にやるとかなり複雑なコードになります.
    • good
    • 0

このQ&Aに関連する人気のQ&A

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

QExcelでの全通りの組み合わせ出力方法(文字列)

Excelについて全くの初心者で、教えて頂きたい質問があります。

Excelの文字列の全通りの組み合わせを出力がしたいのですが、その方法が分かりません。
例えばセルAに
・りんご
・みかん
・いちご

セルBに
・だいこん
・キャベツ
・トマト

があり、別のセルにその全通りの組み合わせを出力
(文字と文字の間はスペース)

りんご だいこん
りんご キャベツ
りんご トマト
みかん だいこん
みかん キャベツ
みかん トマト
いちご だいこん
いちご キャベツ
いちご トマト

この様に出来る方法はあるでしょうか?
また出来ればその裏(だいこん りんご)も出力したいと考えており、キーワードは3つまで出来るようになりたいです。

どなたかご存じでしたら、ぜひお教え下さい。
よろしくお願いします。

Aベストアンサー

A列B列は1行目からデータがあるものとします。
C列に転記するものとします。

以下の手順をおためしください。

1.Altキー+F11キーでVisualBasicEditorを呼び出します。

2.メニューから挿入、標準モジュールで出てきたコードウィンド(右側の白い広い部分)に以下のコードをコピペします。

Sub test01()
a = Cells(Rows.Count, "A").End(xlUp).Row 'A列最終行取得
b = Cells(Rows.Count, "B").End(xlUp).Row 'B列最終行取得
For i = 1 To a '1行からA列最終行まで繰り返し
For n = 1 To b '1行からB列最終行まで繰り返し
x = x + 1
Cells(x, "C") = Cells(i, "A") & " " & Cells(n, "B") 'C列に結合して転記
Next n
Next i
End Sub

3.Alt+F11キーでワークシートへもどります.

4.メニューから、ツール、マクロ、マクロで出てきたマクロ名(test01)を選択して実行

これでできます。
これがわかれば「裏」というのも簡単ですよね。
以上はVBAでの回答ですが、外していたらごめんなさい。

A列B列は1行目からデータがあるものとします。
C列に転記するものとします。

以下の手順をおためしください。

1.Altキー+F11キーでVisualBasicEditorを呼び出します。

2.メニューから挿入、標準モジュールで出てきたコードウィンド(右側の白い広い部分)に以下のコードをコピペします。

Sub test01()
a = Cells(Rows.Count, "A").End(xlUp).Row 'A列最終行取得
b = Cells(Rows.Count, "B").End(xlUp).Row 'B列最終行取得
For i = 1 To a '1行からA列最終行まで繰り返し
For n = 1 To b '1行...続きを読む


人気Q&Aランキング