我有一个包含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.
我该如何解决这个问题?
答案 0 :(得分:2)
如果它应该从0
转到5
,您应该使用%6
答案 1 :(得分:1)
如果您的灯泡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
其中[]
内的数字是基于索引数的常量。
答案 2 :(得分:0)
数组索引从0开始,所以如果你有5个元素,那么它们就位于0,1,2,3,4 ..
答案 3 :(得分:0)
使用0..4作为灯泡ID而不是1..5。这实际上是程序员喜欢从零计算的主要原因:它简化了索引。
答案 4 :(得分:0)
检查这是否是最后一个灯泡。最后一个灯泡只有左邻居
if(bul.id == numBulbs)
{
//Check only left side
if(bul.id == (bulbIdClicked - 1)%5)
...
}
你对第一个灯泡做了同样的事情
if(bul.id == 0)
{
//Check only right side
if(bul.id == (bulbIdClicked + 1)%5)
...
}
答案 5 :(得分:0)
如果您需要向后和向前导航列表,请使用ListIterator
(通过list.listIterator()
或list.listIterator(index)
方法提供。以下是一些示例代码:
List<Bulb> bulbs = new ArrayList<Bulb>();
int amount = 500;
for(int i = 0; i < amount; i++){bulbs.add(new Bulb());}
// which one to switch off
int offset = new Random().nextInt(amount);
ListIterator<Bulb> li = bulbs.listIterator(offset);
li.next().switchOff();
if(li.hasNext()){
li.next().switchOff();
// go back to selected offset
li.previous();
}
if(li.hasPrevious()){
li.previous().switchOff();
}