我的教授不喜欢使用模数,因为它的效率不够高,但我不确定如何使用逻辑运算符或其他东西获得相同的答案。有人可以帮我解决这个问题吗?
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 语句的参数为真,而且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
这个伪代码应该给你一个非常清晰的解决方案提示。