2011-07-05 78 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(); 
}