Methoden Arrays.AsList kleinste Zahl ausgeben Rekursiv

Poly

Mitglied
Hallo,

wie die Überschrift schon sagt, möchte ich mit einer Rekursiv-Methode den kleinsten Int-Wert aus einer Arrays.AsList ausgeben. Nach vielen Exceptions habe ich auch bemerkt, dass Arrays statisch sind und sich nicht verkleinern oder erweitern lassen, obwohl die Methoden .remove() und .add() vorgeschlagen werden. Das ist verwirrend.

Da ich nichts löschen kann, um mir die Abbruchbedingung einfach zu machen, wollte ich vorerst die Liste durchlaufen lassen. Aber da weiß ich schon nicht mehr weiter...Abbruchbedingung...


Java:
public class reku {
    public static void main (String[] args){
        List<Integer> ints = Arrays.asList(1,2,3,4,5,6,5,4,3,2,1,0,-10,10);
//        int m = min(ints);
//       
//        System.out.println("Das Minimum von "+ints+" ist "+m+".");
        int m = durch(ints);
        System.out.println(m);

    public static int durch(List<Integer> a){
        int index = 0;
        if(.....== a.size()){
            return a.get(0);
        } else {
            index++;
            return a.get(durch(a))+1; //Math.min(a.get(0)+1, a.get(1)+1);
        }
}

Kann mir jemand unter die Arme greifen? Wie Durchlaufe ich eine Liste ohne .remove() und wie finde ich die kleinste Zahl (hier muss ich bestimmt zwei Indexwerte vergleichen und den kleineren speichern, um ihn mit dem nächsten Index zu vergleichen).



Lg
 
Versuchs mal damit :

Java:
public int durch(List<Integer> argList, int argActIndex, int argActMinValue) {
        if (argActIndex > argList.size()-1) {
            return argActMinValue;
        }
        if (argList.get(argActIndex)<argActMinValue) {
            argActMinValue = argList.get(argActIndex);
        }
        return durch(argList, argActIndex+1, argActMinValue);
    }

und aufruf:

Java:
      ...
      List<Integer> ints = Arrays.asList(1,2,3,4,-12,6,5,4,3,2,1,0,-10,10);
      System.out.println("Das Minimum von "+ints+" ist "+m+".");
      int m = durch(ints, 0, 500);
      System.out.println(m);
      ...
 
Vielen Dank für die schnelle Antwort, es funktioniert auch perfekt. Ich darf jedoch keine weiteren Eingänge in die Methode schicken. Nur die Liste selbst geht in die Methode 🙁 .

Lg
 
Wie wärs dann mit List::subList?
Java:
public static int min(List<Integer> list) {
  if (list.isEmpty()) {
    throw new NoSuchElementException();
  }
  return list.size() == 1 ? list.get(0) : Math.min(list.get(0), min(list.subList(1, list.size())));
}
 
Muss es denn unbedingt rekursiv sein? Ich hätte es hier mit versucht:
Java:
    public static void main(String[] args) {

        List<Integer> ints = Arrays.asList(1,2,3,4,5,6,5,4,3,2,1,0,-10,10);
        System.out.println(myRek(ints, 5, 20));

    }

    private static int myRek(List<Integer> ints, int index, int small) {
        System.out.println(index); // Debug ausgabe
        if (index == 0) {
            return small;
        }
        if (ints.get(index) < small) {
            small = ints.get(index);
        }
        return Math.min(myRek(ints, (index + 5) % 14, small), small);
    }

Wobei Math.min() ja gar nicht benötigt ist. Dann sieht es wirklich so aus wie bei @da921610 .
 
Leider ja. Es ist eine Aufgabe für eine Klausurvorbereitung. Thema ist unter anderem Rekursion, was bei der Aufgabe schwer zu verstehen ist finde ich.

Das klassische Rekursionsbeispiel mit der Fakultät kann ich mir dagegen gut vorstellen.

Java:
public static int fak (int n){
        if(n==0){
            return 1;
        } else{
            return n*fak(n-1);

        }

//Schematisch geschrieben...:
//
//fac(3)= (3*fac(2*fac(1*fac(0))))
//fac(3)= (3*     (2*    (1*    (1))))


Bei der Listenmethode fällt es mir schwer nachzuvollziehen was da passiert. Ich kann mir die Klammern nicht vorstellen.
Java:
min(list.subList(1, list.size())));

Lg
 
Kannst du damit was anfangen?

Java:
public static int durch(List<Integer> list) {
        if (list.isEmpty()) {
            throw new NoSuchElementException();
        }
        if (list.size()==1) {
            return list.get(0);
        } else {
            if (list.get(0)<durch(list.subList(1, list.size()))) {
                return list.get(0);
            } else {
                return durch(list.subList(1, list.size()));
            }
        }
    }

Das ist @Flown seine Methode in Langform ...

EDIT: Die Methode subList erstellt eine neue Liste, die in der ursprünglichen Liste enthalten ist.
Java-Dokumentation stehts drin 🙂

https://docs.oracle.com/javase/7/docs/api/java/util/List.html#subList(int, int)
 
So kann man es nach @Flown auch schreiben:
Java:
    public static void main(String[] args) {

        List<Integer> ints = Arrays.asList(1, 2, 3, 4, 5, 6, 5, 4, 3, 2, 1, 0, -10, 10);
        System.out.println(myRek(ints));

    }

    private static int myRek(List<Integer> ints) {
        if (ints == null) {
            return -1;
        }
        if (ints.isEmpty()) {
            return -1;
        }
        if (ints.size() == 1) {
            return ints.get(0);
        }
        return Math.min(ints.get(0), myRek(ints.subList(1, ints.size())));
    }

(ohne Exeption)

Aber das ist meiner Ansicht nach immer noch der funktionale Ansatz, nicht imperativ, prozedural usw.

Am Anfang ist es aber besser, Prozedural anzufangen, meiner Meinung nach, dann auch nachvollziehbar.
 
return list.size() == 1 ? list.get(0) : Math.min(list.get(0), min(list.subList(1, list.size())));
Also: Wenn die Liste 1 Element enthält, dann gib sie dieses zurück.
Sonst: Gibt sie das Minimum des 1ten Elementes und des 2ten Elementes zurück.
Wobei die Rekursion bei der Ermittlung des 2ten Elementes stattfindet, indem die Funktion selbst mit einer um das 1te Element verkürzten Liste aufgerufen wird. Das bedeutet die Funktion wird solange aufgerufen, bis die übergebene Liste nur mehr 1 Element enthält und kehrt dann kontinuierliche zurück. Es wird immer das kleiner der beiden Elemente zurückgegeben.
Ich finde das ist eine schöne Lösung. 🙂
 

Zurück
Oben