# ArrayList abzählen



## christophs91 (8. Jun 2012)

Hallo java-forum.org,

ich bin hier neu und studiere Wirtschaftsinformatik im 2. Semester, bin nun zum zweiten mal beim Programmierkurs Java dabei, weil ichs im 1. Semester nicht gepackt habe  Hoffe nun auf Hilfe bei der folgenden Aufgabe!
*In einem Kreis stehen n Kinder (durchnumeriert von 1 bis n). Mit Hilfe eines m-silbigen Abzählreims wird das jeweils m-te unter den noch im Kreis befindlichen Kindern ausgeschieden, bis kein Kind mehr im Kreis steht.
Schreiben Sie ein Java-Programm, das nach Vorgabe von n (positiver int-Wert) und m (positive int-Wert) die Nummern der Kinder in der Reihenfolge ihres Ausscheidens angibt.
Beispiel: Für n=6 und m=5 ergibt sich die Folge 5, 4, 6, 2, 3, 1.*
Ich möchte das ganze nicht mit einem Array, sondern mit einer ArrayList verwirklichen, da es für mich einfacher erscheint.
Das grobe Grundgerüst habe ich schon. Nur komm ich momentan nicht drauf, wie ich den abzaehl Algorithmus am Ende verwirkliche.
Hier mein bisheriger Code, lasst euch nicht von der IO.readInt etc. verwirren, das ist eine Klasse, die unser Prof vorgibt.


```
package Uebungszettel06;

import java.util.ArrayList;

public class Aufgabe2 {

    public static void main(String[] args) {
        int n = IO.readInt("n Kinder angeben: ");
        ueberpruefe(n);
        int m = IO.readInt("Abzaehlreim m eingeben: ");
        ueberpruefe(m);
        ArrayList<Integer> kinderkreis = new ArrayList<>();
        erstelleKreis(n, kinderkreis);
        abzaehlen(n, m, kinderkreis);
    }

    static void ueberpruefe(int zahl) {
        while (zahl < 0) {
            zahl = IO.readInt("Falsche Eingabe, bitte erneut eingeben: ");
        }
    }

    static void erstelleKreis(int n, ArrayList<Integer> kinderkreis) {
        System.out.print("Das ist der Kinderkreis: ");
        // Schleife n Kinder in die Liste hinzufügen, dabei wird mit 1 gestartet
        for (int i = 0; i < n; i++) {
            kinderkreis.add(i+1);
            System.out.print(kinderkreis.get(i));
        }
        System.out.println("  und jetzt wird abgezaehlt...");
    }

    static void abzaehlen(int n, int m, ArrayList<Integer> kinderkreis) {
        // Solange der Kinderkreis nicht leer ist, führe das abzaehlen durch
        while (!kinderkreis.isEmpty()) {          
            System.out.print("Die Reihenfolge der auscheidenden Kinder: ");
            // Ausscheidende Kind wird geprinted
            System.out.print(kinderkreis.get(m));                     
            // abgezaehlte Kind wird entfernt aus der Liste
            kinderkreis.remove(m);
        }
    }
}
```


Mein Problem ist am Ende, ja ich weiß, zurzeit würde es eine Exception ergeben.
Ich möchte solange abzaehlen bis der Kinderkreis leer ist.
Aber wie kann ich in der ArrayList so abzählen wie es in der Aufgabe verlangt ist.
Beim ersten Durchgang bekomm ich 5. Dann wird bei 6 weitergezählt und dann von vorne gestartet.
Und dieser Vorgang wieder von vorne in der ArrayList anfangen zu zaehlen bereitet mir Probleme.
Habt ihr Ideen oder bisherige Verbesserungsvorschläge?

Freundliche Grüße
Christoph


----------



## XHelp (8. Jun 2012)

Du musst die Position des letzten rausgeschmissenes Kindes merken. Darüber hinaus könnte hier der 
	
	
	
	





```
%
```
-Operator ganz praktisch sein.


----------



## christophs91 (8. Jun 2012)

XHelp hat gesagt.:


> Du musst die Position des letzten rausgeschmissenes Kindes merken. Darüber hinaus könnte hier der
> 
> 
> 
> ...



Vielen Dank.
Ich würde jetzt so vorgehen:

```
static void abzaehlen(int n, int m, ArrayList<Integer> kinderkreis) {
        int letztePosition = 0;
        // Solange der Kinderkreis nicht leer ist, führe das abzaehlen durch
        while (!kinderkreis.isEmpty()) {
            System.out.print("Die Reihenfolge der auscheidenden Kinder: ");
            // Ausscheidende Kind wird geprinted
            System.out.print(kinderkreis.get(m));
            letztePosition = kinderkreis.indexOf(m);
            // abgezaehlte Kind wird entfernt aus der Liste
            kinderkreis.remove(m);
        }
    }
```

Ich leg eine letztePosition fest und vor dem Start der Schleife wird diese auf 0 gesetzt, damit ich von da aus losgehen kann.
Das Abzaehlen realisiere ich am besten mit einer for-Schleife, wo der Variable letzePosition immer als Startwert gesetzt wird.
Richtige Idee?


```
for (int i = letztePosition; letztePosition < kinderkreis.size(); i++ ) {
                
            }
```


----------



## XHelp (8. Jun 2012)

Naja, nicht ganz. Du schmeißt hier Index und Element durcheinander. Außerdem musst du ja irgendwo auch "m"-Schritte weiter gehen. Ich dachte eher an:

```
int letztePosition = -1;
System.out.print("Die Reihenfolge der auscheidenden Kinder: ");
while (!kinderkreis.isEmpty()) {
  letztePosition = letztePosition+m;
  letztePosition = letztePosition%kinderkreis.size();
  System.out.print(kinderkreis.get(letztePosition));
  kinderkreis.remove(letztePosition);
}
```
ist aber ungetestet


----------



## christophs91 (8. Jun 2012)

Vielen Dank, das hilft mir schon mal weiter. Es funktioniert noch nicht 100%ig, ab dem 1. Element sind die Werte falsch, aber ich versuche es herauszubekommen.


----------



## XHelp (8. Jun 2012)

Ja, stimmt. Fang mal bei 
	
	
	
	





```
letztePosition = 0;
```
 an und rechne immer 
	
	
	
	





```
letztePosition = letztePosition+m-1;
```
, dann müsste es hinhauen


----------



## christophs91 (8. Jun 2012)

Du bist ein Genie!
Vielen Dank!


----------

