Java Verständnisfrage zum Einbau einer Schleife

violentviper

Lt. Commander
Registriert
Mai 2008
Beiträge
1.821
Hallo,
ich habe eine Verständnisfrage zu meinem kleinem Java Programm. Das Programm liest einen Integer ein (max. 4 stellig) und rechnet dann bei Binärerer Eingabe(z.B 1010) in das dezimale Ergebnis (10) um.
Das funktioniert auch soweit gut, jedoch ohne Schleifen.

Und genau hier ist mein Problem, laut Buch soll man es mittels einer for Schleife lösen. Aber ich weiß beim besten Willen nicht wo ich hier eine Schleife überhaupt reinbauen könnte.

Ich dachte mir Anfangs bei den einzelnen digits, die ich dann hochzähle, aber dann komme ich in Verzug mit der Wertigkeit der einzelnen Stellen, welche für die Berechnung von Bedeutung sind. Bei der Endberechnung, sehe ich auch nicht wo ich da sinnvoll eine Schleife reinbauen könnte.

Wäre nett wenn mir hier jemand auf die Sprünge helfen könnte.

Code:
import java.util.Scanner;


public class BinaerToDecimal {

	public static void main(String[] args) {
		
		System.out.print("Geben sie die Zahl ein ");
		Scanner input = new Scanner(System.in); //Tastatureingabe
		
		int i = input.nextInt();
		int result= 0;

		
		int digit1 = ((i/1000) % 10);						// Digitabfrage	
		int digit2 = ((i/100) % 10);
		int digit3 = ((i/10) % 10);
		int digit4 = ((i/1) % 10);
		
		if (digit1>1 | digit2>1 | digit3>1 | digit4>1)
			System.out.println("Ihr Wert wurde normiert, indem Zahlen>1 als 1 interpretiert wurden :");
		
		
		if (digit1>1)				// normiert den Wert für Zahlen>1 auf 1 
			digit1=1;
		if (digit2>1)
			digit2=1;
		if (digit3>1)
			digit3=1;
		if (digit4>1)
			digit4=1;
		
		
			result=(digit4*1)+(digit3*2)+(digit2*4)+(digit1*8);			
		System.out.println(result);
		
	}

}
 
Eine Schleife eignet sich ja, um sich wiederholende Codefragmente zu ersetzten. In deinem Code sind davon 3:
Code:
int digit1 = ((i/1000) % 10);	// Digitabfrage
int digit2 = ((i/100) % 10);
int digit3 = ((i/10) % 10);
int digit4 = ((i/1) % 10);
sowie
Code:
if (digit1>1)	// normiert den Wert für Zahlen>1 auf 1
digit1=1;
if (digit2>1)
digit2=1;
if (digit3>1)
digit3=1;
if (digit4>1)
digit4=1;
und
Code:
result=(digit4*1)+(digit3*2)+(digit2*4)+(digit1*8);
(nicht ganz so offensichtlich, aber "(digiti*x)+" wiederholt sich 4 mal)

Jetzt musst du schauen, welche Unterschiede es innerhalb der Codefragmente gibt. Im ersten Beispiel wäre es nur die Zahl, durch die i geteilt wird. Jetzt muss man sich überlegen, wie man diese Änderung durch die Laufvariable der Schleife ausdrücken kann. Sagen wir, deine Laufvariable läuft von 1 bis 4, so kann man die Zahl ersetzten durch (10^(4-n))
Das sollten erstmal genug Ansatzpunkte sein, ich will ja nicht alles vorwegnehmen ^^

MFG
Scree
 
Du kannst dir in der Schleife jeweils die letzte Stelle angucken und entsprechend ihrer Wertigkeit (2^i*Wert an der Stelle) zu deinem Ergebnis addieren.

Hier gibts noch ein paar Tipps, aber du solltest es in deinem eigenen Interesse ersteinmal ohne versuchen.
Den Wert der letzten Stelle bekommst du indem du mod 10 rechnest.
Dann rückst du die Zahl weiter indem du durch 10 teilst.
Deine Wertigkeit der Stelle multiplizierst du in jeder Iteration mit 2.
 
