3 Fragen zu ähnlichem Programm

Righteus

Mitglied
Guten Morgen Forum,

Ich habe 3 Probleme/Fragen:

1.) Wir haben mit dem Programm, bei welchem mir letzte Woche geholfen wurde, weitergearbeitet und mein Lehrer hat uns neue Zeilen gegeben, welche ich auch nicht zu 100% verstanden habe, aber darum gehts hier erstmal noch nicht. Das Problem bei dieser Programmzeile ist, dass mir 2 Fehler angezeigt werden, welche eigentlich nicht da sein dürften. Ich hänge euch erstmal das Programm an und dann die Fehler:

Und ja ich weiß die Kommentare sind zu viel, aber die sind nur für mich.

Java:
class Zufallszahlen_keine_doppelt {

   Zufallszahlen_keine_doppelt(){

  boolean flag = false; // solange flag=false -> läuft die Überprüfung/Neugenerierung von a
  boolean added = false; //solange added=false -> läuft die while Schleife
  int a = 0; //Zufallszahl
     int zahl[];
     zahl= new int [10];

     for(int i=0;i<10;i++){

       added = false; //damit nach erfolgreichem Durchlauf der while Schleife diese wieder startet

       while(!added){ //wir wissen nicht, wie viele Durchläufe wir zur "richtigen" Zufallszahl brauchen (darf nicht 1x im Array sein; wenn sie es ist Neugenerierung-> könnte wieder die selbe sein)

         flag = false; // damit die erzeugte Zufallszahl nicht ins Array kommt

         a= (int) (Math.random()*10+1); //Erzeugung Zufallszahl


         for(int index=0;index<i;index++){ //wir wissen wie oft sie laufen muss -> for Schleife; Läuft durch alle bis dorthin vorhandenen Indizies des Arrays

          if(zahl[index] == a){ //Überprüfung, ob Zufallszahl schon im Array ist; durchläuft alle bis dato vorhandenen Indizies

              flag = true; //wenn Zufallszahl schon im Array ist wird falg auf true gesetzt -> d.h. sie kommt nicht durch die nächste if Überprüfung -> while läuft erneut ab

            }//Ende if

          }//Ende for index

          if(!flag){ //Überprüfung, ob flag auf false steht; wenn nicht dann wird die Schleife gar nicht erst gestartet -> while läuft erneut

            zahl[i] = a; // falls die Zufallszahl noch nicht im Array ist wird sie jetzt diesem Überwiesen -> da flag auf false stand -> Zufallszahl noch nicht im Array

            added = true; // damit die while Schleife das erste mal beendet wird und ein neuer Durchlauf mit der neuen Zufallszahl im Array gestartet werden kann

          }//Ende if

        }//Ende while

     }//Ende for i



   for(int z=0;z<zahl.length;z++){ //For Schleife geht solange wie das Array ist

     System.out.println("  "+zahl[z] + "\n"); //gibt so oft wie lang das Array ist die jeweilige Zufallszahl ab Index 0 aus

  }//Ende for z

  System.out.println("Der kleinste Wert liegt auf dem Index: " +b);


  int min (int zahl[]) {

      int element = zahl.length; //größter Wert der Möglich ist

      int rueck = 0; //ist dann der Index von dem kleinsten Wert

      for(int i = 0; i<zahl.length; i++){ //durchläuft alle Indizies

        if(zahl[i] < element){ //Überprüft, ob ein Element kleiner ist als bis dato kleinster Wert

          element = zahl[i]; //wenn er kleiner ist wird er zu neuen kleinsten Wert

          rueck = i; //ist der Index des bis dato kleinsten Wertes

        }//Ende if

      }//Ende for

      return rueck; // wird der Hauptmethode überwiesen

    }//Ende min

    zahl[rueck] = zahl[0]; //gibt Zahl auf Index 0 an die Stelle wo die kleinste Zahl ist

    zahl[0] = element; //kleinste Zahl kommt auf den Index 0

    System.out.println(""+zahl[0] + zahl[rueck]);


}//Ende Methode

   public static void main (String arg[]){

     new Zufallszahlen_keine_doppelt(); //Methode Zufallszahlen_keine_doppelt() wird ausgeführt

   }

}//Ende class

