- ベストアンサー
配列をランダムに並び替えてもとに戻したい
C言語のプログラミングで質問があります。 ある配列をランダムに並び替えて、ある処理をした後にまた元の配列の順番に戻したいと考えているのですが、どのように組めばいいのか解りません。 回答をお願い致します。
- みんなの回答 (11)
- 専門家の回答
質問者が選んだベストアンサー
ポインタを使えばよいのではないでしょうか? 並び替えたい配列を int A[100] と仮定して、 アドレスを入れておく一時的な配列、int *B[100]を用意して、 for( i = 0; i < 100; i++ ) B[ i ] = &A[ i ]; としておきます。 あとは、B[]の要素をランダムに入れ替え、 何らかの処理を *B[ i ] に対して行えばよいですね。 これであれば、元のA[]の内容は変わりますが、 順番は一切変わりませんので、面倒な操作は発生しません。
その他の回答 (10)
- akayoroshi
- ベストアンサー率50% (46/91)
ある配列(zとします)と同じサイズのint配列を2つ(xとyとします)用意します。 配列のサイズと同じだけ乱数を生成させて配列xの要素に入れます。 配列yの要素には値0から(zのサイズ-1)までの整数値を入れておきます。 xの要素が昇順(降順でもかまわない)に並ぶように、配列z, y, xをソートします。これで、元の配列はランダムに並び替わります。 ある処理が終わったら、配列yの要素が昇順並ぶように、配列zとyを並べ替えます。これで元の配列の順番に戻ります。
- yama5140
- ベストアンサー率54% (136/250)
>ある配列をランダムに並び替えて、 たとえば、 cHoge[ 0 ] = 0x11; cHoge[ 1 ] = 0x03; cHoge[ 2 ] = 0x02; cHoge[ 3 ] = 0x12; cHoge[ 4 ] = 0x24; を cHoge[ 0 ] = 0x03; ( [ 1 ] ) cHoge[ 1 ] = 0x24; ( [ 4 ] ) cHoge[ 2 ] = 0x11; ( [ 0 ] ) cHoge[ 3 ] = 0x02; ( [ 2 ] ) cHoge[ 4 ] = 0x12; ( [ 3 ] ) と ☆ランダム?に並び替え(入れ換え?)、さらに cHoge[ 0 ] = 0x02; cHoge[ 1 ] = 0x25; cHoge[ 2 ] = 0x10; cHoge[ 3 ] = 0x03; cHoge[ 4 ] = 0x13; と ☆ある処理(例えば、奇数ならばデクリメント、偶数ならばインクリメント)をしたのち、 cHoge[ 0 ] = 0x10; cHoge[ 1 ] = 0x02; cHoge[ 2 ] = 0x03; cHoge[ 3 ] = 0x13; cHoge[ 4 ] = 0x25; と ☆元の配列の順番に戻す、ということですね。 ★元の配列の「順番」に戻すことが重要で、配列の「値」は、元のままである必要はないのですよね?。 → No.3 さんの「配列のコピー」ではダメ、ということ?。 ★上の例のように、「処理」内容によっては、「ランダムに並び替え」てから、の必要がない場合も、ありですね?。 → No.6 さんの「配列を並び替えずにランダムな処理」どころか「・・順番どおりの処理」で十分と・・?。 ★それとも、処理の「順番」が、「処理内容」に関わってくるのでしょうか?。 → No.6 さんの ある処理( hoge[ order[i] ] ); → ある処理( hoge[ order[i] ], order[i] ); とする必要がある処理内容なのでしょうか?。 ★それとも、処理の対象は、「配列」そのものではない、ですか?。 以上、(具体的な処理例を、上部のように)補足願います。 >どのように組めばいいのか解りません。 「並び替え」時に用いる変数(順番)を、別の「配列」に順番に記憶(代入)しておくだけ、のような・・。 というか、「並び替え」までのプログラムが、できていない?。
- asuncion
- ベストアンサー率33% (2127/6289)
>#7さん コピーを作ったのだから、おっしゃるとおり 書き戻す必要はないですね。 私は無駄なことを書いてしまいました。
>>5 処理の結果、要素内に変化がある んじゃないですかね 例えば全要素に+1して順番を戻すなら元の配列で上書きしたらダメですし というかそれだとx[]に戻さずy[]に対してランダム&処理&廃棄、でいいような
- ko_kinta
- ベストアンサー率39% (43/109)
Cで配列を並び替えるのはあまり効率が良くないと思いますが。 「ある処理」を行うランダムな順番を別の配列に取得して、その順番に沿って「ある配列」を処理するのではいけませんか。 hoge[n]; /* ある配列 */ order[n]; /* 処理順 */ /* order[n]に0~(n-1)のランダムな一意の数値を格納 */ ... for(i = 0; i < n; i++) { ある処理(hoge[order[i]]); } これなら配列を並び替えずにランダムな処理が行えます。
- asuncion
- ベストアンサー率33% (2127/6289)
ある配列をx[]とする。 x[]の全要素を別の配列y[]にそっくりコピーする。 この時点で、全く同じ内容のx[]とy[]が存在する。 x[]の内容をランダムに並べ替える。 ある処理を行なう。 y[]の全要素をx[]にそっくりコピーする。 これで、 >ある配列をランダムに並び替えて、ある処理をした後にまた元の配列の順番に戻したい これが実現できていませんか?
- asuncion
- ベストアンサー率33% (2127/6289)
>「コピーしておいた配列から元に戻す」 >とは具体的にどのようなことをすればよいのですか? >ある配列をランダムに並び替えて ここで書かれている「ある配列(例えばx[])」を別の配列(例えばy[])にコピーすることはできますか? もしもそれができるのであれば、その逆の操作、つまり y[]の全要素をそっくりそのままx[]にコピーすればよいのです。
- asuncion
- ベストアンサー率33% (2127/6289)
別の配列にコピーしておいてからランダムに並び替えて、 ある処理をした後で、コピーしておいた分から 元に戻せばいいのではないでしょうか。
お礼
なるほど。 「コピーしておいた配列から元に戻す」 とは具体的にどのようなことをすればよいのですか?
- ESE_SE
- ベストアンサー率34% (157/458)
最近C系で組まずVBばかりなのでコーディングは無理ですが考え方だけ。 初期の配列→ランダムに順序変更→処理→初期の配列に順序変更 ということですね。 初期の配列であればhoge[i]にi番目のデータが格納されていますが、 順序変更してしまうと初期のi番目の順序が失われるのでこれを格納しておく必要があります。 なのでこんな形はどうでしょうか。 初期の配列hoge[i]とは別に配列 hogehoge[3,]を用意 →hogehoge[0,i]=i //このデータ行が初期配列でi番目であることを格納 hogehoge[1,i]=random() //乱数を発生。後でこの列でソートする hogehoge[2,i]=hoge[i] //初期配列のデータを格納 →hogehoge[]をhogehoge[1,i]の要素でソート →hogehoge[2,i]に処理 →hogehoge[]をhogehoge[0,i]の要素でソート これで可能かと思いますが・・・ ソートは関数を自作するなりライブラリを使用するなり。 こんなところでしょうか?
- makotyan0
- ベストアンサー率41% (5/12)
ん~、もうちょっと具体的に説明しないとわかんないなぁ…。 そういった質問はこちらでしたら結構解決するかもしれませんよ。 http://dixq.net/board/ ↑C言語何でも質問掲示板 結構いろんなプログラマーの方がここで問題を解決させたりしています。僕も結構ここでお世話になっていますよ。
- 参考URL:
- http://dixq.net/board/
お礼
お返事をありがとうございます。 私の説明不足だったようで、コピーすることは可能なのですが、私がやりたい操作はESE SEさんのおっしゃる通り、 初期の配列→ランダムに順序変更→処理→初期の配列に順序変更 ということです。 何か解りやすく、簡単なやり方がないかと考えているのですが…