Scree schrieb:
Eine Schleife eignet sich ja, um sich wiederholende Codefragmente zu ersetzten. In deinem Code sind davon 3:
Code:
int digit1 = ((i/1000) % 10);	// Digitabfrage
int digit2 = ((i/100) % 10);
int digit3 = ((i/10) % 10);
int digit4 = ((i/1) % 10);
sowie
Code:
if (digit1>1)	// normiert den Wert für Zahlen>1 auf 1
digit1=1;
if (digit2>1)
digit2=1;
if (digit3>1)
digit3=1;
if (digit4>1)
digit4=1;
und
Code:
result=(digit4*1)+(digit3*2)+(digit2*4)+(digit1*8);
(nicht ganz so offensichtlich, aber "(digiti*x)+" wiederholt sich 4 mal)

Jetzt musst du schauen, welche Unterschiede es innerhalb der Codefragmente gibt. Im ersten Beispiel wäre es nur die Zahl, durch die i geteilt wird. Jetzt muss man sich überlegen, wie man diese Änderung durch die Laufvariable der Schleife ausdrücken kann. Sagen wir, deine Laufvariable läuft von 1 bis 4, so kann man die Zahl ersetzten durch (10^(4-n))
Das sollten erstmal genug Ansatzpunkte sein, ich will ja nicht alles vorwegnehmen ^^

MFG
Scree

Auf die Idee mit der Laufvariable bei den 10er Potenzen bin ich auch schon gekommen. Nur habe ich da das Problem, das innerhalb der for-Schleife immer alle Werte durchgerasselt werden und somit meine Wertigkeit zerstört wird. Ich habe schon versucht mit break und continue zu arbeiten aber das ist nicht Zielführend gewesen.

Soll konkret heißen, wenn ich jetzt z.B hier 1 eintrage, werden alle 4 Digits auf 1 gesetzt , da jedes Digit alle Potenzen durchläuft. Genau das will ich verhindern, aber bekomme es nicht hin.

Kann man irgendwie sagen, das innerhalb der Schleife die 10^3 nur für Digit 1 gilt, 10^2 nur für Digit2 etc. ?
Genau das ist das Problem.


PS: Bis ich erstmal bemerkt habe das Java 10^3 garnicht kennt sondern das über die Mathmethode machen muss... :D



Code:
		for (int n = 0; n <=3 ; n++)
		{
			
			a = (int) Math.pow(10, 3-n);					// Potenz	 10^(3-n)
			
			digit4 = ((i/a) % 10);
			digit3 = ((i/a) % 10);
			digit2 = ((i/a) % 10);
			digit1 = ((i/a) % 10);		
			
		}
 
Hi,
also im moment hast du durch deine Schleife ja noch nichts gewonnen. Diee Zeile digiti = ((i/a) % 10); wiederholt sich ja immernoch 4 mal.
Im momment scheinst du noch das Problem zu haben, an deinen 4 Variablen für die Digits festzuhalten. Das geht zwar auch, aber dafür bräuchte man eine Strucktur, die man über die Laufvariable der Schleife ansprechen kann (wie z.B. eine Liste/Array).
Einfacher ist es hier aber, in einem Schleifendurchlauf ein Digit komplett abzuarbeiten, also
1. Digit bestimmen,
2. ggf. auf 1 setzten
3. seinen Wert für das resultat bestimmen
4. auf das resultat aufaddieren.

Wenn du diese 4 Schritte in einem Durchlauf abarbeitest, sind die verwendeten Variablen im nächsten Durchlauf wieder frei und können überschrieben werden.

Hoffe das hilft ein bisschen.

MFG
Scree
 
Du musst dich mal von deinen Variablen digit1 - digit4 verabschieden. Pro Iteration wird nur eine Stelle betrachtet. Dadurch bist du auch nicht auf vierstellige Zahlen festgenagelt sondern kannst beliebig* große Zahlen bearbeiten. Sondai hat doch die Lösung im Prinzip schon gepostet. Ist zwar kein Java aber das sollte trotzdem hinreichend verständlich sein.


*wenn es der Datentyp zulässt
 
Ich habs jetzt so gemacht, das ich für jedes Digit eine eigene for Schleife verwendet habe. Das funzt auch für max. 4 Stellige Integer. Das ist nach meinem jetzigen geringen Java Kenntnis Stand noch am nachvollziehbarsten bis jetzt.

Aber schöner finde ich da trotzdessen die Schleifenlose Lösung.


