perlの配列を使った、網羅的な文字列生成について質問です。
ある特定の種類の文字のレパートリをつかった、n文字の文字列すべての組み合わせを生成したいと考えています。
例えば文字 A, B, C の三種類をつかった2文字の文字列なら
AA,AB,AC,BA,BB,BC,CA,CB,CC
3x3 =9 種類というふうになります。
n=2の場合、
@array = qw(A B C);
foreach $moji(@array){
$moji1 = $moji;
foreach $moji(@array){
$moji2 = $moji;
$mojiretu = $moji1.$moji2;
push (@mojiretuset , $mojiretu );
}}
print @mojiretuset;
とするとforeachをふたつ重ねることで文字の組み合わせすべてを生成できました。
問題なのは、問題なのは、今私がしたいのは文字数nを(ループの)外から指定して(例えば$mojisuu = 6 などとして)n文字の場合の網羅的な文字の組み合わせを生じさせることなのです。
毎回自分でforeachを必要なだけ重ねて書き直す、というのは現実的ではありませんし、n個のforeachの入ったperlのコードを書くコードというのも避けたいのです。
文字数を自由に後から設定して、特定の配列から網羅的な組み合わせを生じさせるにはどのようなコードを書けばよいでしょうか?
No.2ベストアンサー
- 回答日時:
以下のコードでできると思います。
@resultに入っている文字列の末尾に1文字ずつ足しています。
(最初はforeachを使って書いたけど、途中でmap使った方がすっきりすると気づいた。)
--------------------------------------------------
use strict;
sub str_comb(\@$){
my @char_list = @{$_[0]}; #第1引数: 構成文字群
my $length = $_[1]; #第2引数: 文字列長
my @result = @char_list; #結果を格納する配列
for(my $i=1; $i<$length; $i++){
@result = map {
my $temp=$_;
map {$temp.$_} @char_list;
} @result;
}
return @result;
}
my @array = qw(A B C D);
my @result = str_comb(@array,5);
print join(",",@result);
--------------------------------------------------
別のやり方でも書いてみたのでそれも載せてみます。
人によってはこっちの方が分かりやすいと感じるかも?
(あともしかしたら少し速いかも。)
--------------------------------------------------
sub str_comb2(\@$){
my @char_list = @{$_[0]};
my $length = $_[1];
my $char_num = @char_list;
my @result = ();
for(my $i=0; ; $i++){
my $i_temp=$i;
my $str_temp="";
for(my $j=0; $j<$length; $j++){
$str_temp .= $char_list[$i_temp % $char_num];
$i_temp = int($i_temp / $char_num);
}
if($i_temp != 0){last;}
push(@result,$str_temp);
}
return @result;
}
--------------------------------------------------
別の書き方を教えていただき、ありがとうございます。
人によって色々と違いが出てくるものですね。その辺、perlならではなのでしょうか。複数のコードを見比べることでより深く勉強できそうです。
有難うございました。
No.4
- 回答日時:
> #3
> 最初の方法では, for は
> for my $i (1 .. $length)
> の方が綺麗ではないでしょうか>#2.
たしかに、範囲演算子がある言語ではそっちの方がきれいですね。
C言語がメインなもので、しばらくperlさわってないと
ついfor(;;)のスタイルで書いてしまいます。
No.1
- 回答日時:
こんちは
ループをまわすたびに
現在の配列のすべての要素に、@arrayの内容をこつこつとくっつけてみました
@array = qw(A B C);
$n = 3;
@mojiretuset = @array;
foreach $i (2..$n) {
@tmp = ();
foreach $elm (@mojiretuset) {
push(@tmp, (map $elm.$_, @array));
}
@mojiretuset = @tmp;
}
print join ",", @mojiretuset;
有難うございました。
コードを実行したところ、網羅的な文字列が出てきました。
foreach $i (2..$n) {
や
$temp
を使うあたりが自分では考え付きませんでした。ループの制御というのは難しいですが、同時にとてもおもしろいものですね。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Java Javaの問題なのですが、「3文字以上の英数字文字列を入力し、文字列の中に文字(9)が出てくるまでの 1 2023/06/06 18:55
- PHP PHPの構文で間違えが分からない 5 2022/07/11 16:38
- PHP SQLとPHPの連結方法がわからないのでアドバイスお願い致します 1 2022/07/12 12:16
- オープンソース 【ChatGTPのオープンソースソフトウェアを解析したことがある方、教えてくださ 2 2023/03/08 18:57
- その他(コンピューター・テクノロジー) googleスプレッドシートでカッコ内の文字数をカウントしたい 1 2023/01/17 15:52
- Excel(エクセル) エクセルで文字列と数字が混在する列に書式設定したい。 3 2022/12/19 09:11
- Visual Basic(VBA) VBA初心者です 検索した数字の行に色をつける 5 2023/02/13 14:22
- Java Java 南京錠 2 2023/02/04 11:46
- Visual Basic(VBA) 特定の文字を簡単な操作で半角スペースに変換するか削除したい 2 2022/11/01 10:35
- Visual Basic(VBA) VBA シート上にドロップダウンリストを作り、予め指定値をセットしたいのですが 1 2023/03/25 15:15
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
乱数と順列と組み合わせ
-
grep関数を用いた複数行からの抽出
-
半角文字の縦書き表示
-
画面を強制的に再描画させる方法
-
VBAのautofilter、criteriaの配...
-
VBAで3秒だけ時間を止めたい
-
vba
-
リストボックスに縦スクロール...
-
二次元配列のインデックスについて
-
二次元配列における要素数のは...
-
Escキーを押すと、中断する時と...
-
perlで2次元配列をサブルーチ...
-
DoEventsが必要な理由について
-
ということですか 他に固定りよ...
-
DOSコマンドのループ内のTIMEコ...
-
Application.OnTime の使い方
-
Visual BasicのUserFormが閉じ...
-
流れ図(フローチャート)が分か...
-
可変長配列を、動的確保した固...
-
ListBox 複数選択 で オートフ...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
perlでファイルの拡張子を除い...
-
python質問
-
DBIを使ってのデータの取り出し...
-
grep関数を用いた複数行からの抽出
-
データベースから取得したデー...
-
配列内定義サブルーチン呼び出し
-
C言語の関数ポインタのイメージ...
-
桁数指定と四捨五入
-
アルファベットn文字の組み合わ...
-
index関数で複数個抜き出す
-
Perl 戻り値の型の判定って出来...
-
二桁の数字からなる配列数10...
-
サブルーチンと繰り返し処理を...
-
ソート時同じ値がある場合、表...
-
ファイルの最後の行から表示さ...
-
半角文字の縦書き表示
-
配列やハッシュで中身が同じか...
-
乱数と順列と組み合わせ
-
ハッシュ内の各値部分に配列を...
-
正規表現に関する質問
おすすめ情報