Java-Programm zur Ausgabe von Zuständen

Hansi3899

Aktives Mitglied
Hallo zusammen,

ich habe ein Problem beim Programmieren eines Programms. Ich möchte gerne mit Hilfe eines Java-Programms:
1. Abfrage: Wie oft sollen 1 und 0 mit einander kombiniert werden? (z.B. 4 Mal)
2. Ausgabe: Zustandsanzahl 2^4=16 Zustände
3. Ausgabe der Zustände unter einander: 0000, 0001, 0010, 0100, 1000, 1100, 1110, 1111, ect --> diese Zustände sollen automatisiert erstellt werden und ausgeben werden.

Hat jemand eine Idee wie Punkt 3 im Code aussehen soll? Ich habe nämlich keine Idee.

Mit freundlichen Grüßen
Hansi2245
 
E gibt hier mehrere Ansätze, die möglich sind.

Ein Ansatz ist immer, sich das Problem anzusehen um zu schauen, ob es irgend eine Form eines bekannten Problems ist. Dann kann man das bekannte Problem direkt nutzen um zu der Lösung zu kommen.

Hier könnte einem auffallen, dass es einfach um eine binäre Darstellung von Zahlen geht. Und zwar der Zahlen von 0 bis 2^n -1. Also bei 4 wären das die Zahlen von 0 (binär: 0000) bis 2^4-1 = 15 (binär: 1111). Somit reicht eine einfache Zählschleife von [0 ... 15] und einer Ausgabe der zählvariable im binären Format mit 4 Stellen.

Wenn man so eine direkte Lösung nicht sieht, dann geht immer der normale Weg:
  • Wie schaffst Du es, alle Kombinationen selbst aufzuschreiben? Schaffst Du das für 1, 2, 3, ... Stellen? Nimm Dir Stift und Papier und mache es selbst
  • Wenn Du das geschafft hast: Überlege Dir, was Du genau gemacht hast. Kannst Du das aufschreiben?

Ziel ist eine genaue Beschreibung in Worten (!! Also kein Java! Vergiss Java!), so dass jede beliebige Person der Beschreibung folgen kann ohne dass diese Person die Aufgabe kennt.

Hier kann man also z.B. auf die Idee kommen, dass man feststellt:
a) Bei einer Stelle hat man "0" und "1".
b) bei n Stellen hat man "0" + jede Lösung von (n-1) sowie "1" + jede Lösung von (n-1) .... der + Operator ist hier so wie bei Java das Zusammenfügen von zwei Strings zu einem String.
==> Siehe da - man hat sofort eine rekursive Lösung, die man bauen kann.
 
Die Schleife ist falsch: for (int j = n; j >= 1; --j)

Überlege Dir noch einmal, um wie viele Stellen Du die 1 verschieben musst bei z.B. 4 Stellen. Derzeit verschiebst Du um 4, 3, 2, 1 Stellen. Mal es Dir einfach einmal auf, was da für binäre Werte heraus kommen.
 
Java:
Aufgabe wie folgt gelöst:

import java.util.Scanner;
import java.lang.Math;

/*
1. Abfrage: Wie oft sollen 1 und 0 mit einander kombiniert werden? (z.B. 4) --> erledigt!

2. Ausgabe: Zustandsanzahl 2^4=16 --> erledigt

3. Ausgabe der Zustände unter einander: 0000, 0001, 0010, 0100, 1000, 1100, 1110, 1111, etc
--> diese Zustände sollen automatisiert erstellt werden.
*/

public class Zustaende
{
    public static void main (String[] args)
    {
         Scanner scan = new Scanner( System.in );
        
         int n;
         int x=2;
         double y;
         int i=0;
         int zahl;
        
         System.out.println( "Wie oft sollen 0 und 1 mit einander kombiniert werden?" );
         System.out.println( "Geben Sie N ein:" );
        
         n = scan.nextInt();
        
         y=Math.pow(x,n);
        
         System.out.println( "Zustandsanzahl = "+ y);
                
          do {    i++;
        
         System.out.print (i+" ");

        for (int j = n-1; j >= 0; --j) {
            if ((i & (1 << j)) == (0))
                System.out.print('0');
                
                
            else
                System.out.print('1');
                                        
        }

        System.out.println();
        
        } while (i<y);
        
    }
}
 
Hallo @KonradN

vielen Dank für deine Lösungsvorschläge. Jetzt habe ich eine neue Aufgabe mir gesetzt. Ich will nicht nur 1 und 0 mit einander kombinieren, sondern 0, 1, 2.

Hättest Du hier eine Idee? Ich zerbreche mir gerade den Kopf und komme nicht darauf wie ich nun noch die 2 unterschieben soll.
 
