Iteriertes Querprodukt

PcIv

Mitglied
Hallo,
ich habe mit der Hilfe von paar Youtube-Videos angefangen etwas zu programmieren und habe im Internet die Anregung bekommen, mal ein Programm zu machen, welches das iterierte Querprodukt von Zahlen berechnet. Also das Querprodukt einer Zahl und von dem Ergebnis wieder das Querprodukt, bis eine einstellige Zahl auftritt. (Querprodukt heißt das Produkt der Ziffern einer Zahl)
Das Programm soll die jeweils kleinsten Zahlen ausgeben die, 1-10 Schritte benötigen.
Bin schon relativ weit aber komsicherweise werden die ersten beiden Zahlen falsch ausgegeben und ich verstehe nicht warum.
Das Programm gibt aus:

1 Schritte braucht die Zahl:11
2 Schritte braucht die Zahl:26
3 Schritte braucht die Zahl:39
4 Schritte braucht die Zahl:77
5 Schritte braucht die Zahl:679
6 Schritte braucht die Zahl:6788
7 Schritte braucht die Zahl:68889
8 Schritte braucht die Zahl:2677889
9 Schritte braucht die Zahl:26888999
10 Schritte braucht die Zahl:378888999

Die erste Zahl sollte jedoch 10, und die 25 sein. Weiß jemand wo mein Fehler liegen könnte?

Ich hoffe mein Code ist für euch verständlich, ist natürlich wahrscheinlich sehr umständlich und schlecht geschrieben.

Java:
public class QP {
   public static void main(String[] args) {
     long zwerg = 9L;
     short ausgabe = 0;
     long schritte = 0L;
     short vglausgabe = 0;
     long zwerghelfer = 0L;

     //Schleife Zahlen testen
     while (schritte < 10000000000L) {
       schritte ++;
       zwerghelfer++;
       zwerg = zwerghelfer;
       ausgabe = 0;

       // Schleife: Iteriertes Querprodukt
       while (zwerg > 10 ) {
         ausgabe++;
         long[] ziffern;
         ziffern = new long [11];
         ziffern[0]= 1;
         ziffern[1]= 1;
         ziffern[2]= 1;
         ziffern[3]= 1;
         ziffern[4]= 1;
         ziffern[5]= 1;
         ziffern[6]= 1;
         ziffern[7]= 1;
         ziffern[8]= 1;
         ziffern[9]= 1;
         ziffern[10]= 1;

         long n = 0;
         long modz = 10;

         short schleife = 0;
         short arraylaufzahl = 0;

         // Anzahl der Ziffern bestimmen
         int stellen = String.valueOf(zwerg).length();

         //Letzte Ziffer
         n = zwerg % modz;
         ziffern[0] = n;
         ///Schleife geht los zur Ziffernbestimmung

         while (schleife < 10) {
           modz = modz *10;
           n = ((zwerg % modz) - n)/ (modz/10);
           arraylaufzahl++;
           ziffern[arraylaufzahl] = n;
           schleife++;
         }

         // Ziffern im Array gespeichert

         // Querprodukt bilden
         short laufzahl = 0;
         long zzwerg = 1;
         while (laufzahl < stellen ) {
           zzwerg = zzwerg*ziffern[laufzahl];
           zwerg = zzwerg;
           laufzahl++;
         }
       }

       if (ausgabe > vglausgabe) {
         vglausgabe = ausgabe;
         System.out.println(ausgabe + " Schritte braucht die Zahl:" + zwerghelfer);
       }
     }
   }
}



Noch eine Frage wäre, wie ich so ein Programm optimieren kann. Die 10 Zahl zu finden dauert sehr lange, vielleicht 7 min. Hat da jemand einen Tipp?

Danke!

Liebe Grüße

PcIv
 
Zuletzt bearbeitet von einem Moderator:

InfectedBytes

Top Contributor
deine variablennamen sind ein wenig unsinnig(zwerg, zwerghelfer,...)
dann ist die äußere schleife auch recht zweifalhaft: while(schritte < 10000000000L)
Und was genau erhoffst du dir hiervon?
Java:
long[] ziffern;
         ziffern =newlong[11];
         ziffern[0]=1;
         ziffern[1]=1;
         ziffern[2]=1;
         ziffern[3]=1;
         ziffern[4]=1;
         ziffern[5]=1;
         ziffern[6]=1;
         ziffern[7]=1;
         ziffern[8]=1;
         ziffern[9]=1;
         ziffern[10]=1;

Außerdem solltest du das ganze besser in mehrere Methoden splitten.
Zum Beispiel wäre es sinnvoll eine Methode zu schreiben, welche das Querprodukt einer Zahl berechnet, das ganze kannst du dann iterativ oder auch rekursiv lösen und zwar ohne den ganzen quatsch mit dem array.
Hiermal rekursiv:
Java:
public static int querprodukt(int value) {
 if(value<10) return value;
 return querprodukt(value/10) * (value%10);
}