Fehlermeldungen:
Code:
Zufallszahlen_keine_doppelt.java:59: error: ';' expected
  int min (int zahl[]) {
         ^
Zufallszahlen_keine_doppelt.java:59: error: ';' expected
  int min (int zahl[]) {
                     ^

Könnte das vielleicht daran liegen, dass diese ganze int Reihe einfach in der falschen Position steht?

2.) Wir sollen den kleinsten Wert, welcher ja mit dieser int Reihe, die nicht funktioniert, herrausgefunden wird, in dem Array auf Index 0 setzen und die Zahl, die ausgetauscht wird, auf die Index Position des kleinsten Wertes setzen. Da ich meinen Ansatz oben im Programm nicht testen kann wollte ich fragen, ob der richtig wäre.

3.) Mein Programm von letzter Woche sollen wir nun doch optimieren. Daher wollte ich fragen, ob noch einer Ideen dazu hat. Das Programm hänge ich an:
Java:
class Zufallszahlen_keine_doppelt {

   Zufallszahlen_keine_doppelt(){

  boolean flag = false; // solange flag=false -> läuft die Überprüfung/Neugenerierung von a
  boolean added = false; //solange added=false -> läuft die while Schleife
  int a =0; //Zufallszahl
     int zahl[];
     zahl= new int [100000];

     for(int i=0;i<100000;i++){

       added = false; //damit nach erfolgreichem Durchlauf der while Schleife diese wieder startet

       while(!added){ //wir wissen nicht, wie viele Durchläufe wir zur "richtigen" Zufallszahl brauchen (darf nicht 1x im Array sein; wenn sie es ist Neugenerierung-> könnte wieder die selbe sein)

         flag = false; // damit die erzeugte Zufallszahl nicht ins Array kommt

         a= (int) (Math.random()*100000+1); //Erzeugung Zufallszahl

         for(int index=0;index<i;index++){ //wir wissen wie oft sie laufen muss -> for Schleife; Läuft durch alle bis dorthin vorhandenen Indizies des Arrays

          if(zahl[index] == a){ //Überprüfung, ob Zufallszahl schon im Array ist; durchläuft alle bis dato vorhandenen Indizies

              flag = true; //wenn Zufallszahl schon im Array ist wird falg auf true gesetzt -> d.h. sie kommt nicht durch die nächste if Überprüfung -> while läuft erneut ab

  break;

            }//Ende if

          }//Ende for index

          if(!flag){ //Überprüfung, ob flag auf false steht; wenn nicht dann wird die Schleife gar nicht erst gestartet -> while läuft erneut

            zahl[i] = a; // falls die Zufallszahl noch nicht im Array ist wird sie jetzt diesem Überwiesen -> da flag auf false stand -> Zufallszahl noch nicht im Array

            added = true; // damit die while Schleife das erste mal beendet wird und ein neuer Durchlauf mit der neuen Zufallszahl im Array gestartet werden kann

          }//Ende if

        }//Ende while

     }//Ende for i



   for(int z=0;z<zahl.length;z++){ //For Schleife geht solange wie das Array ist

     System.out.println("  "+zahl[z] + "\n"); //gibt so oft wie lang das Array ist die jeweilige Zufallszahl ab Index 0 aus

  }//Ende for z


}//Ende Methode

   public static void main (String arg[]){

     new Zufallszahlen_keine_doppelt(); //Methode Zufallszahlen_keine_doppelt() wird ausgeführt

   }

}//Ende class

Die Empfehlung aus meinem ersten Thread break; zu nutzen habe ich eingefügt. Gibt es sonst noch Möglichkeiten das zu optimieren? Meine erste Idee wäre beim Thema Optimieren ja den Code zu kürzen, aber ich glaube da ist nichts mehr möglich.
 

Flown

Administrator
Mitarbeiter
So ich zeig dir mal wie die Java Konventionen so aussehen, indem ich dein Programm genommen und in die richte Form gebracht habe.

Java:
class ArrayUtils {
 
    public static void main(String... args) {
        int[] ints = ArrayUtils.createRandomArray(1, 10001, 10000);
        System.out.println(Arrays.toString(ints));
    int minIndex = ArrayUtils.min(ints);
    System.out.format("Minimum: %d at %d.", ints[minIndex], minIndex);
    }
 