Die Lösungsideen sind doch genau gleich. Was Du bisher hast an Lösung ist ja:
  • Eine Schleife, die die Zahlen durchgeht (Du hast [1..2^n] genommen statt dem [0.. 2^n -1] wie ich es vorgeschlagen hatte, aber das macht keinen Unterschied, da es sich wiederholt)
  • in der Schleife zeigst Du die Zahl an zur Basis 2.

Alles, was sich jetzt ändert, ist doch, dass die Zahlenbasis nicht mehr 2 sondern 3 ist.
  • Äußere Schleife über 1 .. 3^n
  • Darstellung der Zahl zur Basis 3 in der Schleife
 
Hallo @KonradN

Könntest Du bitte einen Code posten? Ich stehe auf dem Schlauf. Als Anfänger fällt es mir schwer deinen Ausführungen zu folgen. Auch wenn das für Dich ganz einfach erscheint.

Vielen Dank im Voraus.
 
An was genau scheitert es denn?

Es sind ja zwei Schritte:
a) die äußere Schleife - das hast Du doch bestimmt hinbekommen, oder?
b) die Darstellung einer Zahl zu einer beliebigen Basis - wenn Du eine zahl abcd mit Basis x hast (a,b,c,d sind Elemente aus den möglichen Ziffern), dann ist der Wert a*x^3 + b*x^2 + c*x^1 + d *x^0
Spiel das einfach einmal durch mit x = 10:
1234 ist ja 1*10^3 + 2*10^2 + 3*10^1 + 4*10^0

Wenn Du die einzelnen Ziffern von der Zahl 1234 haben willst, dann rechnest Du immer %10 und dann / 10 um die Zahl zu bekommen, mit der Du weiter rechnest:
1234 % 10 = 4 -> erste Ziffer (Einerstelle)
1234 / 10 = 123 -> Wir rechnen mit 123 weiter
123 % 10 = 3 -> zweite Ziffer (Zehner)
123 / 10 = 12 -> Wir rechnen mit 12 weiter
Das geht so weiter, bis man dann am Ende eine 0 hat.

Wenn Du nun statt Basis 10 die Basis 3 haben willst, dann rechnest Du abwechselnd % 3 und dann für die übrigen Ziffern / 3 um den Wert zu bekommen, um weiter zu rechnen.

Sind damit die beiden Schritten deutlich geworden? Kannst Du damit den Code selbst anpassen?
 
Hallo @KonradN
soweit so gut, aber ich verstehe deinen Lösungsansatz nicht. Ich kann so ohne weiteres keinen Code erstellen. Die For-Schleife eignet sich nicht für drei Zahlen. Da muss es eine andere Lösung geben. Es sei denn du kann den Code anpassen? Wäre echt super lieb von Dir.
 
Ich verstehe nicht wie ich die For-Schleife umschreiben soll, sodass dort Platz frei wird für die Zahl 2?
Bis her kommt dort nur 1 und 0 vor. Aber jetzt ist die Aufgabe die 2 hinzuzufügen.

Java:
for (int j = n-1; j >= 0; --j) {
            if ((i & (1 << j)) == (0))
                System.out.print('0');
                
            else
                System.out.print('1');

Welche Bedingung kann man hier einfügen? Geht es überhaupt mit der For-Schleife?

Gruß
Hansi2245
 
Nein, der Algorithmus geht komplett und Du gibst die Datei aus mit der 3er Basis. Den Algorithmus dazu habe ich beschrieben:
Wenn Du die einzelnen Ziffern von der Zahl 1234 haben willst, dann rechnest Du immer %10 und dann / 10 um die Zahl zu bekommen, mit der Du weiter rechnest:
1234 % 10 = 4 -> erste Ziffer (Einerstelle)
1234 / 10 = 123 -> Wir rechnen mit 123 weiter
123 % 10 = 3 -> zweite Ziffer (Zehner)
123 / 10 = 12 -> Wir rechnen mit 12 weiter
Das geht so weiter, bis man dann am Ende eine 0 hat.

Wenn Du nun statt Basis 10 die Basis 3 haben willst, dann rechnest Du abwechselnd % 3 und dann für die übrigen Ziffern / 3 um den Wert zu bekommen, um weiter zu rechnen.
Sprich: Du hast eine Schleife für die Elemente und Du hast dann immer, dass Du die Ziffer bekommst mit % und die Zahl zum weiter rechnen mit /.
 
Ich bin nicht fit genug in Java um aus deinen Beschreibungen einen Algorithmus zu machen. Da mich aber deine Lösung interessiert wäre ich dir dankbar, wenn du das als Code ausformulierst.

Gibt es jemand anderen im Forum, der einen leichteren Ansatz hat?
 
Gibt es jemand anderen im Forum, der einen leichteren Ansatz hat?

Hier kann man also z.B. auf die Idee kommen, dass man feststellt:
a) Bei einer Stelle hat man "0" und "1".
b) bei n Stellen hat man "0" + jede Lösung von (n-1) sowie "1" + jede Lösung von (n-1) .... der + Operator ist hier so wie bei Java das Zusammenfügen von zwei Strings zu einem String.
==> Siehe da - man hat sofort eine rekursive Lösung, die man bauen kann.

