有人可以解释这种方法的工作原理吗

时间:2016-05-06 10:26:24

标签: java arrays for-loop

该方法即将删除最小人口的城市!

方法:

public void delCity(long population) {
    if (population== 0) {
        System.out.println("There is no city!");
        return;
    }

    for (int i = 0; i < index; i++) {
        if (cities[i].getPopulation() < population) {
            for (int j = i; j < index - 1; j++) {
                cities[j] = cities[j + 1];
            }
            cities[--index] = null;
            i--;
        }
    }
}

所以我不理解的部分是第二个for循环的主体,例如cities[j] = cities[j + 1];如何工作以及cities[--index] = null; i--;是什么?我非常感谢你的回复。

4 个答案:

答案 0 :(得分:5)

此循环正在移动数组的所有值[从位置 i ,即要删除的城市]。 (因为数组是静态的,否则元素之间就是null)

-webkit-appearance: none 

然后将最后一个元素设置为null并减少索引;

for (int j = i; j < index - 1; j++) {
    cities[j] = cities[j + 1];
}

这里有一个转变的解释: enter image description here enter image description here

正如提到的评论。你的复杂性是O(N²)。但只是更改数据结构(例如,使用列表),您可以将其改进为O(N)。

答案 1 :(得分:2)

cities[j] = cities[j + 1];

以上语句将索引j的城市设置为索引为j + 1的城市。

cities[--index] = null;

此语句只将城市的最后一个索引设置为null

因此,没有删除元素。要删除的元素只会被下一个元素覆盖。并且循环为要删除的元素之后的所有元素执行此操作。最后,我们留下了最后一个设置为null的元素。

抛开解释,代码效率很低。

答案 2 :(得分:1)

我对代码进行了评论,因为在这样简单的上下文中,任何更精细的解释都是多余的。

//Scan all the cities, from i = 0 to i = index -1
for (int i = 0; i < index; i++) 
{
    //Check it cities[i] has LESS population than specified
    if (cities[i].getPopulation() < population) 
    {
         //We need to remove cities[i]
         //We shift all the subsequent cities 
         //(cities[i+1], cities[i+2], ... cities[index-1] one position LEFT,
         //thereby overwriting cities[i] and so deleting it

         //Shift all the subsequent cities left
         //We start this for FROM i, so the first iteration is
         //cities[i] = cities[i + 1];
         //The second is
         //cities[i + 1] = cities[i + 2];
         //and so on. We STOP AT index - 2 (note the strict less than)
         //So that j + 1 is AT MOST index - 1
         for (int j = i; j < index - 1; j++) 
         {
                cities[j] = cities[j + 1];
         }

         //Since j was at most index - 2, the cities[index - 1] was not
         //overwritten with the next one. Naturally as there is no next one
         //for it.
         //This last city is now duplicated (the copy is at index - 2) and
         //Must be overwritten with null.
         //Also index, which keep track of the number of cities must be
         //decremented (here the pre-decrement -- is used)
         cities[--index] = null;

         //cities[i] was the deleted city. But now it contains cities[i + 1]
         //Which is a totally different city!
         //If we continue the for now, we will go to the NEXT city, as i 
         //will be incremented, to keep i the same one more iteration, we
         //decrement it. This way we process (the new) cities[i] one more time.
         i--;
    }
}

使用旧的铅笔和橡胶,直到你完全理解算法,真的,没有更好的方法。

答案 3 :(得分:0)

index是数组cities的大小。因此,当您到达cities[i].getPopulation() < populationtrue的特定位置时,您会将所有城市从位置i + 1移至数组index - 1的末尾,转移到i位置到index - 2,你可以用:

for (int j = i; j < index - 1; j++) {
                cities[j] = cities[j + 1];
            }

因此,位置i上人口较少的城市(现在为j)将被citiescities[j + 1]覆盖,而citiescities[j + 1]将被citiescities[j + 2]覆盖。 1}}等等,直到数组结束。因此,位置citiescities[index - 2]将与citiescities[index - 1]相同,因此我们需要将其删除,因此您放置cities[--index] = null;,其中index将首先递减(这就是为什么{ {1}}将离开--),index将为cities[oldIndex - 1]。这也有助于null循环直到数组中的第一个for值位置,但直到index中的最后一个城市为止。

现在,由于您的索引i将在下一个循环步骤中递增,但您在位置i上移动了下一个城市,您必须递减array以检查该城市,这就是最后i的原因

请注意,使用此功能,您仍然可以像以前一样使用完整的长数组,如果城市的人口数少于规定数,则填充一些空值。也许更好的方法是将它复制到大小为i的新数组,这是index结束时的注意事项(注意:类似于for从中删除项目时所执行的操作)