Hilfe Bei Uniaufgaben 2. Teil

Hallo Hallo,
wuerde mich wieder riesig freuen wenn ihr mir helfen wuerdet meine Aufgaben fuer diese Woche zu entraetseln.
Es sind insgesammt 7. Die erste habe ich doch tatsaechlich schon alleine geschafft, es hapert bei nr. 2:
„Write a program that takes three integer command-line arguments and prints equal if all three are equal, and not equal otherwise“
Inzwischen haben wir auch gelernt if und while Saetze zu verwenden sowie Loops :slight_smile:
Mein Lösungsansatz war folgender:

   public static void main(String[] args){
      int a = Integer.parseInt(args[0]);
      int b = Integer.parseInt(args[1]);
      int c = Integer.parseInt(args[2]);
      if (a = b && b = c) System.out.println("equal");
      else           System.out.println("not equal");
   }
}

Leider werden folgende Fehler aufgezeigt:

C:\Test>javac EqualOrNot.java
EqualOrNot.java:6: error: bad operand types for binary operator '&&'
if (a = b && b = c) System.out.println("equal");
          ^
  first type:  int
  second type: int
EqualOrNot.java:6: error: incompatible types
if (a = b && b = c) System.out.println("equal");
      ^
  required: boolean
  found:    int
2 errors

Sehe dass es irgendwas mit der boolean variable zu tun hat, aber in der Aufgabe steht doch ich soll int verwenden. Stehe hier mal wieder auf dem Schlauch :frowning:
Freue mich ueber jede Hilfe

= ist eine Zuweisung.
== ist ein Vergleich.

Grüße

Das gleiche Problem hattest du schonmal: http://forum.byte-welt.net/threads/9888-Hilfe-bei-meinen-Uni-aufgaben-gesucht-)?p=61829&viewfull=1#post61829

Versuch aus deinen alten Fehlern zu lernen, sonst landest du schnell im Vorkaumodus und damit kommt man nicht sonderlich weit.

Gruß

In einem if() muss in der Klammer immer ein boolescher Wert raus kommen. damit dein if klappt, muss da a==b && b==c stehen, sonst setzt du a auf den wert von b und dann b auf den wert von c, kein boolescher Vergleich.

Das hat die Meldung aber auch gesagt: Du hast 2 ints die du mit && verbindest, was aber nicht geht, du brauchst ein boolean :slight_smile:

So 3. Aufgabe war ich eigentlich sicher sie richtig gelöst zu haben… aber der cloudcoder sagt leider was anderes :frowning:
Aufgabe 3 lautet: Write a code fragment that prints trueif the double variables x and y are both strictly between 0 and 1 and false otherwise.
Meine Lösung:

	public static void main (String[] args)
	{
		double a = Double.parseDouble(args[0]);
		double b = Double.parseDouble(args[1]);
		boolean isBetween;
		isBetween = (a <= 1);
		isBetween = isBetween && (a >= 0);
		isBetween = isBetween && (b <= 1); 
		isBetween = isBetween && (b >= 0);
		System.out.println(isBetween);
	}
}

Alles klappt super im dosfenster… das was mir im cloudcoder angekreidet wird: Failed_assertion (bei 2 tests… die ich aber nicht sehen kann… diese tests sind geheim?!) Als hint wird noch gesagt: Randwerte beachten? Oh man

*** Edit ***

@Firephonix, hatte sogar schon an dich gedacht und mit den zwei gleichheitszeichen :wink: aber irgendwie bin ich noch zu sehr in mathematischen gleichungen denke ich. Muss nochmal genauer lesen ueber den unterschied, scheine das nicht zu kapieren.
Gruss

hm… was bedeutet strictly between… das ist wieder so eine Mathematiker-Sprech
vielleicht heisst das ja dass die Randwert 0 und 1 eben nicht dazu gehören… was weiss ich…

