我想知道是否有一个更好的算法,我正在尝试做什么:
wrapIndex(-6, 3) = 0 wrapIndex(-5, 3) = 1 wrapIndex(-4, 3) = 2 wrapIndex(-3, 3) = 0 wrapIndex(-2, 3) = 1 wrapIndex(-1, 3) = 2 wrapIndex(0, 3) = 0 wrapIndex(1, 3) = 1 wrapIndex(2, 3) = 2 wrapIndex(3, 3) = 0 wrapIndex(4, 3) = 1 wrapIndex(5, 3) = 2
我想出了
function wrapIndex(i, i_max) { if(i > -1) return i%i_max; var x = i_max + i%i_max; if(x == i_max) return 0; return x; }
有更好的方法吗?
答案 0 :(得分:22)
此解决方案无分支,但执行%
两次:
function wrapIndex(i, i_max) {
return ((i % i_max) + i_max) % i_max;
}
应该说假设%
的C#/ Java行为,即结果与被除数具有相同的符号。有些语言定义余数计算以取代除数的符号(例如Clojure中的mod
)。有些语言在Common Lisp,Haskell等中都有变体(mod
/ rem
对。 Algol-68有%x
,它总是返回一个非负数。 C ++将其实现到C ++ 11,now the sign of the remainder is (almost) fully specified according to the dividend sign。
答案 1 :(得分:10)
具有两个%
操作的解决方案可以正常工作,但在大多数硬件上大多数语言都有所加快(但也有例外):
int wrapIndex(int i, int i_max) {
i = i%i_max;
return i<0 ? i+i_max : i;
}
答案 2 :(得分:5)
Nicer是品味的问题,但是怎么样
var x = (i_max + i % i_max) % i_max;
答案 3 :(得分:2)
你可以这样做:
function wrapIndex(i, i_max) {
if (i < 0) i = (i % i_max) + i_max;
return i % i_max;
}
答案 4 :(得分:2)
许多用户给出了很好的答案,只要注意负数,因为不同的语言可能表现不同。 例如,这个C片段写“-1”
int main ()
{
printf("%d\n", (-4) % 3);
}
在python中我们有不同的输出值
Python 2.6.4 (r264:75706, Dec 7 2009, 18:43:55)
[GCC 4.4.1] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> (-4) % 3
2
编辑:实际上我认为你不会有负面索引!然而,知道这一点很好。