    /**
     * Returns an array with the specified {@code length}. It contains only
     * distinct elements which are generated within the range from {@code from}
     * to {@code to} (exclusive).
     *
     * @param from
     *          the lower bound
     * @param to
     *          the upper bound (exclusive)
     * @param length
     *          the length of the resulting array
     * @return an array with size {@code length} containing numbers [
     *         {@code from}, {@code to}[
     * @throws IllegalArgumentException
     *           if {@code from < to} or {@code length > to - from}
     */
    public static int[] createRandomArray(int from, int to, int length) {
        if (from < to && length > to - from) {
            throw new IllegalArgumentException();
        }
        int[] randoms = new int[length];
        outer: for (int i = 0; i < length;) {
            int rand = from + (int) (Math.random() * (to - from));
            for (int j = 0; j < i; j++) {
                if (randoms[j] == rand) {
                    continue outer;
                }
            }
            randoms[i++] = rand;
        }
        return randoms;
    }
 
    /**
     * Returns the index of the smallest element in {@code arr}.
     *
     * @param arr
     *          the array to be searched
     * @return index of smallest element; otherwise {@code -1} if {@code arr} is
     *         empty will be returned
     * @throws NullPointerException
     *           if {@code arr} was {@code null}
     */
    public static int min(int[] arr) {
        Objects.requireNonNull(arr);
        int minIndex = -1;
        for (int i = 0; i < arr.length; i++) {
            if (minIndex == -1 || arr[i] < arr[minIndex]) {
                minIndex = i;
            }
        }
        return minIndex;
    }
}
 
Zuletzt bearbeitet:

Righteus

Mitglied
Erstmal danke für die Hilfe, aber ich denke mein Lehrer wird das nicht akzeptieren, da wir die Hälfte deiner Befehle nicht hatten und ich die auch nicht erklären könnte. ^^

Naja egal. Ich sag ihm einfach ich konnte sie nicht weiter machen, weil er mir ja nicht gesagt hat/wollte warum denn da 2 Fehler sind.
 

Dompteur

Top Contributor
Die int() Methode hast du innerhalb der Methode Zufallszahlen_keine_doppelt eingefügt.
In Java kann man keine Methoden verschachteln.

Kopier einfach die min Methode hinter die Methode Zufallszahlen_keine_doppelt
 

Righteus

Mitglied
Sollte ja eigentlich nicht gehen, da sie dann ja nicht ausgeführt wird von der methode. Die muss definitiv vor System.out.println laufen, da dort eine Variabel benötigt wird.

Ich hab sowas am Do das erste mal gesehen und mein Lehrer wollte mir nicht helfen bei dem Fehler. -.-

Hab versucht das mit und ohne ne neue Methode mit class zu packen ging aber auch nicht.
 

Dompteur

Top Contributor
Bei einer Methode musst du zwischen Deklaration und Aufruf unterschieden

So sollte es etwa aussehen.
Java:
class Zufallszahlen_keine_doppelt {
 
    Zufallszahlen_keine_doppelt(){
        ...
        .. = min (zahl);   // Aufruf der Methode
        ...
    }
 
// Deklaration der Methode:
    int min (int zahl[]) {
        ... Befehle der Methode
    }
 
    public static void main (String arg[]){
        new Zufallszahlen_keine_doppelt(); //Methode Zufallszahlen_keine_doppelt() wird ausgeführt
    }
}
 

Saheeda

Top Contributor
@Righteus
Zufallszahlen_keine_doppelt() ist übrigens genau genommen keine normale Methode, sondern ein Konstruktor.
Der Konstruktor ist nur dafür verantwortlich, Instanzen einer Klasse in ein gültiges Format zu bringen / den inneren Zustand einer Klasse gültig zu machen; d.h. Attribute wenn notwendig zu instanziieren bzw. mit Default-Werten zu belegen, wenn keine Parameter übergeben werden.

Meines Erachtens macht dein Konstruktor viel zu viel. Ich würde das wie in Flowns Beispiel in richtige Methoden packen und diese aufrufen.
 

Righteus

Mitglied
Bei einer Methode musst du zwischen Deklaration und Aufruf unterschieden

So sollte es etwa aussehen.
Java:
class Zufallszahlen_keine_doppelt {

    Zufallszahlen_keine_doppelt(){
        ...
        .. = min (zahl);   // Aufruf der Methode
        ...
    }

// Deklaration der Methode:
    int min (int zahl[]) {
        ... Befehle der Methode
    }