Das wäre eine andere Lösung.

Und Der Code, um eine Zahl im 3er System zu bekommen, wäre:
Java:
    public static String convertToBase3(int number) {
        if (number == 0) {
            return "0";
        }
        
        StringBuilder result = new StringBuilder();
        while (number != 0) {
            result.append(number % 3);
            number /= 3;
        }
        
        return result.reverse().toString();
    }

Das kann man auch mit einer festen Anzahl an Stellen machen:
Java:
    public static String convertToBase3(int number, int length) {

        int count = 0;
        StringBuilder result = new StringBuilder();

        while (number != 0 || count < length) {
            result.append(number % 3);
            number /= 3;
            count++;
        }
        
        return result.reverse().toString();
    }
 
Das reverse() muss raus damit die Konvertierung die richtige Zahl ergibt.

[Edit: Hatte es zuerst auf die falsche Stelle bezogen - sorry. Ich lasse es aber mal stehen]

Das denke ich nicht. Denn er fängt ja mit den Ziffern von rechts nach links an und hat ein Append. Die Einser sind also dann links. Und da wir ja die kleinste Nummer rechts haben wollen, muss da ein reverse sein:

Java:
   public static void main(@NotNull final String[] args) {
        System.out.println(convertToBase3(5, 4));
    }

    public static String convertToBase3(int number, int length) {

        int count = 0;
        StringBuilder result = new StringBuilder();

        while (number != 0 || count < length) {
            result.append(number % 3);
            number /= 3;
            count++;
        }

        return result.reverse().toString();
    }

Ausgabe: 0012
 
Hallo @KonradN

vielen Dank für den Code.

Dein zweiter Code schein wohl zu stimmen. Ich habe ein paar Zahlen ausprobiert. Aber es hängt noch auf dem Automatismus. Ich wollte ein Programm, dass eigenständig alle Kombinationen ausgibt (untereinander). Dein Programm gibt einzelne Werte aus. Kannst Du in dieser Hinsicht eine Anpassung vornehmen? Es sollen alle 27 Möglichkeiten für die Zahlen 0,1,2 ausgegeben werden. Weißt du was ich meine? Vielen Dank im Voraus!

Gruß
Hansi 2245
 
Nein sorry du hattest recht es muss umgedreht werden . Mein Denkfehler! Die Funktion heißt ja convertToBase3
Ah ok.

Ich habe jetzt auch noch einmal den rekursiven Algorithmus geprüft - der würde so wie angegeben auch die richtigen Zahlen ergeben. Einfach mal schnell getestet:

Java:
    public static void main(@NotNull final String[] args) {
        System.out.println(createAllAlterations(3, 4).toString());
    }

    public static List<String> createAllAlterations(int basis, int length) {
        List<String> elements = IntStream.range(0, basis)
                .mapToObj(String::valueOf)
                .toList();

        if (length == 1) return elements;

        List<String> result = new ArrayList<>();
        List<String> previousElements = createAllAlterations(basis, length - 1);
        for (String element: elements) {
            for (String previousElemnent : previousElements) {
                result.add(element + previousElemnent);
            }
        }
        return result;
    }

Ausgabe:
Code:
[0000, 0001, 0002, 0010, 0011, 0012, 0020, 0021, 0022, 0100, 0101, 0102, 0110, 0111, 0112, 0120, 0121, 0122, 0200, 0201, 0202, 0210, 0211, 0212, 0220, 0221, 0222, 1000, 1001, 1002, 1010, 1011, 1012, 1020, 1021, 1022, 1100, 1101, 1102, 1110, 1111, 1112, 1120, 1121, 1122, 1200, 1201, 1202, 1210, 1211, 1212, 1220, 1221, 1222, 2000, 2001, 2002, 2010, 2011, 2012, 2020, 2021, 2022, 2100, 2101, 2102, 2110, 2111, 2112, 2120, 2121, 2122, 2200, 2201, 2202, 2210, 2211, 2212, 2220, 2221, 2222]

