Du verwendest einen veralteten Browser. Es ist möglich, dass diese oder andere Websites nicht korrekt angezeigt werden. Du solltest ein Upgrade durchführen oder ein alternativer Browser verwenden.
Hi, habe eine Aufgabe meines Java-Kurses bearbeitet und eigentlich müsste sie meines Wissens nach gelöst sein... anscheinend habe ich aber einen Fehler im Code, den ich einfach nicht finden kann. Normalerweise würde ich nicht so etwas fragen, aber ich habe wirklich mind. eine Stunde überlegt und den Fehler nicht finden können.
Die Aufgabe lautet:
Aufgabe 8:
Eine Natürliche Zahl heißt potent, wenn sie sich als Summe von Potenzen (>= 1) ihrer Ziffern darstellen lässt. Beispielsweise ist 24 wegen 2^3 + 4^2 = 24 potent. Schreiben Sie ein Java-Programm, das alle zweistelligen potenten Zahlen ausgibt.
Mein Lösungsansatz:
Java:
public class potenteZahlen {
public static void main(String[] args) {
long x = 99;
while (x > 9) { // gehe alle Zahlen von 99-10 durch
long ziffer1 = 0;
long ziffer2 = 0;
ziffer1 = x % 10; // erzeuge Ziffer1
ziffer2 = (x/10) % 10; // erzeuge Ziffer2
if (potent(ziffer1, ziffer2, x)) { // ist Zahl potent?
System.out.println(x); // zeige Zahl
}
x--;
}
}
static boolean potent(long ziffer1, long ziffer2, long zahl) {
long a = ziffer1;
long b = ziffer2;
for (int x = 1; x <=9; x++) { // potenziere die Ziffer 9 mal
if (x != 1) { // bei Ziffer^1 keine Potenzierung
ziffer1*=a; // Ziffer1 * Ziffer1 * ....
}
for (int y = 1; y <=9; y++) { // potenziere die Ziffer 9 mal
if (y != 1) { // bei Ziffer^1 keine Potenzierung
ziffer2*=b; // Ziffer2 * Ziffer2 * ....
}
if (ziffer1 + ziffer2 == zahl) { // wenn sich aus den Potenzen Zahl ergibt, dann true
return true;
}
}
}
return false;
}
}
Die Funktion ergibt niemals true. Wo liegt mein Fehler??
Hab jetzt mehrere Methoden zur Berechnung des Problems überlegt, aber es kommt nichts simpels und sehr sinnvolles dabei raus. Auf alle Fälle gehts wohl nicht so einfach, wie du das versuchst Geht wohl eher in Richtung Combinatorics (ausser da gäbts eine Formel).
Auf den ersten Blick würde ich vermuten, dass du in der potent-Methode am Ende der jeweiligen Schleife ziffer1 und ziffer2 mit a unb b zurückbelegen musst, sonst werden die ja immer größer.
Bau dir paar sysouts rein und guck, warum das Ergebnis nicht hinhaut.
rein und dann funktioniert alles.
Generell stimmt bei dir das Ergebnis, aber da fehlen dennoch ein paar Abbruchbedingungen. for-Schleifen eignen sich dafür nicht wirklich, denn:
mal angenommen du hast die Zahl 55... schon bei 5^3 kommst du auf 125, rechnest aber dennoch weiter und überprüfst sogar die 2. Zahl komplett, obwohl die Summe von 125 und x>=0 nie kleiner sein wird.
Ich hätte es wie folgt gemacht (die Potenzbildung ist ziemlich redundand, deswegen kann es so nicht bleiben, aber der Grundgedanke sollte klar sein):
Java:
public static boolean checkPontent(int number) {
if ((number>9) && (number<100)) {
int n2 = number%10;
int n1 = (number-n2)/10;
int p1=1;
int p2;
while (Math.pow(n1, p1)<=number) {
p2=1;
while (Math.pow(n2, p2)<=(number-(Math.pow(n1, p1)))) {
if (Math.pow(n1, p1)+Math.pow(n2, p2)==number) {
System.out.println(n1+"^"+p1+" + "+n2+"^"+p2+" = "+number);
return true;
}
if ((n2==0)|| (n2==1)) {
break;
}
p2++;
}
if ((n1==0)|| (n1==1)) {
break;
}
p1++;
}
}
return false;
}
Noch ein paar kleine Tips, die Du beherzigen solltest:
1) Parametern sollte man nichts zuweisen.
2) Unnötige Bedingungen wie die, ob eine Zahl 1 ist, machen den Text schwerer nachvollziehbar und blähen ihn auf.
3) Eine Variable mit 0 zu initialisieren und gleich darauf etwas neues zuzuweisen, ist sinnfrei.
4) Eine private Methode sollte privat sein.
5) Statt mit einer While-Schleife zu zählen, sollte man eine For-Schleife verwenden.
6) Ein long ist für eine Ziffer ziemlich hoch gegriffen; das ist aber im Gegensatz zu den anderen Punkten nahezu unwichtig.
Java:
public static void main(String[] args) {
for (int i = 99; i > 9; --i) {
int ziffer1 = i % 10;
int ziffer2 = (i / 10) % 10;
if (potent(ziffer1, ziffer2, i)) {
System.out.println(i);
}
}
}
private static boolean potent(int ziffer1, int ziffer2, int zahl) {
int a = ziffer1;
for (int x = 1; x <= 9; ++x) {
a *= ziffer1;
int b = ziffer2; /* das Zurücksetzen fehlte bei Dir */
for (int y = 1; y <= 9; ++y) {
b *= ziffer2;
if (a + b == zahl) {
return true;
}
}
}
return false;
}
@XHelp: Die While-Schleifen können auch bei Dir problemlos for-Schleifen sein, und die If-Bedingungen in den While-Schleifen sind deplaziert, weil sich die Bedingung innerhalb der Schleife niemals ändert.
[Java=18]for (int x = 1; x <=9; x++) { // potenziere die Ziffer 9 mal
[/Java]
[Java=22]for (int y = 1; y <=9; y++) { // potenziere die Ziffer 9 mal
[/Java]
Setze die Grenze auf 6, das hat folgenden Grund:
Die höchste mögliche Potenz ergibt sich aus der höchsten möglichen Potenz der kleinsten Zahl, welche ihr Ergebnis bei Erhöhung der Potenz ändert. D.h. die höchstmögliche Potenz ergibt sich aus der 2. Gehst du diese durch lässt sich feststellen, dass bei einer Potenz von 7 die Grenze von 100 bereits überschritten wird. Das heißt für dich, dass du beim Schleifendurchlauf von x und y ab dem Wert 7 NIE ein Ergebnis erhalten wirst (außer eventuell mit 0 und 1 als Basis).
Wieso den Logarithmus? Deine While-Schleifen machen auch nichts anderes als hochzuzählen, nur daß man am Anfang für die Initialisierung von p1 sorgen und am Ende p1 hochzählen muß – also genau das, wofür man normalerweise eine For-Schleife verwendet.
achso. ja gut, war dann ein Denkfehler von mir.
Und warum Logarithmus: weil man da bestimmen kann, bis zur welcher Potenz man gehen muss, z.B.:
56
nehmen wir 5:
log_5(56)=2.5 (gerundet)
als braucht man die 5 nur bis zum exponent <=2 untersuchen, denn ab da wird das Ergebnis größer (5^3=125)
Bei der 2. Schleife genau das gleiche, nur dass man da als Logarithmand den Rest nimmt.