Warum so kompliziert?

        double a = 0.15;
        double b = 5.38;

        if (a > 0.0 && a < 1.0) {
            if (b > 0.0 && b < 1.0) {
                System.out.println(true);
            } else {
                System.out.println(false);
            }
        } else {
            System.out.println(false);
        }

    }```
bzw.
```public static void main(String[] args) {
        double a = 0.15;
        double b = 0.38;

        if (a > 0.0 && a < 1.0 && b > 0.0 && b < 1.0) {
            System.out.println(true);
        } else {
            System.out.println(false);
        }
    }```

die ersten beiden mit double a = Double.parseDouble(args[0]); bzw dasselbe mit b austauschen und fertig. Wenn beide zwischen 0 und 1 (jeweils ausgeschlossen) liegen wird true ausgegeben, ansonsten false.

Kurze Zwischenfrage:
Was soll hier denn eigentlich rauskommen?
Double.parseDouble(args[0]);

Hab ich noch nie gesehen, und ich bekomme eine IndexOutOfBounds Exception.

Damit das Array befüllt ist, mussst du das Programm von der Kommandozeile aus ausführen. Die Argumente die du dahinter eingibst, sind dann in diesem String[] drinne, keine Kommandos, leeres Array. Startest du es über die IDE ist es standardmäßig leer :slight_smile: Daher auch die AIOOBE

Achso, jetzt weiß ich auch mal endlich was das da soll.^^
Danke :wink:

warum dann nicht gleich
System.out.println (a > 0.0 && a < 1.0 && b > 0.0 && b < 1.0);

Ich bin nicht son Fan davon, längere Berechnungen/vergleiche direkt im return/sout durchzuführen, bis 2 Vergleiche und 4 Berechnungen mach ichs, danach mach ichs davor, finds hübscher.

Und nochmal @ Bene zum ausprobieren:
nimm diese Klasse:


    public static void main(String[] args) {
        double a = Double.parseDouble(args[0]);
        double b = Double.parseDouble(args[1]);
        System.out.println("a = " + a);
        System.out.println("b = " + b);

        if (a > 0.0 && a < 1.0 && b > 0.0 && b < 1.0) {
            System.out.println(true);
        } else {
            System.out.println(false);
        }
    }
}```
Und speicher sie irgendwo ab.
Dann öffne die Kommandozeile und navigiere zu dem Pfad, wo die .java Datei liegt. Geb "javac Between.java" ein und du bekomsmt die .class Datei.
Wenn die Klasse außerhalb eines Packages liegt, kannst du im Verzeichnis bleiben. Sonst gehst du zum Anfang der Paket-Struktur (Default-Package) Dann gibst du "java 'Paket.in.dem.die.klasse.liegt.klasse' (ohne .class) 0.5 1.3" ein. Schon hast du die Ausgabe auf der kommandozeile, mit deinen eingegebenen Zahlen :)

Das Stimmt :slight_smile: der Fehler bei Aufgabe 3 war wohl das >= und <= Zeichen. Es ging nur um < und > :slight_smile:
Die Aufgabe Nr 2 klappt immernoch nicht. Traue mich aber gar nicht mehr wirklich zu Fragen… kommt mir vor als kapiere ich wohl immer die gleichen sachen nicht. Meine Hochachtung ihr Programmierer, das ist gar nicht so einfach wie ich mir das vorgestellt habe :wink:
Ich hoffe das auch noch irgendjemand anders von meinen plumpen Anfaenger Fragen profitieren kann… sogar vielleicht noch gescheiter ist als ich und das alles viel schneller Versteht als ich.

