Java Noobfrage Part II

ralle_h schrieb:
Alles klar.

Noch ne Frage:

Code:
	for (boolA == false){
		boolB = false;
		boolAusgabe = boolA && boolB;
		System.out.println(boolA + " && " + boolB + " liefert " + boolAusgabe);
		boolAusgabe = boolA || boolB;
		System.out.println(boolA + " || " + boolB + " liefert " + boolAusgabe);
		boolAusgabe = boolA ^ boolB;
		System.out.println(boolA + " ^ " + boolB + " liefert " + boolAusgabe);
	}

Was passt ihm an diesem Teil der Schleife nicht?

Compiler meint in der ersten Zeile fehlt ihm ein ";"???

Danke schonmal!

Der Syntax ist
for (Initialisierung; Test; Fortsetzung) Anweisung

wenn Du keine Initialisierung & Fortsetzung brauchst musst dort eben nur das Trennzeichen ";" hin, also in Deinem Fall:
for (;boolA == false; ){

Edit: Das Leerzeichen nach dem letzten ; kann natürlich auch weg .. aber aus ; ) ohne Leerzeichen macht das Forum ;) :D

2nd Edit: Aber so wie die Schleife dann ist wird sie entweder nie, oder Endlos laufen .. (je nachdem welchen Wert boolA hat)
 
Zuletzt bearbeitet:
Letztere Version ist die in der Java-Welt gebräuchlichere.

Hier wäre die while-Schleife das Mittel der Wahl. Grundsätzlich sollte man aber der for-Schleife wann immer möglich den Vorzug geben, weil man hier Schleifenvariablen auf die Schleife begrenzen kann und somit keine unerwünschten Effekte auftreten können (z.B. durch Copy&Paste Fehler). "Minimize the scope of local variables" in "Effective Java" empfiehlt diesen Ansatz.
 
Danke :)

Habs jetzt so zum Laufen bekommen:

Code:
public class Boolen {
	
	public static void main(String[] args) {

	// 1. Definition und Initialisierung der nötigen Variablen
	boolean boolA = false;
	boolean boolB = false;	
	
	// 2. Ausgabe des Kopfes:
	System.out.println("Logische Operatoren:");
	System.out.println("====================");
	
	// 3. Schleifen
	while(boolA==false)
		{
		if(boolB==false)
			{
				System.out.println(boolA + " && " + boolB + " liefert " + (boolA && boolB));
				System.out.println(boolA + " || " + boolB + " liefert " + (boolA || boolB));
				System.out.println(boolA + " ^ " + boolB + " liefert " + (boolA ^ boolB));
				System.out.println();
				boolB = true;
			}
			else 
			{
				System.out.println(boolA + " && " + boolB + " liefert " + (boolA && boolB));
				System.out.println(boolA + " || " + boolB + " liefert " + (boolA || boolB));
				System.out.println(boolA + " ^ " + boolB + " liefert " + (boolA ^ boolB));
				System.out.println();
				boolA = true;
				boolB = false;
			}
			}
	while(boolA==true)
		{
			if(boolB==false)
			{
				System.out.println(boolA + " && " + boolB + " liefert " + (boolA && boolB));
				System.out.println(boolA + " || " + boolB + " liefert " + (boolA || boolB));
				System.out.println(boolA + " ^ " + boolB + " liefert " + (boolA ^ boolB));
				System.out.println();
			boolB = true;
			}
			else 
				{
				System.out.println(boolA + " && " + boolB + " liefert " + (boolA && boolB));
				System.out.println(boolA + " || " + boolB + " liefert " + (boolA || boolB));
				System.out.println(boolA + " ^ " + boolB + " liefert " + (boolA ^ boolB));
				System.out.println();
				break;
				}
			}
		}
	}

Kann man aber sicher noch geschickter und deutlich kürzer hinbekommen^^
 
ralle_h schrieb:
Kann man aber sicher noch geschickter und deutlich kürzer hinbekommen^^

