![](http://oshiete.xgoo.jp/images/v2/pc/qa/question_title.png?a65a0e2)
こんにちは!
学校のJavaの例題で、四つの重複しないマークの順列を全て書き出す
メソッドを作るっていう問題が出ました!
ネットを見ながらで、何とか再起を使って吐き出すのは組めたんですけど、
先生に見せたら、『まだ再起は教えていない』って言われて、合っているのに
NGを食いました><
どうやら、for文の入れ子と配列の要素の入れ替えだけでできるらしいんですが、
どうやって書けばいいのかが解りません…。
パターンの数を出すのは解るんです。4*3*2ですしね。でも、再起を
使っている例をとっても、どうしてこのソースですべての順列が出せるのか、
その仕組みが解りません。
ソースだけじゃなくて、どうして全部の順列が出せるのか、その仕組みも併せて
教えてください!!
中身は、こんな感じです。
// 順列を出す配列
private int[] arr={0,1,2,3};
private void permutation(int n)
{
if (n < 4)
{
// n以上4未満
for (int i = n; i < 4; i++)
{
if (n != i)
{
this.swap(n, i);
}
// 再起呼び出し
permutation(n + 1);
if (n != i)
{
this.swap(n, i);
}
}
}
else
{
System.out.println(this.arr[0] + "," + this.arr[1] + "," + this.arr[2] + "," + this.arr[3]);
}
}
private void swap(int a,int b)
{
int c = this.arr[a];
this.arr[a] = this.arr[b];
this.arr[b] = c;
}
何もわからなくてゴメンナサイ。
よろしくお願いします^^
A 回答 (4件)
- 最新から表示
- 回答順に表示
![](http://oshiete.xgoo.jp/images/v2/common/profile/M/noimageicon_setting_14.png?a65a0e2)
No.4
- 回答日時:
以下のようにしてください。
------------------------------------------------
// 順列を出す配列
private char[] arr={'A','B','C','D'};
private void permutation(int n)
{
for (int i = 0; i < 4; i++)
{
if (i != 0)
{
this.swap(0,i);
}
for (int j = 1; j < 4; j++)
{
if (j != 1)
{
this.swap(1,j);
}
for (int k = 2; k < 4; k++)
{
if (k != 2)
{
this.swap(2,k);
}
System.out.println(this.arr[0] + "," + this.arr[1] + "," + this.arr[2] + "," + this.arr[3]);
if (k != 2)
{
this.swap(2,k);
}
}
if (j != 1)
{
this.swap(1,j);
}
}
if (i != 0)
{
this.swap(0,i);
}
}
}
private void swap(int a,int b)
{
char c = this.arr[a];
this.arr[a] = this.arr[b];
this.arr[b] = c;
}
---------------------------------------------------------------
これは、再帰を使用しない方法です。
以下、実行結果です。
A,B,C,D
A,B,D,C
A,C,B,D
A,C,D,B
A,D,C,B
A,D,B,C
B,A,C,D
B,A,D,C
B,C,A,D
B,C,D,A
B,D,C,A
B,D,A,C
C,B,A,D
C,B,D,A
C,A,B,D
C,A,D,B
C,D,A,B
C,D,B,A
D,B,C,A
D,B,A,C
D,C,B,A
D,C,A,B
D,A,C,B
D,A,B,C
今回、判り易くするために、A,B,C,Dの文字を使用していますが、0,1,2,3を
使いたいのであれば、
private char[] arr={'A','B','C','D'}; を
private int[] arr={0,1,2,3}; に戻します。
更に void swapメソッド中の
char c = this.arr[a]; を
int c = this.arr[a]; に戻します。
そうすれば、あなたが提示したソースと同じ結果が得られます。
それで、何故、上記の結果が得られるかということですが、以下のようになります。
1.A,B,C,Dの文字を出力するとき、1番目の文字を選ぶ。
これは、for(int i=0;i < 4;i++)のループです。
これは、i=0の場合は、そのままで良いが、以外の場合は、最初の文字とその処理中の文字を入れ変える必要があります。
つまり、Bの文字を処理するときは、A,B,C,DをB,A,C,Dのように置き換えます。
同様に、Cの文字を処理するときは、A,B,C,DをC,B,A,Dのように置き換えます。
同様に、Dの文字を処理するときは、A,B,C,DをD,B,C,Aのように置き換えます。
そして、ループの最後で、置き換えた文字を元に戻しておきます。
2.A,B,C,Dの文字を出力するとき、2番目の文字を選ぶ。
これは、for(int j=0;j < 4;j++)のループです。
これは、j=1の場合は、そのままで良いが、以外の場合は、2番目の文字とその処理中の文字を入れ変える必要があります。
つまり、Cの文字を処理するときは、A,B,C,DをA,C,B,Dのように置き換えます。
同様に、Dの文字を処理するときは、A,B,C,DをA,D,C,Bのように置き換えます。
そして、ループの最後で、置き換えた文字を元に戻しておきます。
3.A,B,C,Dの文字を出力するとき、3番目の文字を選ぶ。
これは、for(int k=2;k < 4;j++)のループです。
これは、k=2の場合は、そのままで良いが、以外の場合は、3番目の文字とその処理中の文字を入れ変える必要があります。
つまり、Dの文字を処理するときは、A,B,C,DをA,B,D,Cのように置き換えます。
そして、ループの最後で、置き換えた文字を元に戻しておきます。
4.ここは、arrの並べ替えた文字を印字する箇所です。
System.out.println(・・・省略・・・)
不明点があれば、補足してください。
ありがとうございます!
少しわかりました!
つまり、一つのループごとにループの初めの数とループしている数を入れ替える
わけですね!
入れ替えというから、二重にループさせてそのiとjを入れ替えるのだとばかり
思っていました!
あと、どうして入れ替えた後で一度戻しているのか、
勿論、一つ一つ指でなぞりながらでもおっていけばその通りには
なるんですけど、なんか戻していたら、一行おきにもとの並び方に
戻ってしまいそうな気がします。
なので、コードはやってることは解るんですけど、『良くバラバラに
順列ができるなぁ』と思ってしまうわけです。
いくらサンプル通りに組んでうまくいっても、『どうしてそうなるのか』が
解らないと気持ち悪いですよね。
ありがとうございました!いただいたコードをもとに、もう一度試してみます!
No.3
- 回答日時:
> 解らない人に教えるわけですから、自分が解っているからって
> いい加減な回答はしないでくださいね^^
再帰をご理解いただいているようなのでご理解いただけると判断したのですが
質問者様の理解力を見誤ったようで失礼しました。
閑話休題
要素が数字だと紛らわしいので文字にします。
arr={"A","B","C","D"};
4重ループで得られた数字が、外側のループから順に2,3,1,0だとすると
この要素番号で順にaryから要素を取り出して順に並べます。
arr1[0] = arr[2];
arr1[1] = arr[3];
arr1[2] = arr[1];
arr1[3] = arr[0];
結果としてarr1 = {"C","D","B","A"}になります。
これを4重ループで得られる重複しない組み合わせで実行すれば良いわけです。
これでご理解いただけましたでしょうか?
…多分、私と同じ人もこれを見ただけじゃ解らないと思いますよ。
>4重ループで得られた数字が、外側のループから順に2,3,1,0だとすると
>この要素番号で順にaryから要素を取り出して順に並べます。
これだと、実際に『入れ替え』をやっていないし。
ソースにもswapって書いてあるわけですし、自分勝手な解釈で答えられても…
ねぇ?って思います。
siffon9さんは、多分『人に何かを教える』のは苦手なのではないでしょうか。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# c言語 プログラムのエラー 1 2023/02/11 20:31
- JavaScript EasyUIのSubGrid(jquery)におけるObjectに入れた連想配列について 1 2022/05/02 11:21
- C言語・C++・C# c言語 int temp = 0; if(isdigit(arr[i])){ temp=arr[i] 2 2022/03/27 01:44
- C言語・C++・C# int temp = 0; if(isdigit(arr[i])){//文字が数字であれば(0~9) 1 2022/03/27 01:37
- その他(プログラミング・Web制作) 十進BASICでの再帰についての質問です。 2 2022/11/18 09:17
- Excel(エクセル) excel vbaの配列なんですが・・・ 1 2022/12/26 18:50
- PHP c言語 文字 - '1'+26 3 2022/03/26 20:58
- JavaScript 配列の1要素を代入した変数を使って元の配列要素を削除できるか 1 2023/07/28 03:34
- C言語・C++・C# c言語の問題です 課題1 (二分探索木とセット) 大きさ size の配列 array を考える。す 2 2023/01/10 21:08
- C言語・C++・C# C言語プログラム変更 2 2022/12/21 15:03
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・一番好きなみそ汁の具材は?
- ・泣きながら食べたご飯の思い出
- ・「これはヤバかったな」という遅刻エピソード
- ・初めて自分の家と他人の家が違う、と意識した時
- ・いちばん失敗した人決定戦
- ・思い出すきっかけは 音楽?におい?景色?
- ・あなたなりのストレス発散方法を教えてください!
- ・もし10億円当たったら何に使いますか?
- ・何回やってもうまくいかないことは?
- ・今年はじめたいことは?
- ・あなたの人生で一番ピンチに陥った瞬間は?
- ・初めて見た映画を教えてください!
- ・今の日本に期待することはなんですか?
- ・集中するためにやっていること
- ・テレビやラジオに出たことがある人、いますか?
- ・【お題】斜め上を行くスキー場にありがちなこと
- ・人生でいちばんスベッた瞬間
- ・コーピングについて教えてください
- ・あなたの「プチ贅沢」はなんですか?
- ・コンビニでおにぎりを買うときのスタメンはどの具?
- ・おすすめの美術館・博物館、教えてください!
- ・【お題】大変な警告
- ・洋服何着持ってますか?
- ・みんなの【マイ・ベスト積読2024】を教えてください。
- ・「これいらなくない?」という慣習、教えてください
- ・今から楽しみな予定はありますか?
- ・AIツールの活用方法を教えて
- ・最強の防寒、あったか術を教えてください!
- ・歳とったな〜〜と思ったことは?
- ・モテ期を経験した方いらっしゃいますか?
- ・好きな人を振り向かせるためにしたこと
- ・スマホに会話を聞かれているな!?と思ったことありますか?
- ・それもChatGPT!?と驚いた使用方法を教えてください
- ・見学に行くとしたら【天国】と【地獄】どっち?
- ・これまでで一番「情けなかったとき」はいつですか?
- ・この人頭いいなと思ったエピソード
- ・あなたの「必」の書き順を教えてください
- ・14歳の自分に衝撃の事実を告げてください
- ・人生最悪の忘れ物
- ・あなたの習慣について教えてください!!
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
do-while文が禁止される理由
-
n重のfor文にするには?
-
エクセルVBAで Do While (1)って?
-
Excel VBAで年度をまたぐ期間の...
-
C++ DirectX カーソルの移動処...
-
break文でループを一気に抜ける...
-
for文while文の無限ループの違...
-
入力した数値を倍々するプログラム
-
C言語 for文を使った一例について
-
C言語のプログラムみてください...
-
猫でもわかる、がわかりません。
-
H8/3048マイコンAD/DA変換について
-
C言語forループが完結した場合...
-
if文の中にfor文なのか、for文...
-
C言語 数字を削除する関数
-
C++のvolatileについて
-
Cプログラムが終了しない
-
C言語の関数の戻り値がおかしい?
-
Aの値からBの値を除するとは??
-
エクセルで可視セルにのみ値貼...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
do-while文が禁止される理由
-
break文でループを一気に抜ける...
-
ループを途中で抜けたいのですが。
-
Excel VBAで年度をまたぐ期間の...
-
C言語forループが完結した場合...
-
For文の終了値を関数にしても問...
-
プログラムで関数は使わない方...
-
Cプログラムが終了しない
-
for文while文の無限ループの違...
-
入力した数値を倍々するプログラム
-
if文を使わずに奇数・偶数を判断
-
UWSCにてある一定の動作を無限...
-
入力した文字列から母音だけを...
-
エクセルでC言語のfor文と同じ...
-
猫でもわかる、がわかりません。
-
PIC のプログラムについて ど...
-
C言語、whileループを抜け出す...
-
VBScriptでSQLに接続し、CSV出...
-
エクセルVBAで Do While (1)って?
-
ループの特定入力終了
おすすめ情報