Code:
	public static void main(String[] args) {
		
		Scanner input = new Scanner(System.in); 
		
		System.out.print("Binäre Zahl eingeben : ");
		
		int i = input.nextInt();
		int digit =0, result=0;	
		int x =0;						// Potenzspeicher

			for (int n=0; n <=3 ; n++)		// Potenzerzeugung
		{
			x = (int) Math.pow(10, 3-n);	// x=10^(3-n)
			
			
			digit=((i/x) % 10);			//letzte Stelle
			
		}
		result=digit;
		
		
		for (int n=1; n>=0; n--)
		{
			
			x = (int) Math.pow(10, 1-n);
			
			digit=((i/x)%10);	
			
		}
	
		result=result+digit*2;
		
		for (int n=2 ; n >=0 ; n--)
		{
			x = (int) Math.pow(10, 2-n);
			
			digit=((i/x) % 10);	
		}
	
		result=result+digit*4;
		
		for ( int n = 3 ; n >= 0 ; n--)
		{
			x = (int) Math.pow(10, 3-n);
			digit=((i/x)%10);	
		}
	
		
		result=result+digit*8;
		
		System.out.println("Dezimales Ergebnis: "+result);
	
	}

}
 
Verwende doch einfach mal eine Schleife wie sie verwendet werden soll und mach dir mal klar was die Problemstellung ist!


Also...

Eine Zahl wird eingeben, welche eine binäre Zahl darstellt. Jede Ziffer >0 wird als 1 betrachtet.
  1. Problem: Wie erhält man alle Ziffern der Zahl?
    1. Teilproblem: letzte Ziffer erhält man mit
      Code:
      n % 10
    2. Teilproblem: letzte Ziffer muss normaliziert werden -> eine Abfrage
    3. Teilproblem: Wie kann man durch die Zahl navigieren, damit nach und nach alle Ziffern betrachtet werden?
      Code:
      n = n/10
      damit wird immer die niedrigstwertige Ziffer verworfen
    4. Teilproblem: Wann haben wir alle Ziffern betrachtet? - Genau dann, wenn n gleich 0 ist. (oder <=0 falls irgendwer negative Zahlen eingibt!)
    Daraus bauen wir jetzt den ersten Teil
    Code:
    for(; n > 0;) {
      int z = n%10;
      if(z > 0) {
        // hier dezimal zahl berechnung
      }
      n = n/10;
    }
  2. Problem: Wie bekommt man jetzt die Dezimaldarstellung?
    1. *Wir wissen, dass wir von n immer die niedrigste Ziffer nehmen, also müssen wir 2^i, wobei i der x'te Schleifendurchlauf ist. 2^i kann einfach
      Code:
      for(int x=1; ...; x *=2) {
      
      }
      gemacht werden
    2. Wie jetzt die Dezimalzahl wo wir die einzelnen x=2^i immer berechnet haben? -> einfach aufsummieren
    Damit bauen wir jetzt die Endschleife zusammen

    Code:
    int dezimal = 0;
    
    for(int x=1; n > 0; x*=2) {
      int z = n%10;
      if(z > 0) {
        dezimal+=x;
      }
      n = n/10;
    }
  3. Letztes Problem: Sind wir sicher dass wir nicht aus dem Bereich von Int rauslaufen?
    - Kann nicht passieren, da n schneller sich verkleinert als dass x groß wird. Weiterhin sind wir sicher dass negative n einfach direkt ignoriert werden und die Dezimalzahl = 0 ist!

Daraus ergibt sich dann der gesamte Code (den ich nicht getestet habe sondern nur angepasst!)

Code:
import java.util.Scanner;

public class BinaerToDecimal {

	public static void main(String[] args) {
		
		System.out.print("Geben sie die Zahl ein ");
		Scanner input = new Scanner(System.in); //Tastatureingabe
		
		int i = input.nextInt();
		int result= 0;

		for(int x=1; i>0; x*=2) {
			if( i%10 > 0) {
				result+=x;
			}
			i = i/10;
		}			
		System.out.println(result);	
		
		input.close();
	}
}
 
Zuletzt bearbeitet:
Danke Sondai für dein Mühe und die gute Erklärung.
Aber ich will ehrlich sein, auf deine Kurzversion wäre ich nicht draufgekommen. Ich bin schon froh wenn die verlangte Funktion erfüllt wird, ob umständlich programmiert oder nicht. Aber klar sollte man sich angewöhnen effektiv zu programmieren. Genau das ist halt der Haken, ich hoffe mal das es mit der Zeit und der Erfahrung kommt. Als Anfänger tu ich mir da noch schwer. Noch hab ich die Hoffnung, das man mit der Zeit sowas einfach "sieht".
 
Zurück
Oben