2016-05-06 5 views
0

この方法では、人口が最も少ない都市を削除しようとしています。誰かがこの方法の仕組みを説明できますか?

方法:

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--;を何でしょうか?私は本当にあなたの反応に感謝します。

+2

いいえ、このメソッドは、指定された制限の下にある人口を持つすべての都市を削除します。ちなみに、それは非常に非効率的な方法(O(N²))で行われ、禁止されるべきです。 –

+0

Lolとこのメソッドをどのようにコード化しますか? –

+0

単一のループで、すべての保持された要素を左にパックします。 –

答えて

5

このループは、[iの位置(削除する都市)から配列のすべての値をシフトしています。(配列が静的なので、そうでない場合は要素間にnullがあります)

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

次に、最後の要素をNULLに設定し、インデックスを減らしています。ここ

cities[--index] = null; 

変速のexplainationは: enter image description hereenter image description here

コメントに述べたように。あなたの複雑さはO(N²)です。しかし、単にリストを使ってデータ構造を変更するだけで、O(N)に改善することができます。

+0

私の問題を照らしてくれてありがとう:) –

+0

@VigKillaさらに、リストを使ってデータ構造を変更するだけです。 O(n^2) – granmirupa

+0

"このループは配列のすべての値をシフトしています" ... ...しきい値以下の母集団を持つ都市の実際の位置から、複雑さを向上させることができます。 – antorqs

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

上記の文は、インデックスj + 1で街にインデックスjで都市を設定します。

cities[--index] = null; 

この文は単にnullに都市の最後のインデックスを設定します。

このように、要素の除去はありません。削除される要素は次の要素で上書きされます。そしてループは、削除される要素に続くすべての要素に対してこれを行います。最後に、最後の要素はnullに設定されています。

説明を省略すると、コードは非常に非効率的です。

+0

応答に感謝しますが、なぜそれは非効率ですか? –

+1

コメントの1つで述べたように、複雑さはO(n²)です。これは、ネストされたforループを使用しているためです。 –

0

indexは、配列citiesのサイズです。だから、あなたはcities[i].getPopulation() < populationtrueある特定の位置に来たとき、あなたは位置index - 2からiに配列index - 1の最後に位置i + 1からすべての都市を移動し、あなたがそれを行う:だから

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

、との都市配列iの小さな集団であるjは、citiescities[j + 1]で上書きして削除され、citiescities[j + 1]は、配列の最後までcitiescities[j + 2]などで上書きされます。だから、位置citiescities[index - 2]citiescities[index - 1]と同じになりますので、あなたはindexは、最初の(--indexから残されるThatsなぜ)デクリメントされ、cities[oldIndex - 1]nullなりますcities[--index] = null;を置くので、私たちは、それを削除する必要があります。これはまたforのループが最初のindexの配列の値の場所まで行くことを助け、arrayの最後の都市まで存在します。

今、あなたのインデックス以来、私はループステップのための次にインクリメントされますが、あなたはその都市をチェックするiをデクリメントしなければならない、私の位置に次の街を移動し、最後になぜiのthats。

これと同じように、これまでのように完全な長い配列を持つことになります。したがって、人口が少ない都市がある場合は、いくつかのヌルが入ります。たぶんより良いアプローチは、サイズindexの新しい配列にコピーすることです。forの末尾にあることに注意してください(注:項目を削除するときにArrayListと同じものがあります)。

+1

'indexは配列都市のサイズです'と仮定していますか? – Nfear

+0

はい、これに基づいて:for(int i = 0; i cities.lengthの場合、これは例外を生成します...したがって、配列のサイズ...または少なくともインデックス

+0

あなたのお返事ありがとうございます。 –

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--; 
    } 
} 

アルゴリズムを完全に理解するまで、古いペンシルとゴムを使用してください。本当に良い方法はありません。

+0

ありがとう、私はします。 –

+0

私は質問がありましたので、5つの要素の配列を得ました。String [] array = {a、b、c、d、x};と私は前のコードを使用してxを削除したい(for-loop)array [i] = array [i + 1];最初の要素(a)が次の要素(b)に置き換えられることを意味しますか?例:array [0] = array [1]; ? –

+0

コード 'array [i] = array [i + 1]'は、* x *以降の位置からのみ実行されます。したがって、* x *を削除する場合は、No、* a *は置き換えられません。内側のループが要素を* d *に最大でシフトするので、何も置き換えられません(したがって、* x *に対しては一度も循環しません)。 –

関連する問題