Aber es hängt noch auf dem Automatismus. Ich wollte ein Programm, dass eigenständig alle Kombinationen ausgibt (untereinander). Dein Programm gibt einzelne Werte aus. Kannst Du in dieser Hinsicht eine Anpassung vornehmen? Es sollen alle 27 Möglichkeiten für die Zahlen 0,1,2 ausgegeben werden. Weißt du was ich meine? Vielen Dank im Voraus!
Das war ja nur die Lösung ohne die äußere Schleife. Du musst natürlich die äußere Schleife von 0... 3^n -1 haben. Und das hattest Du ja schon:

Code:
         int n;
         int x=3; // Statt 2 ist es hier 3!
         double y;
         int i=0;
         int zahl;
        
         System.out.println( "Wie oft sollen 0 und 1 mit einander kombiniert werden?" );
         System.out.println( "Geben Sie N ein:" );
        
         n = scan.nextInt();
        
         y=Math.pow(x,n);
        
         System.out.println( "Zustandsanzahl = "+ y);
        
         do {
                System.out.println(convertToBase3(i, n)); // Aufruf für jede Zahl
                i++; // Ans Ende geschoben
         } while (i<y);
 
Ich habe es hinbekommen, alles zusammenzufügen. Vielen Dank @KonradN

Noch eine kleine Frage. Mit der For-Schleife geht es nicht oder? Ist aus meiner Sicht die elegantere Lösung. Hast Du eine Idee?

Java:
import java.util.Scanner;
import java.lang.Math;

public class Test3
{
       
           
     public static void main (String[] args)
    {
         Scanner scan = new Scanner( System.in );
         int n;
         int x=3; // Statt 2 ist es hier 3!
         double y;
         int i=0;
         int zahl;
       
         System.out.println( "Wie oft sollen 0, 1 und 2 mit einander kombiniert werden?" );
         System.out.println( "Geben Sie N ein:" );
       
         n = scan.nextInt();
       
         y=Math.pow(x,n);
         System.out.println( "Zustandsanzahl = "+ y);
       
       
         do {
                System.out.println(convertToBase3(i, n)); // Aufruf für jede Zahl
                i++; // Ans Ende geschoben
                System.out.print (i+" ");
         } while (i<y);
}
public static String convertToBase3(int number, int length) {

        int count = 0;
        StringBuilder result = new StringBuilder();

        while (number != 0 || count < length) {
            result.append(number % 3);
            number /= 3;
            count++;
        }
       
        return result.reverse().toString();
    }

}
 
Du willst die do/while Schleife in eine for Schleife umwandeln? Dann schau Dir doch einfach einmal an, was da in der for Schleife angegeben wird.

Du hast eine Zählvariable i und du hast eine Initialisierung, einen Check ob das Ende erreicht ist und eine Veränderung der Zählvariable. Du kannst die Schleife also 1:1 umwandeln.
 
Hallo @KonradN

ich habe mich falsch ausgedrückt. Ich suche für diese Lösung eine Erweiterung, damit die For-Schleife drei Zahlen mit einander kombiniert.

