4

次の 3D 配列を 2 つのプログラム状態間のバッファーとして設定しました。

private boolean state [][][] = new boolean [20][20][2];

からすべてをコピーしようとしています

state[0-19][0-19][1]

state[0-19][0-19][0]

現時点では for ループを使用していますが、これは問題なく動作しますが、もっと良い方法があると感じずにはいられません。2 つの別々の 2D 配列を使用して単純なコピーを実行できることはわかっていますが、これを回避する方法があるかどうかを知りたいと思っています。

現在のループ:

for (int i=0;i<20;i++){
        for (int j=0;j<20;j++){
            state[i][j][0]=state[i][j][1];
    }
}
4

2 に答える 2

2

場合によっては、内側のループをSystem.arraycopyに置き換えると、高速になります。しかし、あなたの記憶のレイアウトにはないと思います。

可能であれば、配列をコピーする代わりに、参照を更新することを検討してください。Java の「多次元」配列は、実際には配列の配列であることを思い出してください。

特に、

 boolean[] tmp = multi[0];
 multi[0] = multi[1];
 multi[1] = tmp;

ゼロに近いコストで 2 つの配列参照を交換します。これは、古い値をコピーしてから上書きするよりもはるかに高速です。ただし、コピーが必要な場合 (古い値を上書きしない場合) は、これを行うことができません。

これを盲目的に行うべきではないことに注意してください。

 multi[0][0] = 1;
 multi[1] = multi[0];
 multi[1][0] = 0;
 System.err.println(multi[0][0]);

これは、 と が同じネストされた配列を指している0ためです。使用する必要がありました。multi[0]multi[1]

 multi[1] = multi[0].clone();

また、複製は深くないためmulti.clone()、 と同じネストされた配列を指すことに注意してくださいmulti。Java には組み込みのディープ クローンやディープ アレイコピーはありません。どちらの方法でもループを使用する必要があります。

しかし、繰り返しになりますが、多くの arrayで 2 番目の要素を最初の要素にコピーしたい場合、これらのどれも機能しないと思われます。これはメモリ レイアウトの問題です。

データ構造がメモリ内でどのように見えるかを思い出してください。

 boolean[][][] -> boolean[][] -> boolean[]{ 0, 1 }
              \               \> boolean[]{ 0, 1 }
               \> boolean[][] -> boolean[]{ 0, 1 }
                              \> boolean[]{ 0, 1 }

各配列に 1 つの要素をコピーします。それらはメモリ全体に存在する可能性があるため(すべてboolean[]...が独自のオブジェクトです!)、プリミティブを使用してこれを高速化する方法はありません。データは散らばっています。可能であれば、メモリ レイアウトの変更を検討してください。

ブール配列に代わるものも検討してください。ブール値は 1 バイトのメモリを使用しますが、保存できるのは 1 ビットのみです (これはより高速になる可能性があるため、それ自体は悪くないことに注意してください!)。BitSetただし、代わりにブール配列全体を aまたは alongに格納してから、実際のビット操作を行うことが理にかなっている場合があります。しかし、利益は、時にはそれが報われることもあれば、時には傷つくこともあります。

于 2013-02-27T10:26:01.323 に答える
0

ディメンションを再編成するnhahtdhのソリューションは気に入っていますが、参照をコピーした場合、後で変更state[0]した場合state[1]は変更が反映され、その逆も同様であることに注意してください(実際にはこれが必要な場合があります)。参照には2つの場所でアクセスできますが、コンテンツは1つの場所にのみ保存されます-古いポインター/参照の混乱。ユニットテストはあなたの友達です:-)

単一の次元配列がある場合、このArrays.copyOf()メソッドはコードのループを回避するのに役立ちます。ただし、一部のオブジェクトのコピーは、すべての個々のオブジェクトではなく、オブジェクトへの参照sometype[]をコピーすることに注意してください。 sometype

.clone()もちろん、オブジェクトの「深い」コピーを取得するために、シリアル化やシリアル化をいじり始めることもできsometype[]ますが、そうすると、ネストされたループよりもすぐに複雑になります。

于 2013-02-27T10:39:44.000 に答える