Glückliche oder Traurige Zahl?
Aufgabenstellung:
Die Dezimalziffern einer natürlichen Zahl n, n ≥ 1, werden einzeln quadriert und addiert. Anschließend wird mit der entstandenen Summe genauso verfahren. Die Ausgangszahl n ist fröhlich, wenn man bei diesem Vorgehen schließlich auf die Zahl 1 stößt, ansonsten ist sie traurig. Beispielsweise ist 7 eine fröhliche Zahl
Schreiben Sie ein Java-Programm, das alle fröhlichen Zahlen zwischen einer Unter- und einer Obergrenze berechnet und die zugehörigen Folgen ausgibt.
Der Dialog soll folgendermaßen ablaufen:
untere Grenze ein: 5
obere Grenze ein: 30
7 -> 49 -> 97 -> 130 -> 10 -> 1
10 -> 1
13 -> 10 -> 1
19 -> 82 -> 68 -> 100 -> 1
23 -> 13 -> 10 -> 1
28 -> 68 -> 100 -> 1
import java.util.Scanner;
public class GlücklicheZahl2 {
private int counter = 0;
private int[] summenSpeicher = new int[1];
private int zahl;
int summenCounter = 0;
Scanner scanner = new Scanner(System.in);
public static void main(String[] args) {
GlücklicheZahl2 zahl = new GlücklicheZahl2();
}
public GlücklicheZahl2() {
/*System.out.print("Zahl? ");
int zahl = scanner.nextInt();*/
System.out.print("untere Grenze? ");
int untereGrenze = scanner.nextInt();
System.out.print("obere Grenze? ");
int obereGrenze = scanner.nextInt();
for (int i = untereGrenze; i <= obereGrenze + 1; i++) {
this.zahl = i;
this.summenSpeicher = new int[1];
createIntArray(i);
}
}
public void rechnung(int[] intArray) {
boolean glücklich = false;
int summe = 0;
for (int i = 0; i < intArray.length; i++) {
summe += intArray[i] * intArray[i];
}
if (summe == 1) {
glücklich = true;
}
if (summenCounter >= summenSpeicher.length) {
int[] tmpArray = new int[summenSpeicher.length + 1];
for (int i = 0; i < summenSpeicher.length; i++) {
tmpArray[i] = summenSpeicher[i];
}
summenSpeicher = tmpArray;
}
summenSpeicher[summenSpeicher.length - 1] = summe;
summenCounter++;
if (glücklich) {
System.out.print(zahl);
for (int i = 0; i < summenSpeicher.length; i++) {
System.out.print(" -> " + summenSpeicher[i]);
}
System.out.println("");
} else {
if (counter < 50) {
counter++;
createIntArray(summe);
}
}
}
public void createIntArray(int x) {
String wert = Integer.toString(x);
char[] wertarray = wert.toCharArray();
int[] intArray = new int[wertarray.length];
for (int i = 0; i < wertarray.length; i++) {
intArray[i] = Character.getNumericValue(wertarray[i]);
}
rechnung(intArray);
}
}
![](https://images.gutefrage.net/media/user/zooper/1649503486141_nmmslarge__0_117_1080_1080_9b7492dff0dd6c49d980ab15f8d2845f.jpg?v=1649503486000)
Wieso erstellst du eine Instanz der Main Klasse mit einer Methode in dieser Klasse um den Konstruktor aufzurufen der ein Programm ausführt? Sieht sehr komisch aus.
![](https://images.gutefrage.net/media/default/user/10_nmmslarge.png?v=1551279448000)
keine Ahnung hat mein Tutor im Studium mal so gemacht
3 Antworten
![](https://images.gutefrage.net/media/user/MagicalGrill/1548472380616_nmmslarge__260_60_1080_1080_9461c4b490096d30204b9d24434abaa7.png?v=1548472381000)
Ich hab mich auch mal dran versucht (in C#) und folgendes ist dabei herausgekommen:
internal class Program
{
public static void Main(string[] args)
{
Console.WriteLine("Bitte geben Sie die untere Grenze ein: ");
int start = int.Parse(Console.ReadLine());
Console.WriteLine("Bitte geben Sie die obere Grenze ein: ");
int end = int.Parse(Console.ReadLine());
for (int i = start; i <= end; i++)
{
var sequence = new NumberSequence(i);
if (sequence.IsLucky)
{
Console.WriteLine(sequence.StringRepresentation);
}
}
}
}
internal class NumberSequence
{
private readonly List<int> _numbers;
public string StringRepresentation => string.Join(" -> ", _numbers);
public bool IsLucky => _numbers[_numbers.Count - 1] == 1;
public NumberSequence(int startNumber)
{
_numbers = new List<int>();
ExpandSequence(startNumber);
}
private void ExpandSequence(int number)
{
if (_numbers.Contains(number)) return;
_numbers.Add(number);
ExpandSequence(SumOfSquaredDigits(number));
}
private int SumOfSquaredDigits(int number)
{
if (number == 0) return 0;
int firstDigit = number % 10;
return firstDigit * firstDigit + SumOfSquaredDigits(number / 10);
}
}
ACHTUNG: Die ExpandSequence-Methode fügt rekursiv Elemente zur Sequence hinzu, bis sich irgendwann eines wiederholen würde (ab da würde die Sequence sich periodisch wiederholen und in eine Endlos-Rekursion ausarten). Ich bin mir nicht sicher, ob die Rekursion immer terminiert, daher kann man zur Sicherheit auch die Iterationen mitzählen und irgendwann abbrechen (etwa so wie zooper in seiner/ihrer Lösung auch nur 100 Iterationen durchgeführt hat).
![](https://images.gutefrage.net/media/user/daCypher/1444744777_nmmslarge.jpg?v=1444744777000)
Ist eine nette kleine Aufgabe, daher geb ich auch mal meinen Senf dazu:
public class GluecklicheZahl {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// Unter- und Obergrenze abfragen
System.out.print("Bitte geben Sie die Untergrenze ein: ");
int lBound = scanner.nextInt();
System.out.print("Bitte geben Sie die Obergrenze ein: ");
int uBound = scanner.nextInt();
scanner.close();
// Jede Zahl zwischen Unter- und Obergrenze durchgehen
for (int i = lBound; i <= uBound; ++i) {
int num = i;
Set<Integer> iterationResults = new LinkedHashSet<>();
// Die Serie aufbauen
// Da als Abbruchbedingung nur vorgegeben ist, dass die Serie irgendwann bei einer 1 enden soll,
// wird als weitere Abbruchbedingung angenommen, dass die Serie sich ansonsten ab einem bestimmten Punkt wiederholt.
// Daher wird die Schleife abgebrochen sobald ein Element eingefügt werden soll, welches schon in der Serie ist.
while (num != 1 && !iterationResults.contains(num)) {
iterationResults.add(num);
num = Integer.toString(num).chars().map(Character::getNumericValue).map(value -> value * value).sum();
}
iterationResults.add(num);
// Serie ausgeben, falls sie mit einer 1 geendet ist.
if (num == 1) {
System.out.println(iterationResults.stream().map(n -> n.toString()).collect(Collectors.joining(" -> ")));
}
}
}
}
![](https://images.gutefrage.net/media/default/user/10_nmmslarge.png?v=1551279448000)
funktioniert nicht so ganz wenn ich es nur mit einer Zahl gemacht habe hat es funktioniert also im Konstruktor folgendes:
System.out.print("Zahl? ");
int zahl = scanner.nextInt();
createIntArray(zahl);
jetzt mit der schleife für den zahlenbereich net mehr wirklich. Bin auch dankbar für sonstige Anmerkungen wenn ihr das ganz anders gemacht hättet oder so