w jaki sposób element jest kasowany w pętli

0

Trochę nie rozumiem działania tej 2 pętli w pełni - chcę naumieć się czytać algorytmy.
Może mi ktoś wytłumaczyć jak się to dzieje że element searchKey jest usuwany ?

      searchKey = 55;              // usuwamy element o kluczu 55 - elementów nElems jest 10
      for(j=0; j<nElems; j++) {
	    if (arr[j] == searchKey) {
		break;
	    }
	}
      for(int k=j; k<nElems; k++) {   
	    arr[k] = arr[k + 1];        // o co tu chodzi ?
	}
      nElems--;                         // zmniejszamy ilość elementów 

Podręcznikowy przykład, pierwszy z brzegu :D

0

jakiś dziwny ten kod....
najpierw wyszukujesz w array klucza a gdy go znajdziesz wychodzisz z pętli nic nie robiąc :o
w drugiej pętli natomiast każdy element z array jest zastępowany elementem kolejnym z listy :o

Czy aby na pewno dobrze przekopiowałeś ten kod ?

1

Niczego dziwnego w tym kodzie nie ma. Pierwsza pętla znajduje miejsce w tablicy gdzie jest 55. Druga pętla przesuwa każdy wyraz leżący na prawo "na prawo" od znalezionego miejsca o jedną pozycje w lewo. Pierwsze wykonanie tej pętli wymazuje 55.

1

Powiedzmy ze masz tablice 6-elementową np: {5, 15, 25, 55, 35, 45} przeszukujesz tablicę za pomocą pierwszej pętli pokolei:
0. czy 5 == 55? Nie, to jedziemy dalej,

  1. czy 15 == 55? Nie, to jedziemy dalej,
  2. czy 25 == 55? Nie, to jedziemy dalej,
  3. czy 55 == 55? Tak, to przerywamy pętlę przy j równym 3

wchodzimy do drugiej pętli i dla k równego j rónego 3
3. element 3 zastepujemy 4 (element czwarty zastępujemy piątym), wtedy arr[3] = arr[4]
4. element 4 zastepujemy 5, wtedy arr[4] = arr[5]
tablica w tym momencie wygląda tak {5, 15, 25, 35, 45, 45}

Wychodzimy z pętli drugiej i zmniejszamy tablicę o jeden element.

W tym momencie tablica wygląda tak {5, 15, 25, 35, 45} - pozbyto się wartości 55 z pętli.

0

Tak, zastosowałem copy - paste.

I ten kod działa znaczy usuwa dany elem.

Źródło : http://helion.pl/ksiazki/java-algorytmy-i-struktury-danych-robert-lafore,javalg.htm

0

W pierwszej pętli zakańczasz przeglądanie tablicy gdy natrafisz na element searchKey i wtedy wyskakuje z pętli breakiem a j wskazuje na ten element.
W drugiej pętli przesuwasz drugą część tablicy w lewo poczynając od elementu po searchKey (na miejsce j wskakuje j+1, na j+1 wskakuje j+2 itd.)

0
MJay napisał(a)

wchodzimy do drugiej pętli i dla k równego j rónego 3
3. element 3 zastepujemy 4 (element czwarty zastępujemy piątym), wtedy arr[3] = arr[4]
4. element 4 zastepujemy 5, wtedy arr[4] = arr[5]
tablica w tym momencie wygląda tak {5, 15, 25, 35, 45, 45}

Wychodzimy z pętli drugiej i zmniejszamy tablicę o jeden element.

W tym momencie tablica wygląda tak {5, 15, 25, 35, 45} - pozbyto się wartości 55 z pętli.

Teraz rozumiem:) Wielkie dzięki.

Aha, jeszcze parafrazując: po prostu prawa część tablicy leci o 1 w dół począwszy od j=3 (który jest zamieniany na j=4, itd.) a ostatni - kopia arr[4] jest usuwany przez nElem--
I rozumiem że tą pętlę można stosować w wielu różnych algorytmach modyfikując ją tylko... ?

np.

arr[k] = arr[k + 2];  // czyli arr[3] = arr[5] itd.(?)
 
1

Prawdę mówiąc ostatni nie jest usuwany, zmniejszana jest tylko liczba elementów tablicy mimo iż one tam dalej istnieją
Jeżeli zdefiniowałeś tablicę 6-elementową {5, 15, 25, 35, 45, 55}, to nElems == 6, jeżeli przesunęliśmy całą tablicę w lewo czyli {15, 25, 35, 45, 55, 55} to rozmiar tablicy się nie zmienił, dalej zajmuje ona 6 * 4 bajty, teraz zmniejszamy liczbę elementów nElems-- i nElems == 5 przykład:
Wywołujemy pętlę

for(int i = 0; i < nElems; i++)
"wypisz" arr[i]; // wypisuje od 0 do 5 elementu, czyli {15, 25, 35, 45, 55, 55}
nElems--;
for(int i = 0; i < nElems; i++)
"wypisz" arr[i]; // wypisuje od 0 do 4 elementu, czyli {15, 25, 35, 45, 55}

Ale po tej operacji arr[5] wciąż istnieje, tylko się go nie wyświetla bo wyświetlasz w drugiej pętli elementy od 0 do 4.
Po zakończeniu pętli wpisz linijkę kodu
"wypisz" arr[5] // ta linijka pokaże Ci wartość 55, bo ona dalej w pamięci zalega

0

Dzięki - to jest teraz bardzo proste.

Pytanie dla chętnych:)
Ale czy w chwili nElem-- tablica nie zawiera już tylko 9 nElem'entów ? Jeśli tak to co się dzieje z dziesiątym. Skoro można go wywołać?
Krótko mówiąc - gdzie jest wtedy ten element w pamięci ? :)

1

Tablice mają stałą wielkość od chwili alokacji do chwili de-alokacji. Obojętne czy w C++, Javie czy C#. Zmienna nElem, z punktu widzenia kompilatora, OSa, maszyny wirtualnej, etc nie ma żadnego znaczenia. Zresztą w Javie masz specjalne pole mówiące ile jest elementów w tablicy.

<code-java>int[] tablica = new int[10];
System.out.println(tablica.length);

1 użytkowników online, w tym zalogowanych: 0, gości: 1