私の教授は、十分に効率的ではないためモジュロの使用を好みませんが、論理演算子などを使用して同じ答えを得る方法が他にわからないのです。誰かがこれを行う方法を手伝ってくれますか?
j = (j + 1) % a.length;
これでうまくいくはずです。
int k = a.length;
int d = (j+1)/k;
j = (j+1) - d*k
モジュロなしでこれを行う唯一の方法は、まだ素晴らしいものではありません。
j = (++j < a.length)? j : (j - a.length);
または、読みやすくするために、次のようにします。
j++;
j = (j < a.length)? j : (j - a.length);
また
j++;
if (j >= a.length) {
j -= a.length;
}
また、Java がループ予測をどのように処理するかについては完全にはわかりませんが、少なくとも C では、if ステートメントへの引数が true になるという一般的な仮定があるため、読みにくい場合でも、速度がわずかに向上します。 、そしてj < a.length
多くの場合 ( を除いa.length <= 2
て、ありそうにないようです。)
j++;
if(j < a.length) {
}
else {
j -= a.length;
}
の初期値が(包括的 - 排他的)j
の範囲外にある場合、唯一の解決策は、同じ演算で同じ速度のモジュラスまたは除算を使用するか、減算のループを使用するかのいずれかです。非常に古いプロセッサのモジュラスと同じことです。これは、私が知っている現在のプロセッサのモジュラスの組み込み操作よりも遅いです。0
a.length
あなたはこれを行うことができます:
j = j + 1;
if (j >= a.length) {
j = j - a.length; // assumes j was less than length before increment
}
@ajp は、実際に問題なく動作する別のソリューションを提案しています。
j = j + 1;
if (j >= a.length) { // assumes j was less than length before increment
j = 0;
}
私がコードを書いていたら、念のためこのように書いてください。追加のオーバーヘッドはほとんどなく、「想定」を削除します
j = j + 1;
while (j >= a.length) {
j = j - a.length;
}
もちろん、%
これも良い方法です。あなたの教授でない限り。
これは、ジャンプのコスト (および命令パイプライン/先読みに与える影響) と整数除算命令の効率に応じて、除算/モジュロよりも高速または低速になる可能性があります。
古いプロセッサは、ジャンプでうまくいく可能性があります。分割されたより現代的なもの。
ここで何をしているのか考えてみてください。あなたは本質的に言っています:
if j + 1 is smaller than a.length, set j to j + 1
otherwise, we set j to a value smaller than a.length
この疑似コードは、ソリューションへの非常に明確なヒントを提供するはずです。