我有一个包含5个灯泡的数组列表我可以像这样重复它们

for(Bulb bul : list){
    System.out.println(bul.id);
}

没有关闭/打开灯泡。其结果是,它的邻居灯泡也一个开关。
我的问题是,当最后一个或第四个灯泡被切换时,我需要确定它的邻居既然我有5个灯泡,这就行了。
int bulbIdClicked = 3;

if(bul.id == (bulbIdClicked + 1)%5)

if(bul.id == (bulbIdClicked - 1)%5)

如果是3个,我就有2个和4个邻居但是当4被切换时,它给了我3和0的邻居,其中0应该是5。
我怎样才能解决这个问题?

最佳答案

如果灯泡ID介于0到4之间,则获取下一个和上一个ID的最佳方法是使用:

next = (id + 1) % 5
prev = (id + 4) % 5

这是语言不可知论的,因为并非所有的语言对待负数上的模运算符都是一样的您可以看到,从4向前4步(例如)可以得到:0、1、2、3,这与向后一步相同。
然而。模数实际上只对基于零的值起作用。因为你有一个基值,你可以先减去一个,做相关的加法/模,然后再加一个。
next = ((id - 1) + 1) % 5 + 1
prev = ((id - 1) + 4) % 5 + 1

这些简化为:
next = id % 5 + 1
prev = (id + 3) % 5 + 1

使用这些公式,可以得到:
id  next  prev
--  ----  ----
 1    2     5
 2    3     1
 3    4     2
 4    5     3
 5    1     4

如预期。
这与没有查找表时可能得到的优化效果差不多。你可以对任何翻滚大小使用相同的方法(不仅仅是5),你只需要改变模和你添加的内容。
如果索引范围从1到N,则其:
next = id % [N] + 1
prev = (id + [N-2]) % [N] + 1

其中[]中的数字是基于索引数的常量。

10-06 03:18