Java灯泡开关问题

时间:2011-07-05 08:08:01

标签: java algorithm

我有一个包含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.

我该如何解决这个问题?

6 个答案:

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