Java:
for (int j = n-1; j >= 0; --j) {
            if ((i & (1 << j)) == (0))
                System.out.print('0');
                
            else
                System.out.print('1');


Hast Du eine Idee wie das aussehen soll? Ich bin mal wieder überfragt...

Vielen Dank im Voraus.
 
Die Deklarierung / Initialisierung ist doch: int i=0;
Der Check ist: i<y
Und die Erhöhung der Zählvariable ist: i++;

Das musst Du nur in die for Schleife ziehen:
for (int i=0; i<y; i++) {

Ansonsten bleibt alles so, wie bisher auch schon. In der Schleife rufst Du dann die convert Methode auf.
 
Hallo @KonradN

hast Du auch keine Idee wie es ohne die convert-Methode geht? Ich will eine einfache For-Schleife damit drei Zahlen mit einander kombiniert werden.

Z.B. so aber da kommt falsches Ergebnis raus:

Code:
import java.util.Scanner;
import java.lang.Math;

public class ABC
{
   public static void main (String[] args)
    {
         Scanner scan = new Scanner( System.in );
        
         int n=3;
         int m=2;
         int x=3;
         double y;
         int vi=0;
         int zahl;
        
    
         y=Math.pow(x,n);
        
         System.out.println( "Zustandsanzahl = "+ y);
            
    
    do {vi++;
        
            System.out.print (vi + "   ");
        for (int f = 2; f >= 0; --f) {
            
            if ((vi & (1 << f)) == (0))
                System.out.print('0');
            else if ((vi & (2 >> f)) == (0))
                System.out.print('1');
            else
                System.out.print('2');
              
         }
        
        System.out.println();
    } while (vi<y);
    }
}
 
Hallo @KonradN

Es geht nicht um die Methode. Ich versuche jetzt eine Lösung mit der For-Schleife hinzubekommen. Siehst Du dort einen Ansatz? Oder ist das unmöglich?

Gruß
Hansi2245
 
Ich verstehe schlicht nicht, was Du genau versuchst. Der Ansatz mit dem
Java:
        for (int f = 2; f >= 0; --f) {
            
            if ((vi & (1 << f)) == (0))
                System.out.print('0');
            else if ((vi & (2 >> f)) == (0))
                System.out.print('1');
            else
                System.out.print('2');
              
         }
ist doch von der Logik her schlicht falsch.

Das funktioniert im Dualsystem, da die Darstellung ja mit Bits ist und damit dual, aber jetzt geht es bei den Zahlen um das Dreiersystem. Da macht das keinerlei Sinn.

Egal was Du programmieren willst: Du musst immer erst die fachliche Komponente verstanden haben. Das war der Grund, wieso ich das eine oder andere Erläutert hatte zu der Lösung.
 
Hallo @KonradN

Es geht nicht um die Methode. Ich versuche jetzt eine Lösung mit der For-Schleife hinzubekommen. Siehst Du dort einen Ansatz? Oder ist das unmöglich?
Also ich verstehe Dein Problem auch nicht. @KonradN hat Dir bereits eine Lösung geliefert.
Falls Du auf die Methode verzichten willst ( was zwar nicht zu empfehlen ist ) kannst Du anstatt des Methodenaufrufs den Code aus der Methode in Deine Schleife integrieren.

Hier eine Variante mit der Methode von @KonradN
Java:
import java.util.Scanner;

public class StartCombineSymbols {
    private final static Scanner input = new Scanner(System.in);

    public static void main(String[] args) {
        String symbols = "012"; // definiert die verwendeten Symbole
        String label = "Bitte die Anzahl der Stellen\nfuer die Kombinationen\nder Symbole ( " + symbols
                + " ) eingeben?\n";
        int numDigits = inputInt(label, 2, 10); // liest ein Zahl von 2 - 10 ein
        int numCombination = (int) Math.pow(symbols.length(), numDigits);
        System.out.println("Anzahl der Kobinationen = " + numCombination);
        for (int num = 0; num < numCombination; num++)
            System.out.println(convertIntDigitsToSymbols(num, symbols.toCharArray(), numDigits));
    }

    public static String convertIntDigitsToSymbols(int number, char[] symbols, int minLenght) {
        StringBuilder result = new StringBuilder();
        int base = symbols.length;
        while (minLenght-- > 0 || number != 0) {
            result.append(symbols[number % base]);
            number /= base;
        }
        return result.reverse().toString();
    }

    private static int inputInt(String label, int min, int max) {
        boolean ok = false;
        int value = 0;
        do {
            System.out.print(label + "-> ");
            try {
                value = Integer.parseInt(input.next());
                if (value < min || value > max)
                    System.out.println("Wert muss im Bereich [" + min + "-" + max + "] liegen");
                else
                    ok = true;
            } catch (NumberFormatException e) {
                System.out.println("Bitte eine Zahl eingeben!");
            }
        } while (!ok);
        return value;
    }

}
 
Hallo @Blender3D und @KonradN

ich wollte eigentlich nur ein paar Zahlen mit einander kombinieren und siehe da ich habe ein sehr mächtiges Programm von Euch zur Verfügung gestellt bekommen. Vielen Dank. Ich spiele mal damit ein bischen herum.
 
Ich spiele mal damit ein bischen herum.
Wie das auch schon @Blender3D richtig gesagt hat: Es ist wichtig, die Logik dahinter zu verstehen. Und die ist unabhängig vom Programmcode.

Du musst also die Problematik, die gelöst wird, an sich verstanden haben. Das ist immer der erste Schritt. Du setzt Dich also hin und denkst über das Problem nach. Du recherchierst ggf. und dann spielst Du die Problematik mit Stift und Papier durch.

Das ist mit der härteste Teil der Software Entwicklung: Ein Problem verstehen und in Teilprobleme unterteilen.

Aber natürlich macht es am Anfang Sinn, mit dem Code zu spielen. Da geht es dann aber nur darum, die Sprachkonstrukte von Java zu verstehen. Also das was z.B. in #26 angeklungen ist mit der Umwandlung einer while Schleife in eine for Schleife und so. Es ist also wichtig, dass Du möglichst viel mit Java machst um die Sprache selbst gut zu lernen.

Aber die zwei unterschiedlichen Problembereiche sollten klar sein.
 
Hallo zusammen,

ich habe zwei neue Anfänger-Fragen. Beim Ändern von Integer auf Long habe ich zwei Probleme.

Wieso wird hier Undeclared Method inputLong angezeigt?
Java:
long numDigits = inputLong(label, 2, 10);

Und hier wird incompatible types: possible lossy conversion from long to int angezeigt als Fehler.
Code:
result.append(symbols[number % base]);

Hier der gesamte Code:

Java:
import java.util.Scanner;

public class Test_drei_Zahlen
{
    private final static Scanner input = new Scanner(System.in);

    public static void main(String[] args) {
        String symbols = "123"; // definiert die verwendeten Symbole
        String label = "Bitte die Anzahl der Stellen\nfuer die Kombinationen\nder Symbole ( " + symbols
                + " ) eingeben?\n";
        long numDigits = inputLong(label, 2, 10); // liest ein Zahl von 2 - 10 ein
        long numCombination = (long) Math.pow(symbols.length(), numDigits);
        System.out.println("Anzahl der Kobinationen = " + numCombination);
        for (long num = 0; num < numCombination; num++)
        System.out.println(num + convertIntDigitsToSymbols(num, symbols.toCharArray(), numDigits));
        
    }

    public static String convertIntDigitsToSymbols(long number, char[] symbols, long minLenght) {
        StringBuilder result = new StringBuilder();
        long base = symbols.length;
        while (minLenght-- > 0 || number != 0) {
            result.append(symbols[number % base]);
            number /= base;
        }
        return result.reverse().toString();
    }

    private static long inputInt(String label, long min, long max) {
        boolean ok = false;
        long value = 0;
        do {
            System.out.print(label + "-> ");
            try {
                value = Long.parseLong(input.next());
                if (value < min || value > max)
                    System.out.println("Wert muss im Bereich [" + min + "-" + max + "] liegen");
                else
                    ok = true;
            } catch (NumberFormatException e) {
                System.out.println("Bitte eine Zahl eingeben!");
            }
        } while (!ok);
        return value;
    }

}

Mit freundlichen Grüßen
Hansi2245
 
Die Methode heisst noch immer inputInt, auch wenn sie ein Long zurück gibt.

Und wenn du einen long zu einem int machst, dann werden Bits abgeschnitten. Wenn du eine mathematische Operation von einem long mit einem int hast, dann wird der int zu einem long, die Operation wird mit long ausgeführt und das Ergebnis ist ein long. Und den verwendest du, wo ein int erwartet wird.

Ansonsten ist der Code unleserlich. Wie kommst du zu so dubiosen Code?
minLength— > 0 in der Bedingung der while Schleife?

Mach pro Zeile immer nur eine Sache …. Dann bleibt es auch für Dich lesbar
 
Hallo @KonradN

danke für das Feedback. Der Code wurde von @Blender3D geschrieben . Ich bin dabei den Code zu verstehen und wollte diese Frage auch demnächst stellen.

Java:
while (minLenght-- > 0 || number != 0) {
            result.append(symbols[number % base]);
            number /= base;

Nun habe ich ein Problem mit dem % base. Es wird mir die Fehlermeldung incompatible types: possible lossy conversion von long to int. Ich habe alles in long geändert. Wieso sagt dann das Programm mir, dass ich long in int umwandeln möchte mit dieser Funktion. Sowohl base als auch number sind als long angelegt.

Java:
import java.util.Scanner;

public class Test_drei_Zahlen_long
{
    private final static Scanner input = new Scanner(System.in);

    public static void main(String[] args) {
        String symbols = "123"; // definiert die verwendeten Symbole
        String label = "Bitte die Anzahl der Stellen\nfuer die Kombinationen\nder Symbole ( " + symbols
                + " ) eingeben?\n";
        long numDigits = inputLong(label, 2, 10); // liest ein Zahl von 2 - 10 ein
        long numCombination = (long) Math.pow(symbols.length(), numDigits);
        System.out.println("Anzahl der Kobinationen = " + numCombination);
        for (long num = 0; num < numCombination; num++)
        System.out.println(num + convertLongDigitsToSymbols(num, symbols.toCharArray(), numDigits));
       
    }

    public static String convertLongDigitsToSymbols(long number, char[] symbols, long minLenght) {
        StringBuilder result = new StringBuilder();
        long base = symbols.length;
        while (minLenght-- > 0 || number != 0) {
            result.append(symbols[number % base]);
            number /= base;
        }
        return result.reverse().toString();
    }

    private static long inputLong(String label, long min, long max) {
        boolean ok = false;
        long value = 0;
        do {
            System.out.print(label + "-> ");
            try {
                value = Long.parseLong(input.next());
                if (value < min || value > max)
                    System.out.println("Wert muss im Bereich [" + min + "-" + max + "] liegen");
                else
                    ok = true;
            } catch (NumberFormatException e) {
                System.out.println("Bitte eine Zahl eingeben!");
            }
        } while (!ok);
        return value;
    }

}
 
Nun habe ich ein Problem mit dem % base. Es wird mir die Fehlermeldung incompatible types: possible lossy conversion von long to int. Ich habe alles in long geändert. Wieso sagt dann das Programm mir, dass ich long in int umwandeln möchte mit dieser Funktion. Sowohl base als auch number sind als long angelegt.
Der Zugriff auf ein Array ist ein int. Du gibst aber ein long.
JLS 15.10.3: Chapter 15. Expressions (oracle.com)
The index expression undergoes unary numeric promotion (§5.6). The promoted type must be int, or a compile-time error occurs.
 
Der Zugriff auf ein Array ist ein int. Du gibst aber ein long.
JLS 15.10.3: Chapter 15. Expressions (oracle.com)

Hallo @KonradN

sagen wir mal ich will nun nach dem ich Zahlen geordnet habe, Zahlen und Sonderzeichen gemeinsam ordnen. Dann reicht aber Integer nicht aus. Ich brauche dann am besten Double.

Muss dann ein neuer Code her?

Oder kann ich diesen umschreiben, sodass die Range für Double greift?

Mit freundlichen Grüßen
Hansi2245
 
sagen wir mal ich will nun nach dem ich Zahlen geordnet habe, Zahlen und Sonderzeichen gemeinsam ordnen. Dann reicht aber Integer nicht aus. Ich brauche dann am besten Double.
Das ist jetzt wieder schwer zu verstehen... Generell solltest Du Dir immer genau überlegen, was für Daten Du speichern willst um dann einen brauchbaren Datentyp zu verwenden.

Wenn Du Sonderzeichen haben willst, also nicht nur Zahlen, dann wird Dir ein Format, das Zahlen speichert, wohl kaum weiterhelfen. Double speichert Gleitkommazahlen.

Hier ist daher die Frage, was genau Du speichern willst. Es könnte z.B. ein char sein. Das kann ein Zeichen speichern. Das ist aber nur ein 16 Bit Wert, der speichert nicht alle Zeichen. UTF benötigt bis zu 32 Bit. Daher bräuchtest Du ggf. auch mehr als nur ein char. Was Du verwenden könntest, wäre z.B. String. String kann mehrere Zeichen abbilden und hat daher auch keine Probleme mit allen Zeichen die im Bereich UTF definiert sind.
 
Hallo @KonradN

gibt es einfache Möglichkeit die Berechnungen automatisiert zwischen zuspeichern, sodass die Berechnung nicht abbricht?

Mein Problem mit dem Programm ist, dass sich Bluej nach einer gewissen Zeit aufhängt. Ich aber die Berechnung bis zum Ende gerne als Text-Datei hätte.

1. Start der Berechnung: Ausführung des Programms
2. Zwischenspeichern nach 1000 Schritten
3. Cache löschen
4. Berechnung wird ab Schritt 1001 fortgesetzt.

Lässt sich sowas in Java realisieren? Gibt es fertige Befehle? Meine Recherche hat nichts ergeben.

Mit freundlichen Grüßen
Hansi2245
 
Ich kenne BlueJ nicht. Evtl. ist das da eine Limitation oder so? BlueJ ist schon relativ speziell bezüglich Instanzen von Klassen zu erzeugen, die dann von BlueJ verwaltet werden und bei denen man dann beliebige Methoden aufrufen kann. Das mag ganz am Anfang evtl. interessant sein, aber wenn die Limitationen nicht ok sind, dann wäre es ggf. Zeit, eine vernünftige Java Entwicklungsumgebung zu nutzen.
 
@Blender3D @KonradN

ich habe zwei Probleme. Wisst Ihr zufällig eine Vorgehensweise?

1. Ich bekomme die Error-Meldung: Out of memory.
2. Integer in der For-Schleife ist nicht groß genug. Ändern auf Long hat bei mir nicht funktioniert. Wie kriege ich das Programm hin, sodass über die Range von Integer hinaus die For-Schleife weiter läuft?

Derzeit benutze ich das Programm von @Blender3D.

Java:
import java.util.Scanner;

public class Kombination_Programm_1 {

    

        private final static Scanner input = new Scanner(System.in);

        public static void main(String[] args) {
            String symbols = "0123456789!§$%&?+*#-.,"; // definiert die verwendeten Symbole
            String label = "Bitte die Anzahl der Stellen\nfuer die Kombinationen\nder Symbole ( " + symbols
                    + " ) eingeben?\n";
            int numDigits = inputInt(label, 2, 27); // liest ein Zahl von 2 - 27 ein
            int numCombination = (int) Math.pow(symbols.length(), numDigits);
            System.out.println("Anzahl der Kobinationen = " + numCombination);
            for (int num = 0; num < numCombination; num++)
            System.out.println(convertIntDigitsToSymbols(num, symbols.toCharArray(), numDigits));
            
        }

        public static String convertIntDigitsToSymbols(int number, char[] symbols, int minLenght) {
            StringBuilder result = new StringBuilder();
            int base = symbols.length;
            while (minLenght-- > 0 || number != 0) {
                result.append(symbols[number % base]);
                number /= base;
            }
            return result.reverse().toString();
        }

        private static int inputInt(String label, int min, int max) {
            boolean ok = false;
            int value = 0;
            do {
                System.out.print(label + "-> ");
                try {
                    value = Integer.parseInt(input.next());
                    if (value < min || value > max)
                        System.out.println("Wert muss im Bereich [" + min + "-" + max + "] liegen");
                    else
                        ok = true;
                } catch (NumberFormatException e) {
                    System.out.println("Bitte eine Zahl eingeben!");
                }
            } while (!ok);
            return value;
        }

    }

Mit freundlichen Grüßen
Hansi2245
 
Evtl. macht es mehr Sinn, einem Kurs oder Lehrbuch zu folgen, damit Du die Grundlagen der Reihe nach lernst und so deutlich mehr verstehst?

Sorry, wenn ich das so direkt sage:
Im Augenblick sehe ich wenig Ansätze, Dir wirklich zu helfen. Ich denke nicht, dass es wirklich viel bringt, Dir eine Code Anpassung zu geben, ohne es im Detail zu erklären. Und auch dann dürfte es noch ein Problem sein, dass Du mit Code arbeitest, den Du vermutlich nicht vollständig verstanden hast.

In kurz:
  • Wenn der Wertebereich von int nicht ausreicht, dann muss man long nehmen. Wenn der auch nicht reicht, dann könnte man BigInteger nehmen.
  • Bezüglich OutOfMemoryException sehe ich nicht wirklich die Ursache. Es werden massiv Instanzen erzeugt, aber eigentlich sollte der GC Platz machen, wenn es notwendig ist. Evtl. reicht es, wenn man Java beim Start mehr Speicher gibt.
 
ich habe zwei Probleme. Wisst Ihr zufällig eine Vorgehensweise?

1. Ich bekomme die Error-Meldung: Out of memory.
2. Integer in der For-Schleife ist nicht groß genug. Ändern auf Long hat bei mir nicht funktioniert. Wie kriege ich das Programm hin, sodass über die Range von Integer hinaus die For-Schleife weiter läuft?
2) Zum Wertebereich von int bzw long in Java
1682635962331.png
Wie du gut erkennen kannst ist mit long eine Zahl mit bis zu 19 Stellen möglich.
Du möchtest aber 22^27 = 1.759.. x 10^36 also 37 Stellen realisieren.
Dafür gäbe es wie @KonradN bereits erwähnt hat BigInteger.
1) Das Out Of Memory kann nicht von Java kommen, da jede erzeugte Zahl an die Ausgabe geschickt wird. Möglicherweise hat die Commandozeile damit ein Problem wenn du so eine immense Zahl von 27 stellige Strings speichert. Aber das habe ich noch nie gemacht ist also nur eine Vermutung meinerseits.
Falls das das Problem ist könnte man die Zahlen in eine Datei speichern anstatt sie auszugeben.
 
@Blender3D

1. Die Ausagabe in eine Datei umleiten habe ich hinbekommen. Jetzt wird mir die Fehlermeldung out of memory nicht mehr angezeigt.
2. Beim Umstellen des Codes auf BigInteger habe ich Probleme. Abhilfe täte gut. Kannst Du mir einen Tipp geben. Ich bekomme lauter Fehlermeldungen. Das sind zu viele um Sie hier zu posten.

Gruß
Hansi2245
 
2. Beim Umstellen des Codes auf BigInteger habe ich Probleme. Abhilfe täte gut. Kannst Du mir einen Tipp geben. Ich bekomme lauter Fehlermeldungen. Das sind zu viele um Sie hier zu posten.
Ein Tip wäre: Mach es richtig.
Ehrlich, ohne zu wissen, was schiefläuft, kann's auch keine Tips geben, wie man's besser macht.
Halt dir vor Augen, dass BigInteger kein primitiver Datentyp ist und sämtliche Operationen über dessen Methoden ausgeführt werden.
 

Neue Themen


Zurück
Oben