Wie programmiere ich eine dynamische Zahlenpyramide mit weiteren Zeichen?
Da ist die Aufgabenstellung. Ich arbeite jetzt seit Tagen mit dem Versuch ein Programm zu schreiben, was solche Dreiecke erstellen kann. Normale Dreiecke sind kein Problem für mich, aber bei so einem komplexen Muster dampft mir der Kopf. Kann jemand mir bitte helfen?
Hast Du denn einen Ansatz?
Ist mir etwas peinlich, aber mein Ansatz ist ein simples Skript, womit ich allgemein eine Pyramide erstelle. forSchleifen, wo eine für Reihe ist, s, für die Leerzeichen und j für *
2 Antworten
Den Ansatz musst Du mir noch mal genauer erklären...
Ansonsten wäre jetzt mein Ansatz, dass Du eine For Schleife hast mit einer Variable n, welche am Anfang 1 ist und in eine weitere for-Schleife kommt. Dort wird dann die Variable p ausgeschrieben und um 1 erhöht. Das wird n-mal ausgeführt, danach geht das Programm in die Schleife davor zurück und ändert den Wert n zu n + 1 und führt die Schleife aus bis q größer gleich 14 oder sowas ist, danach hört es auf.
Damit hast Du aber nur eine normale Pyramide aus zahlen. Die Leerzeichen und die + und * sind schon aufwendiger... Die Anzahl der Leerzeichen könntest Du (q-n)*k nehmen, wobei das vor dem String kommt, den Du ausgeben willst (das sieht vor, dass Du die Werte mit Trennzeichen in eine Variable stopfst und als String später rausgibst, das würde bei der innersten for-Schleife mit reingehören), wobei k eine Zahl ist, bei einer Pyramide mit der Höhe 5 zum Beispiel ist die 2, bei einer mit 14 Zeilen ist die 3. Vergleichbar mit der Anzahl der + vor einer Zahl 1. Die Anzahl der * nach der 1 ergibt sich scheinbar aus der ( Anzahl der + bei 1 ) - 1.
Jetzt bleiben noch zwei Fragen:
1. Wie bekommt man die Anzahl der + raus?
2. Und wo gibt man die rein, dass die auch die richtige Anzahl sind?
- wäre sowas wie die Anzahl der Stellen maximal, das heißt nach meinem Ansatz würde ich die größte Zahl vorher schon berechnen, als Anzahl für + in eine globale Variable setzen (oder Du nutzt Funktionen, ist sowieso schöner...) und danach als die Anzahl von * in eine globale Variable (= (Anzahl von +) - 1) setzen. Das würde ich dann in eine neue Variable in der innersten for-Schleife übergeben, welche ich mit der Überprüfung nach der (Anzahl der Stellen) - 1 (weil eine Stelle ist Standard) bearbeiten würde: Anzahl + temp = (Anzahl +) - (Anzahl Stellen) - 1) / 2 und danach aufgerundet) , das heißt Du nimmst die globale Anzahl für die + und rechnest dann aus den Stellen die Differenz raus, wie viele + Du nicht haben möchtest und subtrahierst das dann von +. Das gleiche mit *, aber abgerundet. Beispiel: 101 hat 3 stellen, 3*+ also. Du nimmst die 3 - (((3-1)/2) aufgerundet), was 3-1 wäre, also die Anzahl der + bei 101. Bei 14 sehe das etwa so aus: 3-((2-1)/2) -> 3-(1) (3, weil + global einen Wert von 3 hat)
- Für * sehe das ganze dann zum Beispiel bei 14 mit 2 * global so aus: 2-((2-1)/2 (abgerundet)) = 0.
So, das war jetzt ne ganz schöne Fummelei...
Um es kurz zu fassen, Du berechnest also die Anzahl der + mit (Anzahl Stellen Gesamt) - ((Anzahl Stellen der Zahl - 1) / 2) aufrunden
und die Anzahl der * mit (Anzahl Stellen Gesamt - 1) - ((Anzahl der Stellen der Zahl - 1) / 2) abrunden.
Danach hast Du die Anzahl der + und * und gibst die dementsprechend nur noch in der innersten Schleife vor und nach dem String für die Zahl aus, der String kann dann eventuell irgendwo ran angehangen werden und mit den Leerzeichen zusammen in der äußeren for-Schleife ausgegeben werden.
Prinzip ist also, dass Du durch die Anzahl der Zeilen iterierst, dabei durch die Anzahl der Zahlen iterierst und dabei für jede Zahl die Stellen herausfindest und anhand dieser eben die Zeichen vor und Nach der Zahl anhängst und voran schiebst.
Das lässt sich auch gut in C programmieren, wenn man Lust hat, könnte man das damit mal versuchen...
Ich würde das jetzt nicht für super performant halten, aber schnell genug, damit ne Lösung in unter einem Arbeitstag rauskommt, dürfte es schon sein.
Soweit ich erkenne, hat jede Zahl die Ausgabeform "++nnn**". Die Gesamtbreite ist konstant und gerade, und bei einer ungeraden Ziffernzahl gibt es ein "+" mehr als "*".
Finde also erst mal raus, wie viele Stellen die größte ausgegebene Zahl hat, denk Dir ein "+" und "*" dazu und runde das auf die nächste gerade Zahl auf. Das geht zum Beispiel so (mit rows als Benutzereingabe):
int width = Integer.toString(rows+(rows+1)/2).length() + 2;
if ( width % 2 != 0 )
++width;
Jetzt geht es nur noch darum, eine beliebige Zahl auf diese Breite zu strecken:
String format ( int n, int width ) {
int rest = width - Integer.toString(n).length();
return "+".repeat((rest+1)/2) + n + "*".repeat(rest/2);
}
Beachte, dass rest == (rest+1)/2 + rest/2 immer passt. Bei einem ungeraden rest ist der erste Wert eins größer als der zweite, bei geradem rest sind beide gleich.
Das kannst Du in Deiner Ausgabeschleife direkt verwenden. Die i-te Zeile wird dabei mit (rows-i)*width/2 Leerzeichen eingerückt.
Tipp für die letzte Zeile: " ".repeat(0) funktioniert genau so, wie es soll. Du brauchst dafür keine Sonderbehandlung.