アプリ版:「スタンプのみでお礼する」機能のリリースについて

$kana1[0][0] = "a";
$kana1[0][1] = "u";
$kana1[1][0] = "n";
$kana1[1][1] = "m";

という二次元配列があったときに

an
am
un
um

と出力するようなプログラムのアルゴリズム(?)を教えてほしいです。
簡単なようでforループでやるとうまくいかずwhileを使ってフラグ変数とか作ってやってみましたがどうも駄目です。

ヒントでも何でもいいのでよろしくお願いします!
むしろ二次元配列を使うのがダメなら言って下さるとありがたいです。

よろしくお願いします。

最終的には二次元配列の縦も横も任意の数のときにすべての組み合わせを出力できるようにならなければなりません。

A 回答 (5件)

#1 で書いたものにちょこっと手を入れれば終わりのはずなんだけどなぁ.


my @words = ('');
for my $array (@kana1) {
my @newwords;
for my $word (@words) {
push @newwords, map {"$word$_" } @$array;
}
@words = @newwords;
}
でダメかな?
なんかデジャヴなんだけど....
    • good
    • 0
この回答へのお礼

すいません!なんとか自力でやりました!
でもTacosanさんのソースとほとんど変わらないものになりましたのでとてもうれしいです。費やした時間はかなり違うと思いますが(笑)
@newwordを初期化すること(Tacosanさんは宣言することで初期化していらっしゃいますが)に気がつかずゴミが残る事態となってました。
本当にありがとうございます。まだまだ未熟なんでこれからもがんばりたいと思います。
ありがとうございまいした!!

お礼日時:2008/11/13 14:25

再帰呼び出しを使って、全部の組み合わせを生成しています。



use strict;
my @kana1 = (['a', 'u'], ['n', 'm'], ['ko', 'co']);
my @work =();
comb(0);

sub comb {
my $i = shift;
foreach my $str (@{$kana1[$i]}) {
push @work, $str;
if ($i == $#kana1) {
print join('', @work), "\n";
} else {
comb($i + 1);
}
pop @work;
}
}
    • good
    • 0

「すべての組み合わせ」というのがあいまいなので確認したいのですが,


$kana1[0][0] = "a";
$kana1[0][1] = "u";
$kana1[1][0] = "n";
$kana1[1][1] = "m";
$kana1[2][0] = "ko";
$kana1[2][1] = "co";
のときにはどのような結果が欲しいのでしょうか?

この回答への補足

anko
anco
amko
amco
unko
unco
umko
umco

の8種類です。

現状では
$kana1[0][0] = "a";
$kana1[0][1] = "u";
$kana1[1][0] = "n";
$kana1[1][1] = "m";
$kana1[2][0] = "ko";
$kana1[2][1] = "co";

my @newwords;
my @words;
my $word;
my $i;
my $j;
my $k;

@words = @{$kana1[0]};
#print "$words[0][0]";
$k = 0;
for $j (0..1) {
#print "words = @words\n";
for $i (0..$#words){
push @{$newwords[$i]}, map {"$words[$i]$_" } @{$kana1[$j+1]};
}

for $k (0..$#newwords){
print "@{$newwords[$k]}\n";
@words[$k] = @{$newwords[$k]};
print "k = $k\nwords = @words\n\n";
}

}
for $i (0..$#newwords){
print "*@{$newwords[$i]}\n";
}
となっています。現状の出力は
an am
k = 0
words = an u

un um
k = 1
words = an un

an am anko anco
k = 0
words = an un

un um unko unco
k = 1
words = an un

*an am anko anco
*un um unko unco

です。
あと少しのようですがリファレンスが使いこなせないので苦しいです。
個人的ボトルネックはpush関数は二次元配列に使えない
push @newwords[$i], map {"$words[$i]$_" } @{$kana1[$j+1]};
ができないことですね。リファレンスにするとなんとかなったのですが中で何が起こってるのか現在解析中です。
なにか申し訳ありません・・・。

補足日時:2008/11/12 18:08
    • good
    • 0

Perlの特徴的なコーディングは使わず,多くのプログラム言語でも通用するだろうコードの概略がどうなるかを知りたいというならこんな感じ。



@kana1 = (
['A', 'B', 'C', 'D']
, ['a', 'b', 'c', 'd']
, ['1', '2', '3', '4']
);
for ($i = 0; $i < 4; $i++) {
for ($j = 0; $j < 4; $j++) {
for ($k = 0; $k < 4; $k++) {
print $kana1[0][$i], $kana1[1][$j], $kana1[2][$k], "\t";
}
}
}

>最終的には二次元配列の縦も横も任意の数

ということで,その数があまりにも大きく多段forループをいちいち書いていられないというなら,次の手を考えましょうか。

この回答への補足

二次元配列が●行●列とわかっているならこれでできるのですが
それがわからない場合。forループの数が変わるのでその場でプログラムがソースコードを書くことはできないし・・・
printのところも行の数によって変わってくるし。
なんだかできそうでできないです。

補足日時:2008/11/12 12:08
    • good
    • 0
この回答へのお礼

これが概念ですね!ありがとうございます!!
printのところは特にわかっているようであいまいだったのでなんだかすっきりしました!

お礼日時:2008/11/12 12:07

え? for で簡単にできると思うんだけど.... どんなふうにやってみたんでしょうか?


例えば
my @words;
@words = @{$kana1[0]};
my @newwords;
for my $word (@words) {
push @newwords, map {"$word$_" } @{$kana1[1]};
}
@words = @newwords;
で @words に全ての組合せが入ってる... かな?

この回答への補足

$kana1[0][0] = "a";
$kana1[0][1] = "u";
$kana1[1][0] = "n";
$kana1[1][1] = "m";
$kana1[2][0] = "ko";
$kana1[2][1] = "co";

になるともちろんこのコードでは無理で改造が必要です。
そしていろいろやったのですが。

an am un um nko mco

の出力で沈黙です・・。
@newwordsの内容を$wordの位置に持ってきてさらにつなげていくのが理想だと思うのですが。そうすると@wordが永遠に増え続け無限ループに・・・。
もう少し頑張ってみますがずっと返信しないのは失礼なので現状報告させてもらいました。
また何かヒントがあれば教えて下さい。
よろしくお願いします。

補足日時:2008/11/12 11:55
    • good
    • 0
この回答へのお礼

ありがとうございます!
map関数とリファレンスの概念を全く知らなかったので理解するのに時間がかかりました。
map関数は非常に強力ですね!
これは使わない手はないです!!
ありがとうございます!!

お礼日時:2008/11/12 11:55

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