• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:perlの文字列組み合わせ)

perlの文字列組み合わせ

このQ&Aのポイント
  • perlで文字列の組み合わせを作成するプログラムを作成中です。
  • 入力文字列に対して1をA、2をB、3をCに置換するプログラムを作成中です。
  • 組み合わせを全て出力するためのプログラムを作成しているがうまくいかない。

質問者が選んだベストアンサー

  • ベストアンサー
  • tatsu99
  • ベストアンサー率52% (391/751)
回答No.16

#13です。 >あと、変換前にカンマの使用があります。 変換前の文字列にカンマがあるということなので、 変換するファイルをタブ形式で定義したバージョンのスクリプトを 参考URLに書きました。(バージョン3 (CL.3)になります。)(カンマをタブに替えただけす。) ファイルの1行は 変換前文字列<tab>変換後文字列1<tab>変換後文字列2<tab>・・・変換後文字列N の形式で定義してください。 <tab>はタブ文字"\t"を意味します。 変換前文字列、変換後文字列の何れも カンマ(",")を変換文字として使用可能です。 例 ,1<tab>A<tab>B は ",1"をAに変換し、かつ ",1"をBに変換します。 >ちなみに前文はケース2の場合を想定してました。 定義の方法はケース1で行っていますが、 どうしても定義2でなければいけない理由があるのでしょうか? もし、そうであれば、その旨補足ください。 スクリプトをケース2の形式に対応させるのは、簡単にできます。

参考URL:
http://climbi.com/b/3383/3
oguogu01
質問者

お礼

 出来ました!理想とするプログラムができあがって理解することも出来ました。 長々とお付き合いありがとうございました。 ケース2にしたかった理由は、変換される文字より変換後の文字の方が少なかったので、 テキストファイルが見やすくなると思ったのです。 ですが、作ってみると、ケース1の方が便利な理由が出来たので、このまま行きます。 本当にありがとうございました。 他の方も回答してくださっているようなので、そちらの方も勉強してみようと思います!

すると、全ての回答が全文表示されます。

その他の回答 (15)

  • ybnormal
  • ベストアンサー率50% (220/437)
回答No.5

