電子書籍の厳選無料作品が豊富!

perlでプログラムを作成中です。
作成したモノはうまく動かないので掲載できませんが、
どなたかお知恵を貸してください。

 入力文字列に対して
1をA、2をB、3をC
に置換するプログラムを作成中です。
ただし、全ての組み合わせを出力したいのです。
つまり、”213”と入力すると回答は、
B13
BA3
BAC
2A3
21C
2AC
B1C

と出力したいのです。
 プログラムとしては、入力文字列を1つずつを配列に入れて、それぞれの変換
をかけ、1つずつ組み合わせて出力しているのですが、どうもうまくいきません。
手法は特に固執してませんので、どの様な形でも結構です。
よろしくお願いします。

A 回答 (16件中11~16件)

#3,#4です。


以下のようにしてください。
-----------------------------------------------
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";
}
-------------------------------------------------------
尚、このソースは、「現在、この回答はサポートで内容を確認中です。」
を回避するために、@を!!に替えてあります。
このソースを実行時は、!!を@に読み替えてください。
実行結果は、以下の通りです。
入力してください->1A2x3y1B
16 通りの組合せがあります
1A2x3y1B
1A2x3yAB
1A2xCy1B
1A2xCyAB
1ABx3y1B
1ABx3yAB
1ABxCy1B
1ABxCyAB
AA2x3y1B
AA2x3yAB
AA2xCy1B
AA2xCyAB
AABx3y1B
AABx3yAB
AABxCy1B
AABxCyAB

このソースの最初の3行はあなたのソースを使用しています。
不明点は、補足ください。
    • good
    • 0

具体的にどういう入力ファイルを想定しているのかはっきりしないので、私が書いたコードをベースに話を進めますが。




> ・入力する文字列は、複数の文書みたいなモノを入力するので、
> いただいたプログラムのように、スペースで文字毎を1個ずつ区切れない。

これの意味するところが、1 2 3のようなものではなくて、123のようなものを考えているならば、@z = split(//, $_)としてやれば配列に変換できます。@zはそのまま先のコードで使用できます。


>・入力する文字列にはAやBも存在する。(それについては変換しない)

これも難しくないと思いますが。if文を置いて、変換対象の文字の場合のみ変換すればいいだけです。


>・変換文字は複数ある。
> %x = ~
> では、文字が多すぎるのです。

複数というのがいくつくらいかわかりませんが、なんらかの形でそれをコード内に記述する必要があります。それを連想配列でするか他の方法でするかだけの違いで、他の方法でできるのなら連想配列を使ってできない理由はないと思いますが。
もし、変換文字のマッピングが膨大でファイルであたえられているのであれば、それを読み込んで連想配列に変換してしまえばいいのでは。

いずれにしてもどういう入力形式を想定しているのかわからないと何とも言えません。実際の入力ファイルの一部を見せてください。

あと、配列に入っているようだが出力ができないということですが、それがこの質問の本質であるならば、具体的にどうやって出力していて、どういう出力になるのですか?
    • good
    • 0
この回答へのお礼

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

お礼日時:2015/01/03 23:41

#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

不明点があれば、補足してください。
    • good
    • 0

以下のようにしてください。


---------------------------------
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

不明点があれば、問い合わせください。
    • good
    • 0

> ./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
    • good
    • 0
この回答へのお礼

 早速の回答ありがとうございます。
プログラム見させてもらいました。

 条件が複雑だったので省略しましたが、このプログラムでは
ちょっと目的は達成できませんでした。
(早く作ってくださったのにごめんなさい)
条件としては
・入力する文字列は、複数の文書みたいなモノを入力するので、
いただいたプログラムのように、スペースで文字毎を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/;



このように作って、配列に入っているようではあるのですが、結果の
出力方法がうまくできないのです。
考え方が悪いのでしょうか??

 プログラムは全く異なってしまってもかまいません。
皆様の更なるご指導願います。

お礼日時:2014/12/31 23:54

#!/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
    • good
    • 0

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