Das wichtigste ist das Du die Verknüpfungen verstehst. :cool_alt:

Aber imho besser lesbar:
Code:
public class Boolen {
  public static void main(String[] args) {
    Print("Logische Operatoren:");
    Print("====================");
    for (int i = 0; i < 2; i++) {
      for (int j = 0; j < 2; j++) {
        boolean boolA = i % 2 == 0;
        boolean boolB = j % 2 == 0;
        Print(boolA + " && " + boolB + " liefert " + (boolA && boolB));
        Print(boolA + " || " + boolB + " liefert " + (boolA || boolB));
        Print(boolA + " ^ " + boolB + " liefert " + (boolA ^ boolB));
        Print("");
      }        
    }
  }

  private static void Print(String txt) {
    System.out.println(txt);
  }
}

P.S: Für einen extra Zeilenvorzub kann man auch "\n" in einem String verwenden,
Print(boolA + " ^ " + boolB + " liefert " + (boolA ^ boolB) + "\n");

bewirkt also das gleiche wie:
Print(boolA + " ^ " + boolB + " liefert " + (boolA ^ boolB));
Print("");
 
lynxx schrieb:
Print(boolA + " ^ " + boolB + " liefert " + (boolA ^ boolB) + "\n");
bewirkt also das gleiche wie:
Print(boolA + " ^ " + boolB + " liefert " + (boolA ^ boolB));
Print("");

Danke, das ist sehr praktisch und gut zu wissen :)

Dein Code ist echt viel kürzer und übersichtlicher, Respekt.

lynxx schrieb:
boolean boolA = i % 2 == 0;
boolean boolB = j % 2 == 0;

Den Teil versteh ich allerdings leider noch nicht. Du hast zunächst nen Counter, der nach dem Durchlauf der Schleife hochzählt 2 mal hochzählt (für jeden Block quasi), aber was prüfst du mit Modulu 2 da genau bzw. was ist der Sinn dahinter?

Danke schonmal!
 
Jep, aber wie genau hilft der Code Teil hier die 4 Textblöcke auf einen zu reduzieren? Da hänge ich grade ^^
 
Zuletzt bearbeitet:
Geh doch die Schleife einfach mal durch:

