2011-07-05 55 views
0

我有一个包含5个灯泡的数组列表。我可以迭代通过他们这样的Java灯泡开关问题

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.

我该如何解决这个问题?

回答

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 

其中内部[]附图基于索引的数目是恒定的。

+0

非常感谢 –

2

如果它应该从05你应该使用%6

+0

它应该从1到5 –

+0

然后,您应该使用'%5',但由于您的列表基于零(0-4),因此使用'1'降低索引。 – wjans

0

数组索引从0开始,所以如果你有5个元素,那么他们在0,1,2,3,4位..

0

通过使用0..4作为灯泡ID而不是1..5。这实际上是程序员更喜欢零基计数的主要原因:它简化了索引。

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) 
    ... 
} 
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(); 
}