Da du ja das ganze solange anwenden willst, bis das ergebnis einstellig ist, kannst du das ganze in eine schleife packen:
Java:
public static int querproduktBisEinstellig(int value) {
 while(value>=10) {
  value = querprodukt(value);
 }
 return value;
}
 

CSHW89

Bekanntes Mitglied
Da gibt es so einige Möglichkeiten, das schneller zu machen. Zunächst kann man sich überlegen, dass wenn du das Querprodukt von z.b. 26 berechnest, ist dies 12. Dessen Querprodukt, bzw. die Anzahl der Schritte von 12 hast du schon vorher berechnet, und machst dies wieder. Man kann schon viel sparen, wenn man die Anzahl der Schritte jeder Zahl speichert. Mit 1 GB Speicher kann man auch alle Zahlen bis 10 Stellen speichern.
Dann ist der Algorithmus auch recht einfach:
Code:
Erstelle Array 'anzahl' mit 1000000000 Stellen vom Typ byte
Setze für i = 1..9: anzahl[i] = 0
Mache für i = 10..1000000000 ...
  Berechne Querprodukt qp von i
  Setze anzahl[i] = anzahl[qp] + 1 // qp wurde schon berechnet und in 'anzahl' gespeichert

Das ziffern-Array zu berechnen kann man auch optimieren. Du berechnest bei jeder Zahl die Ziffern immer wieder neu, und dann das Produkt. Besser wäre es neben der Zahl 'i' das Array 'ziffern' weiterlaufen zu lassen. Also in jedem Schritt, in dem man i erhöht, die nullte Position (die nullte sind die Einer, die erste sind die Zehner usw..) um eins erhöhen. Wenn dieser Wert 10 ist, auf 0 setzen und die erste Position erhöhen. Wenn diese dabei 10 erreicht, die zweite erhöhen, usw...

Und zu guter letzte kann das Querprodukt einer Zahl auch schneller berechnet werden. Man speichert für jede Stelle das Produkt dieser Stelle und aller höherwertigen Stellen. Also z.b. bei der Zahl 32584 hat man ein Array [4*8*5*2*3, 8*5*2*3, 5*2*3, 2*3, 3]. Die nullte Stelle des Arrays ist immer das Querprodukt. Wenn man i nun um eins erhöht, nimmt man das Ergebnis an der ersten Stelle '8*5*2*3' und multipliziert dies mit dem neuen Einer, also 5, und speichert es an die nullte Stelle des Arrays und hat [5*8*5*2*3, 8*5*2*3, 5*2*3, 2*3, 3]. Beim Ziffernübertrag nimmt man demendsprechend die zweite Stelle und berechnet die erste Stelle neu.

lg Kevin
 

PcIv

Mitglied
Vielen dank für die ausführlichen Antworten! Stimmt ich merke, dass das Array ziemlich überflüssig war, ich kann das j ain einem Schritt machen. Ich probiere das mal so wie du es gesagt hast InfectedBytes und melde mich dann!
Danach versuche ich mich mal an dem Tipp mit dem riesen Array zur Optimierung!
Liebe Grüße
PcIv
 

PcIv

Mitglied
Super! Mit Methoden ist das echt viel einfacher:
Java:
public class QPOPT {
   public static long querprodukt(long i){
      if(i<10) return i;
      else{ return querprodukt(i/10) * (i%10);}}

public static long querproduktschleife(long testzahl, long schritte ) {
   schritte = 0;
while(testzahl>=10) {
    schritte++;
  testzahl = querprodukt(testzahl);
}
return schritte;
}
 
   public static void main(String[] args) {
     long testwert = 9L;
     long vergleich = 0;
   
     while ( querproduktschleife(testwert, 0) <=11){
     testwert++;
   
if (querproduktschleife(testwert, 0) > vergleich){System.out.println(testwert + " ist die kleinste Zahl, die  " + querproduktschleife(testwert, 0) + " Schritte braucht." );
      vergleich = querproduktschleife(testwert, 0);}
   
   }}}


Habe das jetzt etwas umständlich gemacht, um die Anzahl der Schritte rauszubekommen. (mit dieser zweiten Variable "schritte") Geht das vielleicht eleganter?




Und Kevin, ich habe noch nicht ganz verstanden, wie ich das Riesenarray jetzt in meinen code einbauen könnte ... Kannst du mir das vielleicht nochmal genauer erklären?


Vielen Dank,

PcIv
 
Zuletzt bearbeitet von einem Moderator:
Ähnliche Java Themen
  Titel Forum Antworten Datum
V Querprodukt ermitteln Java Basics - Anfänger-Themen 6

Ähnliche Java Themen

Neue Themen


Oben