2016-04-01 12 views
2

Ich versuche, das Josephus-Problem in einer ArrayList-Datenstruktur zu arbeiten, und die Aufgabe ist, ListIterator zu verwenden. Ich bleibe am entfernenden Teil hängen.Bedenken mit Listiterator entfernen Java

Sagen wir, ich habe folgende 10 Soldaten - 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 Und ich muss jeden dritten Soldaten treten - was bedeutet, 3 zu entfernen, dann 6, dann 9 und so weiter.

Ich bin in der Lage, erfolgreich 3 zu entfernen, aber das nächste Mal entfernt es 7 und nicht 6. Können Sie bitte meinen Code überprüfen und mir sagen, was ich falsch mache:

private static int suicide (List<Integer> list, int step) { 

     ListIterator<Integer> itr = list.listIterator(); 

     while(itr.hasNext()&& list.size() != 1){ 

      if((itr.nextIndex()+1) % step == 0) { 
       System.out.println(itr.previousIndex()+1); 
       itr.next(); 
       itr.remove(); 
       itr.next(); 
      } 
      else { 
       itr.next(); 
      } 

      if(!itr.hasNext()){ 

       itr=list.listIterator(); 
      } 
     } 
     return 0; 
    } 
+0

Ich verstehe, dass das Problem ist, dass die Elemente im Index bewegen und dass gemäß meiner Logik jetzt Element 7 im Index '5' (logisch 6) und damit entfernt wird. Ich möchte verstehen, wie man das stoppt. – user4261932

Antwort

0

Eine Möglichkeit ist, dass Sie Erstellen Sie eine Kopie der Liste, und entfernen Sie die Elemente in dieser Kopie, indem Sie immer noch das "Original" durchlaufen (und den Iteratorschritt in der Kopie überspringen).

ListIterator itr = list.listIterator(); ListIterator itr2 = copy.listIterator();

while(itr.hasNext()&& list.size() != 1){ 

    if((itr.nextIndex()+1) % step == 0) { 
     System.out.println(itr.previousIndex()+1); 
     itr.next(); 
     itr2.next(); 
     itr2.remove(); 
     itr.next(); 
    } 
    else { 
      itr.next(); 
      itr2.next(); 
     } 
0

Versuchen Sie dies;

int i = 3; 
int step = 1; 

while (list.size() > i) { 
    list.remove(i); 
    step++; 
    i = 3 * step - step + 1; 
} 
0

Setzen Sie Ihre Konstruktionslogik um!

Das Erstellen einer neuen Liste mit nur akzeptierten Elementen ist ein wirklich guter Ansatz.

Entfernen ist immer schwieriger zu verstehen und zu pflegen.

Zum Beispiel sollten Sie Methode Selbstmord eine neue Liste <> mit den gewünschten Elementen zurückgeben.

Ihr Code wird wirklich einfacher:

List<Integer> cleanedList = new ArrayList<Integer>(); 
for(Integer soldier : list) { 
    if(solider%3!=0){ 
     cleanedList.add(soldier); 
    }  
} 
return cleanedList; 

Die meiste Zeit ich API bevorzugen, die neue objets schafft. Wenn Sie diese Regel anwenden, erhalten Sie immer einfacheren Code! Und das Aktualisieren von Parametern ist kein gutes Verhalten: Wenn Sie die Methode zweimal aufrufen, erhalten Sie zwei verschiedene Ergebnisse.

+0

Aber in erster Ordnung möchte er jeden dritten Eintrag entfernen (so habe ich es verstanden), und nicht nur einen Eintrag, der durch 3 geteilt werden kann. Ihr Code funktioniert für sein "Lass uns sagen" -Beispiel, wo sie perfekt geordnet sind und mit beginnen 1. – Martin

+0

Sie haben Recht, aber Sie können dies mit dem Index mit für (int i = 0) tun, und es funktioniert, wo ich Ihren Listenindex ist –

Verwandte Themen