Nr. 2:
http://openbook.galileocomputing.de/javainsel/javainsel_02_004.html
(Gleichheitsoperatoren)

        ArrayList<Integer> al = new ArrayList<Integer>(args.length < 10 ? 10 : args.length);
        for (String string : args) {
            try {
                al.add(Integer.parseInt(string));
            } catch (NumberFormatException nfe) {
                //ignore
            }
        }

        boolean equal = true;
        for (int i = 0; i < al.size() - 1;) {
            if (al.get(i).compareTo(al.get(++i)) != 0) {
                equal = false;
                break;
            }
        }
        System.out.println("equal = " + equal);
    }```

Jetzt lässt sich darüber streiten, ob keine oder genau eine Zahl auch das Kriterium erfüllt.

Compilieren und ausführen tust du wieder so:

[[img]http://abload.de/thumb/2201snk.jpg[/img]](http://abload.de/image.php?img=2201snk.jpg)

[[img]http://abload.de/thumb/111rsdm.jpg[/img]](http://abload.de/image.php?img=111rsdm.jpg)

Nr. 3:
Verwende den Echt-kleiner/größer-als-Operator (arithmetischer, binärer Operator) und das kurzschließende Oder/Und (logischer, binärer Operator; kein bitweiser Operator).

@iKnwWhtUDidLast : damit hilfst du @Annefranz nicht (Diese Aufgabe ist übrigens schon im Thread gelöst worden. Wenn du versuchen würdest gezielt zu helfen und keine Komplettlösung vorwerfen würdest, hättest du das bemerkt). Du kannst sie nicht bei den Programmieranfängen gleich mit Collections und Generics erschlagen. Das macht so einfach keinen Sinn und ist für dieses Beispiel auch ein absoluter Overkill. Aus deinem Quellcode ist erst nach längerem Lesen ersichtlich, was er überhaupt macht. Ergo ist der Quellcode schlecht.
Die main-Methode hat bei dir mehrere Aufgaben, was nicht gut ist. Sie parst einmal die Eingabe. Das solltest du in eine Hilfsmethode auslagern:
private static List<Integer> parseInput(String[] input);
Die zweite Aufgabe ist, dass du dann prüfst, ob alle Eingabewerte gleich sind. Das verdient auch eine Hilfsmethode.
private static boolean allEntriesEqual(List<Integer> intList);
Dann verkürzt sich die Main zu einer leserlichen Methode:

    List<Integer> intList = parseInput(args);
    boolean equal = allEntriesEqual(intList);
    System.out.println("equal = " + equal);
}```


      @Schesam : du hast aber mit deinen zwei sout Code dupliziert, was man meiner Meinung nach auch im Kleinen vermeiden sollte. Besser fände ich da dann:
```boolean isBetween = a > 0.0 && a < 1.0 && b > 0.0 && b < 1.0;
System.out.println(isBetween);```
statt einer Verzweigung. Anders sieht es natürlich aus, wenn komplett unterschiedliche Texte ausgegeben werden sollen.


Edit:
 @iKnwWhtUDidLast : ich sehe gerade das Konstruktorargument beim `new ArrayList`. Das ist absolut überflüssig und so wie du es machst, ist es gleich doppelt kompliziert. Was hast du dir dabei gedacht? Entweder gibst du die Anzahl der Parameter als Argument ein, oder du verwendest den Standardkonstruktor.

@iKnwWhtUDidLast

Findest du den Code für das Problem “Write a program that takes three integer command-line arguments and prints equal if all three are equal, and not equal otherwise” tatsächlich gerechtfertigt?
Von Anfängerfreundlich und Lesbar ist das Snippet weit entfernt.

Für 3 Integer a,b,c reicht equal = a == b && b == c && a == c;, das Einlesen klappt ja offenbar schon.

Und wozu sollte sich jemand der mit dem Unterschied zwischen == und = schon Probleme hat mit solchem Unfug beschäftigen?

ArrayList<Integer> al = new ArrayList<Integer>(args.length < 10 ? 10 : args.length);
Wozu den komplizierten Konstruktor? Args ist immer = 3, der default-Konstruktor erzeugt eine initiale Kapazität von 10 und das umkopieren bei wachsenden Listen merkst du meistens nichtmal.
Den Konstruktor mit values kann man nehmen, wenn man weiß, dass gleich 5-Stellige Elemente in die Liste kommen, aber in dem Zahlenbereich ist das Fliegenschiss im Speicher, der direkt auf Kosten von Lesbarkeit geht.