for (int i = 0; i < 2; i++) {
i = 0
for (int j = 0; j < 2; j++) {
i = 0; j = 0
boolean boolA = i % 2 == 0;
i = 0; j = 0; boolA = ist der Rest von i durch 2 gleich 0? -> boolA = true
boolean boolB = j % 2 == 0;
i = 0; j = 0; boolA = true; boolB = ist der Rest von j durch 2 gleich 0? -> boolB = true
(...)

for (int j = 0; j < 2; j++) {
i = 0; j = 1; boolA = true; boolB = true
boolean boolA = i % 2 == 0;
i = 0; j = 1; boolA = true; boolB = true
boolean boolB = j % 2 == 0;
i = 0; j = 1; boolA = true; boolB = false (1 mod 2 = 1; ist 1 == 0? nein -> false)
usw.



Der "Trick" ist, dass Boolean-Variablen einen Zahlenraum mit genau zwei Elementen haben (nämlich true und false). Nimmt man eine beliebige positive natürlich Zahl und rechnet modulo 2, so kommt da immer 0 oder 1 raus. Auf 0 und 1 wird mit dem Teil "== 0" getestet. Und je nach Testergebnis, springt dann true oder false heraus.
Ganz wichtig und immer beachten: "=" ist nicht "=="!
"=" ist eine Wertzuweisung. "==" ist immer ein Test auf Gleichheit.
Es gab schon x Leute vor dir, die das übersehen haben, etwas a la "if (x = 1)" geschrieben haben und sich hinterher wunderten, warum das Programm nicht richtig läuft.


So was kann man sich auch sehr gut im Debugger-Modus anschauen, wenn man sich die Anweisungen Step-by-step anschaut.
 
Zuletzt bearbeitet:
e-Laurin schrieb:
Es gab schon x Leute vor dir, die das übersehen haben, etwas a la "if (x = 1)" geschrieben haben und sich hinterher wunderten, warum das Programm nicht richtig läuft.
In Java kein Problem, da "x = 1" kein boolscher Ausdruck ist und man somit einen Compilerfehler kassiert.

[Randbemerkung]
Wobei mir neulich ein "erfahrener" C++-Programmierer erzählt hat, dass so was wie
Code:
EineKlasse* pKl;
if (pKl = GetEineKlasse()) { 
    // ... 
}
doch super ist, weil man sich so eine zusätzliche null-Prüfung ersparen kann. :rolleyes:

Das muss jetzt aber bitte nicht wieder in eine große Diskussion über Code-Stil ausarten. Wie gesagt: nur eine Randbemerkung. ;)
[/Randbemerkung]
 
Zuletzt bearbeitet:
Jep, habe fast alles in deinem Post verstanden, bis auf das hier:

e-Laurin schrieb:
Und je nach Testergebnis, springt dann true oder false heraus.

Das ist mir nicht klar, wo das im Code genau passiert.

Es wird ja nirgends definiert wann boolA oder boolB true bzw. false sind (z.B. if i = 0 -> boolA = false), sondern bool wird gleich i (also anfangs 0, dann 1, usw...) gesetzt, was ja eigentlich gar nicht gehen sollte?

:confused_alt::

/edit: Oder ist das so zu verstehen, dass boolA den Wert true/false annimmt, je nachdem ob der Rest der Gleichung stimmt, oder nicht?

/edit2: Grad mit ner Test Klasse getestet... jep, ist so. Mhhh, ich sollte vllt. mehr Theorie lesen bevor ich drauf los "code" :schluck:

-

Okay, hab noch eine Frage. Hier meine Version einer Primfaktorenzerlegung:

Code:
class Prime
{
	public static void main (String[] args)
	{
		int number = Integer.parseInt(args[0]);
		int newNumber = number;
		if(newNumber > 1)
			{
				System.out.print("Primfaktorenzerlegung von " + number + ": ");
				while(true)
				{
					if(newNumber%2==0)
					{
						System.out.print("2 ");
						newNumber = newNumber/2;
					}
					else if (newNumber%3==0)
					{
						System.out.print("3 ");
						newNumber = newNumber/3;
					}
					else if (newNumber%5==0)
					{
						System.out.print("5 ");
						newNumber = newNumber/5;
					}
					else if (newNumber%7==0)
					{
						System.out.print("7 ");
						newNumber = newNumber/7;
					}
					else
					{
						if(newNumber != 1) System.out.print(newNumber);
						break;
					};
				};
			}
			else if(newNumber == 1)
			{
				System.out.print("1 ist keine Primzahl!");
			}
			else 
				System.out.print("Bitte eine natürliche Zahl größer 0 eingeben!");
		}
}

Sollte soweit passen, habs schon ausführlich getestet.

Einziger brainfuck ist... wie krieg ich die Ausgabe mit einem * zwischen den Werten am geschicktesten hin?

System.out.print("2 * ") und System.out.print("* 3 * ")geht ja nicht, sonst hab bei 2 bzw. ein unschönes "2 *" bzw. "* 3 * " als Ausgabe, statt 2 und 3.

Einzige Lösung die mir jetzt einfallen würde, wäre das unten als extra else if einzubauen und so zu machen wie oben beschrieben?
Ergänzung ()

Hab die Ausgabe für die 1 angepasst:

Code:
			// Die Primfaktorzerlegung der 1 besteht aus dem leeren Produkt (welches hier per Definition den Wert 1 hat)
			else if(newNumber == 1)
			{
				System.out.print("Primfaktorenzerlegung von 1: 1");
			}

Passt das so (mathematisch), auch von der Erklärung im Kommentar?
 
Zuletzt bearbeitet:
Der Code ist mathematisch korrekt.

Das "*" Problem kannst Du einfach lösen in dem Du vergleichst ob number != newNumber ist, es also nicht die erste Ausgabe ist und nur in dem Fall wird vor der nächsten Zahl ein "*" ausgegeben.

Aber diese "if", "else if", "else if", "else if" .. Blöcke sind nicht so schön, erstens wird es unübersichtlich, zweitens schlechter wartbar, angenommen Du willst jetzt irgendeine Änderungen in den Blöcken haben, dann musst Du Zigmal Copy & Paste machen und dabei passieren oft Fehler (z.B alte Teile aus versehen stehen gelassen) die auch erstmal gar nicht auffallen weil sie nur in einem der vielen "else if" Blöcke steckt ..

Besser ist für solche "gleichen" Code-Teile entweder eine Unterroutine schreiben, oder das ganze in eine Schleife umzuschreiben (oder beides).
Für die Primfaktorenzerlegung bietet es sich an ein Array innerhalb einer Schleife zu verwende, ich würde das so schreiben:

Code:
class Prime {
  public static void main (String[] args)   {
    int number = 0;
    // Fängt Fehler ab, z.b kein Argument übergeben, oder keine Zahl
    try {
      number = Integer.parseInt(args[0]);
    }
    catch (Exception e) { }
    
    int primZahlen[] = { 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271 };
    String strOutputBegin = "Primfaktorenzerlegung von " + number + ": ";
    String strOutput = "";
    if (number > 0) {
      if (number > 1) {
        int newNumber = number;
        for (int i = 0; i < primZahlen.Length; ) {
          if (newNumber % primZahlen[i] == 0) {
            if (number != newNumber) // Es nicht der erste Durchlauf, zusätzlich * ausgeben
              strOutput += "* ";
            strOutput += primZahlen[i] + " ";
            newNumber /= primZahlen[i];
          }
          else
            i++;
        }
        if (newNumber > 1)
          strOutput += "* " + newNumber;
      }
      else
        strOutput = "1";
    }
    else
      strOutputBegin = "Bitte eine natürliche Zahl größer 0 eingeben!";

    Print(strOutputBegin + strOutput);
  }

  private static void Print(String txt) {
    System.out.println(txt);
  }
}

Das mit "else if's" für Primzahlen bis 271 wäre statt 41 satte 316 Zeilen lang. :evillol:

Ich habe schon lange nichts mehr mit Java gemacht (C# gefällt mir einfach besser :D), aber ich meine " int primZahlen[] = .." war in Java der richtige Syntax, falls es da Probleme gibt, probier " int[] primZahlen = ..".

Edit:
TheCadillacMan schrieb:
[Randbemerkung]
Wobei mir neulich ein "erfahrener" C++-Programmierer erzählt hat, dass so was wie
Code:
EineKlasse* pKl;
if (pKl = GetEineKlasse()) { 
    // ... 
}
doch super ist, weil man sich so eine zusätzliche null-Prüfung ersparen kann. :rolleyes:
...
[/Randbemerkung]
Klar, kann Sinn machen, aber mit sowas kann man sich auch schöne Probleme bereiten sobald da mehrere Bedingungen miteinander verknüpft werden, z.B:

Code:
bool bResult = false;
EineKlasse* pKl;
if (pKl = GetEineKlasse() && bResult = WichtigerAufruf()) { 
    // ... 
}

if (bResult) {
 ...
}
WichtigerAufruf() wird nämlich nur dann ausgeführt wenn GetEineKlasse() einen Wert zurückgegeben hat ..
 
Zuletzt bearbeitet:
Ich habe schon lange nichts mehr mit Java gemacht (C# gefällt mir einfach besser ), aber ich meine " int primZahlen[] = .." war in Java der richtige Syntax, falls es da Probleme gibt, probier " int[] primZahlen = ..".

Beide Möglichkeiten sind richtig und funktionieren.




Das gehört jetzt zwar nicht wirklich zum Projekt, aber...wenn du dir die Werte der Primzahlen rechnerisch ermitteln lassen solltest,dann bietet sich nicht an, ein festes Array zunehmen, wenn man nicht weiß, wie viele Werte es speichern soll.

Oder kennst du alle primZahlen bis 1000 und beschränkst den maximalen zu überprüfenden Wert auf 1000?

Bei sowas würde man eher einen
Code:
Vector<Integer> primzahlen = new Vector<Integer>();
benutzen oder ähnliches, damit man auch einfach den Suchbereich vergrößern kann, ohne das Array zu ändern.

Man kann den Vector auch ohne Generics verwenden und ,,int'' darf man nicht reinschreiben, da es sich um einen primitiven Datentyp handelt, deshalb muss man die Klasse Integer nehmen (Java hat für jeden prim. Datentyp auch eine Klasse).


Könntest du hier einbauen, dass er Primzahlen ermittelt bis zu dem Wert, den der User eingibt. So kannst du auch riesige Werte eingeben, dauert dann halt nur länger. :D
 
Zuletzt bearbeitet:
Besten dank nochmal an Beide, hat mir sehr geholfen.

Insbesondere das hier fand ich auch gut bzw. hab ich mich selbst schon gefragt wie man sowas macht:

Code:
   // Fängt Fehler ab, z.b kein Argument übergeben, oder keine Zahl5.    try {      number = Integer.parseInt(args[0]);    }    catch (Exception e) { }
-

Hab noch ne Frage zu If Schleifen:

Code:
		// 1. Fallunterscheidung - Niederschläge
		if (niederschlaege == true) {
			// 2. Fallunterscheidung für Temperaturen
			if (temp < 0) {
				System.out.print("Schnee");
			}
			if (temp >= 0) {
				System.out.print("Sauwetter");
			}
		}
		
		// 1. Fallunterscheidung - Ohne Niederschläge
		...

Kann ich mir das, wenn ich es nur mit if lösen will, das zweite if (temp >= 0) irgendwie sparen? Oder muss ist das der einzige Weg?

Mersi schonmal!
 
Code:
		// 1. Fallunterscheidung - Niederschläge
		if (niederschlaege) {
			if (temp < 0) {
				System.out.print("Schnee");
			}else {
				System.out.print("Sauwetter");
                        }
		}
		
		// 1. Fallunterscheidung - Ohne Niederschläge
		...

oder alternativ
Code:
else if(bedindung){
              // blubb...
             }

oder, wenn danach die Methode zu ende ist, wie in dem Beispiel jetzt, dann macht man es so


Code:
public int testMethode(){
          int testInt= 2;
          
          if(testInt==2){
                  return 10000;
          }
          return -1;
}

Hier braucht man auch nichtmal else, weil, wenn die eine if-Bedingung und die Schleife dann ausgeführt wird, er auf das return trifft und die Methode gibt was zurück.
 
Zuletzt bearbeitet: (ups, was hat den das break da gemacht...sry^^)
Code:
if (temp < 0) {
} else {
}

ist äquivalent. Wenn eine Zahl nicht < 0 ist, muss sie zwingend >= 0 sein!

Ansonsten verwendet man üblicherweise auch das kürzere

Code:
if (wert) { // test wahr
}

bzw.


Code:
if (!wert) { // test nicht wahr
}
für boolsche Werte.
 
Zuletzt bearbeitet:
Sowas kann man auch mit dem Tenären Operator lösen:
Code:
System.out.print(niederschlaege ? (temp < 0 ? "Schnee" : "Sauwetter") : (temp < 15 ? "Kalt" : "Warm"));

Das entspricht:
Code:
if (niederschlaege) {
  if (temp < 0)
    System.out.print("Schnee");
  else
    System.out.print("Sauwetter");
}
else {
  if (temp < 15)
    System.out.print("Kalt");
  else
    System.out.print("Warm");
}
 
Zurück
Oben