5

我的教授不喜欢使用模数,因为它的效率不够高,但我不确定如何使用逻辑运算符或其他东西获得相同的答案。有人可以帮我解决这个问题吗?

j = (j + 1) % a.length;
4

4 回答 4

3

这应该可以解决问题。

 int k = a.length;
 int d = (j+1)/k;
 j = (j+1) - d*k
于 2013-10-15T19:21:00.330 回答
3

我能看到在没有模数的情况下这样做的唯一方法仍然不是很好:

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超出(含-不含)的范围0a.length那么唯一的解决方案要么使用模数或除法,作为相同的操作,它们的速度相同,要么使用减法循环,这将基本上完成与非常旧的处理器上的模数相同,它比我所知道的任何当前处理器上的内置模数操作都慢。

于 2013-10-15T19:21:08.363 回答
2

你可以这样做:

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;
}

当然,这%也是一个很好的方法。除非你的教授。

这可能比除法/模运算更快或更慢,具体取决于跳转的成本(以及对指令流水线/前瞻的任何影响)和整数除法指令的效率。

旧处理器可能会在跳跃中做得更好。更现代的有分歧。

于 2013-10-15T19:20:58.920 回答
1

想想你在这里做什么。你本质上是在说:

if j + 1 is smaller than a.length, set j to j + 1
otherwise, we set j to a value smaller than a.length

这个伪代码应该给你一个非常清晰的解决方案提示。

于 2013-10-15T19:21:16.957 回答