![](http://oshiete.xgoo.jp/images/v2/pc/qa/question_title.png?8acaa2e)
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ランキング
-
桁数指定と四捨五入
-
画面を強制的に再描画させる方法
-
Can't use string ("0") as an ...
-
csh foreachで「*」でエラ...
-
GIFアニメをループさせたくない
-
UWSCの終了の仕方
-
perlで配列の要素が空なのを知...
-
多重ループの抜けだし方
-
アセンブラによるウェイト(WAIT...
-
VBのReturnの使い方
-
フラグについて
-
DOSコマンドのループ内のTIMEコ...
-
ボタンが押された時にループか...
-
csv形式のデータの一部を削除し...
-
CSVファイルの特定の行だけを読...
-
Escキーを押すと、中断する時と...
-
チェックデジットについて
-
CやJAVa,Rubyなどプログラミン...
-
Excel(VBA)で配列の要素数を...
-
イベントの発生を待つ
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
index関数で複数個抜き出す
-
perlで2つの配列を比較する方...
-
perlでファイルの拡張子を除い...
-
[Perl]長すぎるif文を簡単にしたい
-
grep関数を用いた複数行からの抽出
-
桁数指定と四捨五入
-
配列やハッシュで中身が同じか...
-
組み合わせを作るアルゴリズム
-
複数の配列の要素を繰り返し処...
-
正規表現に関する質問
-
データベースから取得したデー...
-
ソート時同じ値がある場合、表...
-
非共通要素を抜き出す
-
配列に入った変数を二度使いたい
-
C言語の関数ポインタのイメージ...
-
Perl 戻り値の型の判定って出来...
-
QNo.3258883データベースから取...
-
ループ中でのmy宣言と処理速度
-
Perlについて教えてください!
-
配列から網羅的な文字列を生成...
おすすめ情報