    public static void main (String arg[]){
        new Zufallszahlen_keine_doppelt(); //Methode Zufallszahlen_keine_doppelt() wird ausgeführt
    }
}
Ah ok danke! Dann weiß ich ja wo mein Fehler liegt. ^^


@Righteus
Zufallszahlen_keine_doppelt() ist übrigens genau genommen keine normale Methode, sondern ein Konstruktor.
Der Konstruktor ist nur dafür verantwortlich, Instanzen einer Klasse in ein gültiges Format zu bringen / den inneren Zustand einer Klasse gültig zu machen; d.h. Attribute wenn notwendig zu instanziieren bzw. mit Default-Werten zu belegen, wenn keine Parameter übergeben werden.

Meines Erachtens macht dein Konstruktor viel zu viel. Ich würde das wie in Flowns Beispiel in richtige Methoden packen und diese aufrufen.
Das Problem ist ja die Hälfte der Befehle kenn ich nicht bzw. kann sie nicht erklären. Mein Lehrer reißt mir den Kopf ab, wenn ich damit komme. ^^
 

Righteus

Mitglied
So gut wie alle Befehle von dir kenn ich nicht. Daher hat das auch keinen Sinn die mir zu erklären. Wir sind halt recht am Anfang bei Java und hängen auch noch nen halbes Jahr zurück, weil mein Lehrer so lange krank war. Ich bin ja auch nicht in ner Ausbildung oder so, sondern ganz normal in der Schule. ^^

Was mich aber interessieren würde: Gibts denn ordentliches Nachschlagewerk für die Befehle (am besten online^^)? Wir haben zwar sowas an der Schule, aber das ist mega unübersichtlich und damit komme ich gar nicht klar.
 

Flown

Administrator
Mitarbeiter
Das Nachschlagewerk nennt sich Java API und wenn du jetzt nach konkreten Befehlen fragst, erklär ich sie dir auch.

Methoden sind kein Problem und Schleifen, nehm ich an, auch nicht.

Was über den Methoden steht dient nur zur Dokumentation - was man sich am Anfang gleich mit aneignen sollte - und erklärt wie die Methode funktioniert was der Anwender, eben dieser, zu erwarten und zu liefern hat.

Arrays.toString(ints) ist von Java eine convenient function, um ein Array in eine Stringrepräsentation zu bringen (in Form von: [x1, x2, ..., xn])

System.out.format("Minimum: %d at %d.", ints[minIndex], minIndex); ist nichts anderes als System.out.println("Minimum: " + ints[minIndex] + " at " + minIndex + "."); Man kann hier nett den ganzen String mit Platzhalter(%d -> Platzhalter für ganze Zahlen) schreiben ohne eben wie bei der zweiten Variante alles zu Konkatenieren.

throw new IllegalArgumentException(); wirft eine Exception, wenn gewisse Umstände eintreten (kannst du ja in der Dokumentation darüber lesen wann, oder du siehst dir den Code an). Exception sind Ausnahmen, damit kein unerwartetes Verhalten auftreten kann.

outer: for (int i = 0; i < length;) { und continue outer;. Das erste outer: nennt sich ein Label. Damit kannst du bei geschachtelten Schleifen eine Schleifen benennen und diese dann beenden (break <label>;). continue <label>; ist genau das Gegenteil von break und bewirkt, dass an dieser Stelle gestoppt wird und mit der nächsten Iteration, der genannten Schleife, begonnen wird.

Objects.requireNonNull(arr); ist ebenfalls eine convenient function und macht nichts anderes zu prüfen, ob das Array null ist. Wenn ja, dann wird wie oben beschreiben eine NullPointerException geworfen.
 
Zuletzt bearbeitet:

Righteus

Mitglied
Erstmal danke für die Antwort, aber das ist mir irgendwie alles noch zu hoch. ^^

Er haut mir auch zwei Fehlermeldungen raus:
Code:
ArrayUtils.java:5: error: cannot find symbol
  System.out.println(Arrays.toString(ints));
                     ^
symbol:  variable Arrays
  location: class ArrayUtils

ArrayUtils.java:54: error: cannot find symbol
  Objects.requireNonNull(arr);
  ^
  symbol:  variable Objects
  location: class ArrayUtils
2 errors

Prozess beendet mit Exit-Code 1
 

Neue Themen


Oben