具体的にどういう入力ファイルを想定しているのかはっきりしないので、私が書いたコードをベースに話を進めますが。 > ・入力する文字列は、複数の文書みたいなモノを入力するので、 > いただいたプログラムのように、スペースで文字毎を1個ずつ区切れない。 これの意味するところが、1 2 3のようなものではなくて、123のようなものを考えているならば、@z = split(//, $_)としてやれば配列に変換できます。@zはそのまま先のコードで使用できます。 >・入力する文字列にはAやBも存在する。(それについては変換しない) これも難しくないと思いますが。if文を置いて、変換対象の文字の場合のみ変換すればいいだけです。 >・変換文字は複数ある。 > %x = ~ > では、文字が多すぎるのです。 複数というのがいくつくらいかわかりませんが、なんらかの形でそれをコード内に記述する必要があります。それを連想配列でするか他の方法でするかだけの違いで、他の方法でできるのなら連想配列を使ってできない理由はないと思いますが。 もし、変換文字のマッピングが膨大でファイルであたえられているのであれば、それを読み込んで連想配列に変換してしまえばいいのでは。 いずれにしてもどういう入力形式を想定しているのかわからないと何とも言えません。実際の入力ファイルの一部を見せてください。 あと、配列に入っているようだが出力ができないということですが、それがこの質問の本質であるならば、具体的にどうやって出力していて、どういう出力になるのですか?

oguogu01
質問者

お礼

回答ありがとうございます。 文字の置換がperlは簡単だったので、これでやればいいやと思ってヤケドしてますw 連想配列について、正月に勉強しましたが、これが中々難しい・・・ 私の持ってる本がお粗末なのかもしれませんが、”split”について詳しく書かれていなく、 ネット検索もしましたが、イマイチわかりずらかったので他の手法を模索中しております。

すると、全ての回答が全文表示されます。
  • tatsu99
  • ベストアンサー率52% (391/751)
回答No.4

#3です。 投稿した文章が 「現在、この回答はサポートで内容を確認中です。 ご迷惑おかけいたしますが、今しばらくお待ちください。」 となってしまったので、再度、投稿します。 前回のは、出力結果がソートされていなかったので、ソートするように変更しました。 以下のようにしてください。 ---------------------------------------- print "入力してください->"; chomp($inp1 = <STDIN>); $cont1 = length($inp1); @array = (); push @array,$inp1; %conv = ('1','A','2','B','3','C'); for ($i = 0; $i < $cont1;$i++){ $cont2 = scalar(@array); for ($j = 0; $j < $cont2; $j++){ $temp = $array[$j]; $char = substr($temp,$i,1); if (exists $conv{$char}){ substr($temp,$i,1) = $conv{$char}; push @array,$temp; } } } @array = sort(@array); printf("%d 通りの組合せがあります\n",scalar(@array)); foreach $str (@array){ print $str,"\n"; } ------------------------------------------------------- 最初の3行は、あなたのコードをそのまま使用しています。 以下、実行結果です。 入力してください->1A2B3C1x 16 通りの組合せがあります 1A2B3C1x 1A2B3CAx 1A2BCC1x 1A2BCCAx 1ABB3C1x 1ABB3CAx 1ABBCC1x 1ABBCCAx AA2B3C1x AA2B3CAx AA2BCC1x AA2BCCAx AABB3C1x AABB3CAx AABBCC1x AABBCCAx 不明点があれば、補足してください。

すると、全ての回答が全文表示されます。
  • tatsu99
  • ベストアンサー率52% (391/751)
回答No.3

以下のようにしてください。 --------------------------------- print "入力してください->"; chomp($inp1 = <STDIN>); $cont1 = length($inp1); @array = (); %conv = ('1','A','2','B','3','C'); push @array,$inp1; for ($i = 0; $i < $cont1;$i++){ $cont2 = scalar(@array); for ($j = 0; $j < $cont2; $j++){ $temp = $array[$j]; $char = substr($temp,$i,1); if (exists $conv{$char}){ substr($temp,$i,1) = $conv{$char}; push @array,$temp; } } } printf("%d 通りの組合せがあります\n",scalar(@array)); foreach $str (@array){ print $str,"\n"; } --------------------------------- 実行結果は以下の通り。 入力してください->1ABC2X2YZ3 16 通りの組合せがあります 1ABC2X2YZ3 AABC2X2YZ3 1ABCBX2YZ3 AABCBX2YZ3 1ABC2XBYZ3 AABC2XBYZ3 1ABCBXBYZ3 AABCBXBYZ3 1ABC2X2YZC AABC2X2YZC 1ABCBX2YZC AABCBX2YZC 1ABC2XBYZC AABC2XBYZC 1ABCBXBYZC AABCBXBYZC 不明点があれば、問い合わせください。

すると、全ての回答が全文表示されます。
  • ybnormal
  • ベストアンサー率50% (220/437)
回答No.2

> ./foo 2 3 1 2 2 3 1 2 2 3 1 B 2 3 A 2 2 3 A B 2 C 1 2 2 C 1 B 2 C A 2 2 C A B B 3 1 2 B 3 1 B B 3 A 2 B 3 A B B C 1 2 B C 1 B B C A 2 B C A B

oguogu01
質問者

お礼

 早速の回答ありがとうございます。 プログラム見させてもらいました。  条件が複雑だったので省略しましたが、このプログラムでは ちょっと目的は達成できませんでした。 (早く作ってくださったのにごめんなさい) 条件としては ・入力する文字列は、複数の文書みたいなモノを入力するので、 いただいたプログラムのように、スペースで文字毎を1個ずつ区切れない。 ・入力する文字列にはAやBも存在する。(それについては変換しない) ・変換文字は複数ある。 このため、いただいたプログラムのように %x = ~ では、文字が多すぎるのです。 それで、入力文字を@data[$cont2][$cont3]の配列に入れて後から printすれば良いと思っていたのです。 こんな感じに・・・ print "入力してください->"; chomp($inp1 = <STDIN>); $cont1 = length($inp1); for ($i = 0;$i < $cont1;$i++) { $chr =substr($inp1,$i,1); $data[$cont2][$cont3] = $chr; #入力文字列の配列代入 $cont3 = $cont3+1; $chr =~ s/1/A/; $chr =~ s/2/B/; $chr =~ s/3/C/; ・ ・ ・ このように作って、配列に入っているようではあるのですが、結果の 出力方法がうまくできないのです。 考え方が悪いのでしょうか??  プログラムは全く異なってしまってもかまいません。 皆様の更なるご指導願います。

すると、全ての回答が全文表示されます。
  • ybnormal
  • ベストアンサー率50% (220/437)
回答No.1

#!/usr/bin/perl %x = ("1", "A", "2", "B", "3", "C"); foreach (@ARGV){ push (@z, $_); } $cnt = scalar(@z); $len = 2**$cnt; for($i=0;$i<$len;$i++){ @tmp = @z; @s = split(//, sprintf("%0${cnt}b", $i)); $c = 0; foreach (@s){ if($_ eq '1'){ $orig = $tmp[$c]; $tmp[$c] = $x{$orig}; } $c++; } print "@tmp\n"; } > ./foo 2 1 3 2 1 3 2 1 C 2 A 3 2 A C B 1 3 B 1 C B A 3 B A C > ./foo 1 2 3 1 2 3 1 2 C 1 B 3 1 B C A 2 3 A 2 C A B 3 A B C

すると、全ての回答が全文表示されます。

関連するQ&A