2

たとえば、Javaで次のようなことをしたいと思います。

int[] numbers = {1,2,3,4,5};
int[] result = numbers*2;
//result now equals {2,4,6,8,10};

これは、配列を反復処理せずに実行できますか?ArrayListなどの別のデータ型を使用する必要がありますか?現在の反復ステップには時間がかかります。このようなことが役立つことを願っています。

4

4 に答える 4

4

いいえ、配列全体を反復処理せずに、配列内の各項目を乗算することはできません。コメントで指摘されているように*、このような方法で演算子を使用できたとしても、実装は配列内の各項目にアクセスする必要があります。

さらに、別のデータ型でも同じことを行う必要があります。

于 2012-08-22T15:53:19.720 に答える
2

明白なものとは異なる答えは、同じ問題を抱えていて、複雑さの層(または2つ)を気にしない他の人にとって有益かもしれないと思います。

Haskellには、「遅延評価」と呼ばれるものがあります。この場合、無限に大きな配列に2を掛けるようなことができ、Haskellはそれを「実行」します。アレイにアクセスすると、必要に応じてすべてを評価しようとします。Javaにはそのような贅沢はありませんが、この動作を制御可能な方法でエミュレートできます。

List独自のクラスを作成または拡張し、いくつかの新しい関数を追加する必要があります。サポートしたい数学演算ごとに関数が必要になります。以下に例を示します。

LazyList ll = new LazyList();
// Add a couple million objects
ll.multiplyList(2);

これの内部実装は、実行する必要のあるすべての基本操作を格納するキューを作成することです。これにより、操作の順序が保持されます。これで、要素が読み取られるたびに、結果を返す前にキュー内のすべての操作を実行します。これは、読み取りが非常に遅いことを意味します(実行される操作の数によって異なります)が、少なくとも目的の結果が得られます。

毎回配列全体を反復処理していることに気付いた場合は、元の値を保持するのではなく、最後にデキューする方が便利な場合があります。

ランダムアクセスを行っていることがわかった場合は、元の値を保持し、呼び出されたときに変更された結果を返します。

エントリを更新する必要がある場合は、それが何を意味するかを決定する必要があります。そこで値を置き換えますか、それとも操作の実行後に値を置き換えますか?回答によっては、キューを逆方向に実行して、古い値を置き換える「操作前」の値を取得する必要がある場合があります。その理由は、同じオブジェクトを次に読み取るときに、操作が再度適用され、値がリストで置き換えようとしたものに復元されるためです。

このソリューションには他のニュアンスがあるかもしれません。また、実装方法は、ニーズとこれにアクセスする方法(順次またはランダム)によって完全に異なりますが、良いスタートになるはずです。

于 2012-08-22T16:14:36.710 に答える
1

Java 8の導入により、このタスクはストリームを使用して実行できます。

 private long tileSize(int[] sizes) {
    return IntStream.of(sizes).reduce(1, (x, y) -> x * y);
}
于 2018-10-12T14:28:29.207 に答える
0

いいえ、そうではありません。コレクションが非常に大きく、より速く実行したい場合は、2つ以上のスレッドの要素を操作することができますが、同期を処理する(同期コレクションを使用する)か、コレクションを2つ(またはそれ以上)のコレクションに分割する必要があります各スレッドで1つのコレクションを操作します。配列を反復処理するよりも高速になるかどうかはわかりません。コレクションのサイズと、各要素で何をしたいかによって異なります。このソリューションを使用したい場合は、あなたの場合はそれが速いかどうかがわかります-それは遅くなる可能性があり、間違いなくはるかに複雑になります。一般的に、それがコードの重要な部分ではなく、実行時間が長すぎない場合は、今のままにしておきます。

于 2012-08-22T16:48:25.173 に答える