//ignore
}```
No comment... geb das einem Anfänger und die nächste Frage ist mit 98% Wahrscheinlichkeit: "Ich hab da jetzt was eingegeben, aber nichts passiert"
 
```boolean equal = true;
for (int i = 0; i < al.size() - 1;) {
if (al.get(i).compareTo(al.get(++i)) != 0) {
equal = false;
break;
}
}```

schreib das in eine Methode, dann fliegt schonmal das break raus, der snippet reduziert sich dann sehr leicht auf
```for(int i = 0; i < al.size() -1; i++){
if(!al.get(i).equals(al.get(i+1))){
return false;
}
}
return true;
}```

Seinen Kollegen tut man bei for-Schleifen auch einen Gefallen, wenn man die "gewohnte" Form so weit wie möglich einhält.
Den Compare-Salat kannst du dir hier auch schenken, siehe auch den JavaDoc dazu: 
> Returns: the value 0 if this Integer is equal to the argument Integer

System.out.println("equal = " + equal);

Edit:  @cmrudolph  War schneller :) Schön zu sehen, dass ich nicht der Einzige bin, den das stört

Gruß

Halli hallo,
das problem ist ja auch noch, dass das ganze ein Einstiegskurs ist. Der Prof sagte, wenn man Lösungen verwendet mit Material was nicht durchgenommen wurde, gibt es Punktabzug. Also muss man sich einfacher mittel bedienen. Zum glueck haben wir ja jetzt if saetze und loops :slight_smile: Also nochmal habe ich jetzt diese == verwendet und auch den boolean:

    public static void main(String[] args){
        int a = Integer.parseInt(args[0]);
        int b = Integer.parseInt(args[1]);
        int c = Integer.parseInt(args[2]);
        boolean isEqualOrNot;
        if isEqualOrNot = (a == b) && (b == c) System.out.println("equal");
        else           System.out.println("not equal");
    }
}

Kommt das hier heraus:
C:\Test>javac EqualOrNot.java
EqualOrNot.java:7: error: ‚(‘ expected
if isEqualOrNot = (a == b) && (b == c) System.out.println(„equal“);
^
EqualOrNot.java:7: error: ‚)‘ expected
if isEqualOrNot = (a == b) && (b == c) System.out.println(„equal“);
^
2 errors

Wie jetzt der gute erwartet ein < und ein > zeichen, sagt er mir… ja das ist ja nett dass das erwartet wird, ist aber leider nicht die Aufgaben stellung :wink:

Nein, er erwartet ( und ein ). Es müsste also so aussehen

if(isEqualOrNot = (a == b) && (b == c)) {

} else {

}

Wobei du dir die Variable isEqualOrNot schenken kannst, da sie nie wirklich verwendet wird. Also könnte dein IF auch so aussehen:

if(a==b && b==c) {
}

Desweiteren würde ich dir empfehlen auch immer die geschweiften Klammern {} zu nutzen wie ich oben den Code-Beispielen.

Zu guter letzt: die Java-Tags ;-). Ich sehe du bemühst dich diese zu nutzen, aber es ist noch ein Fehler drin. die Tags enden so: [noparse]```[/noparse], du hast aber [noparse][\JAVA][/noparse] geschrieben. Bitte da in Zukunft drauf achten. Des weiteren wäre es toll, wenn du als deinen Code für die Leserlichkeit besser einrücken könntest (wie ich es auch als nachträglich für dich gemacht habe). Danke :slight_smile:

Zusätzlich zu @Tomate_Salat s Ausführungen habe ich noch einen Punkt: der Variablenname isEqualOrNot ist äußerst irreführend. Wenn man den Inhalt der Logik des Namens nach betrachtet, müsste dort immer true drinstehen, denn entweder sind die Werte gleich, oder eben nicht. Verständlicher wäre areEqual.
Außerdem solltest du vermeiden, in einer if-Bedingung eine Zuweisung zu machen (das nennt sich übrigens Seiteneffekt).

Eine der wenigen Stellen, in denen Exceptions zur Programmflusssteuerung angezeigt sind.

Methoden hatte @Annefranz doch noch gar nicht. Ob Collections/imports und Generics/diamond operators jetzt eher hinderlich sind, vermag ich nicht zu sagen. Noch sind sie bei einer festen Anzahl an Parametern, aber was, wenn sich das mal ändern sollte? “if”-Abfrage/Bedingung und “for”/“while”-Schleifen ( http://www.if-schleife.de/ ) hatten sie jedenfalls schon.

Alternative, welche keine Komplettlösung sein soll:


        Integer[] integerArray = new Integer[args.length];
        int idx = 0;
        for (String string : args) {
            try {
                integerArray[idx++] = Integer.parseInt(string); // zuerst rechte Seite ausgewertet
            } catch (NumberFormatException nfe) {
                //ignore
                System.out.println(nfe);
            }
        }

        boolean areEqual = true;
        for (idx--; idx > 0;) {
            if (!integerArray[idx].equals(integerArray[--idx])) {
                areEqual = false;
                break;
            }
        }
        System.out.println("areEqual = " + areEqual);
    }```

Edit: Sorry, das muss lauten: ```                integerArray[idx] = Integer.parseInt(string); // zuerst rechte Seite ausgewertet
                idx++;```