Schleife mit Top-Down

  • VB.NET

Es gibt 10 Antworten in diesem Thema. Der letzte Beitrag () ist von Hutti.

    Schleife mit Top-Down

    Hello Leute,
    und zwar brauche ich Hilfe ab Zeile 39.
    Ich will einen Tannenbaum darstellen und bei 39 sollen die Tannen dargestellt werden.
    Es soll mit einem Zeichen beginnen und dann immer 2 mehr werden bis die MaxBreite erreicht ist.
    Die Leerzeichen sollen auch kleiner werden. Habe den Rest hinbekommen, es hakelt nur an dieser Stelle.
    Wäre nett wenn ihr mir es erklären könntet. Rest steht denke ich in dem Kommentar erklärt. :)

    VB.NET-Quellcode

    1. Module Module1
    2. Sub Main()
    3. Dim MaxBreite As Integer
    4. Dim breite As String
    5. Dim Zeichen1 As Char
    6. Dim Zeichen2 As Char
    7. Console.WriteLine("Bitte maximale Breite eingeben!")
    8. MaxBreite = 0
    9. Do While MaxBreite = 0
    10. breite = Console.ReadLine()
    11. If IsNumeric(breite) Then
    12. MaxBreite = CInt(breite)
    13. End If
    14. Loop
    15. Console.WriteLine("maximale Breite = " & MaxBreite)
    16. Console.WriteLine()
    17. Console.WriteLine("Bitte Zeichen auswählen, womit Sie die Tannen darstellen wollen!")
    18. Zeichen1 = Console.ReadLine()
    19. Console.WriteLine("Zeichen für Tanne = " & Zeichen1)
    20. Console.WriteLine()
    21. Console.WriteLine("Bitte Zeichen auswählen, womit Sie den Stamm darstellen wollen!")
    22. Zeichen2 = Console.ReadLine()
    23. Console.WriteLine("Zeichen für Stamm = " & Zeichen2)
    24. Console.WriteLine()
    25. 'Wiederholung der Tannen bis MaxBreite
    26. 'Top - Down einbringen
    27. 'mit einem Zeichen starten und dann nach unten +2 bis MaxBreite
    28. Dim i = 1
    29. Do Until (i < MaxBreite)
    30. Console.WriteLine(" " + Zeichen1)
    31. i += 2
    32. Loop
    33. ' Wiederholung des Stammes 3 Mal
    34. Dim Zähler As Integer = 0
    35. Do
    36. Console.WriteLine(Zeichen2 + Zeichen2 + Zeichen2)
    37. Zähler += 1
    38. Loop Until Zähler = 3
    39. Console.ReadLine()
    40. End Sub
    41. End Module


    *Eigentlichen Beitragstext aus Codeteil extrahiert* ~NoFear23m

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Nofear23m“ ()

    Ich weiss nicht ob ich dich richtig verstehe, aber evtl so:


    für den Kopf (also die Tanne selbst)

    VB.NET-Quellcode

    1. For i As Integer = 0 To (MaxBreite - 1) / 2
    2. Dim outputLine As String = ""
    3. For a As Integer = (MaxBreite - 1) / 2 To i Step -1
    4. outputLine += " "
    5. Next
    6. For a As Integer = 0 - i To i
    7. outputLine += Zeichen1
    8. Next
    9. Console.WriteLine(outputLine)
    10. Next



    Und für den Stamm dann:

    VB.NET-Quellcode

    1. For i as Integer = 0 To 2
    2. dim outputLine As String = ""
    3. For a as Integer = 0 To (MaxBreite-3)/2
    4. outputLine += " "
    5. Next
    6. outputLine += Zeichen2+Zeichen2+Zeichen2
    7. Console.WriteLine(outputLine)
    8. Next



    Wichtig ist dass der Nutzer eine Ungerade Zahl bei der Breite eingibt^^



    Nachtrag: 13:54 Uhr

    @Michelleisback freue mich über das "Danke" :)
    Sollte somit dein Problem gelöst sein, dann bitte schliesse das Thema ab:



    Oben Rechts :)

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „Hutti“ ()

    @Hutti
    versuche grade den code zuverstehen.
    Bei der Tanne startet die Variable i mit dem Wert 0 und bei jeder schleife wird MaxBreite -1 gerechnet und dann durch 2 dividiert .
    Dann haben wir outputline als string mit dem Wert "" deklariert. also wird nach oben immer eine Leerzeile hinzugefügt.

    a fängt dann mit (maxBreite-1)/2 an bis i=0? und nach jeder schleife immer eins weniger
    outputline soll dann immer um " " erweitert werden

    dann startet a wieder mit 0-i bis i erreicht wird?
    die outputline wird immer um Zeichen1 erhöhert
    und dann soll alles ausgegeben werden

    ok bin jz ganz verwirrt xD
    Könntest du es mir bitte erklären? :)
    Danke im Voraus

    Michelleisback schrieb:


    Könntest du es mir bitte erklären? :)
    Danke im Voraus


    Klar!

    Also schauen wir uns mal die Sache mit der Tanne an:

    VB.NET-Quellcode

    1. For i As Integer = 0 To (MaxBreite - 1) / 2
    2. Dim outputLine As String = ""
    3. For a As Integer = (MaxBreite - 1) / 2 To i Step -1
    4. outputLine += " "
    5. Next
    6. For a As Integer = 0 - i To i
    7. outputLine += Zeichen1
    8. Next
    9. Console.WriteLine(outputLine)
    10. Next


    Die äusserste Zählerschleife start bei i = 0. Die MaxBreite, habe ich mir gedacht willst du sicher eine Ungerade, damit die Tanne oben einen Spitz hat (Also nur ein Zeichen)
    Mit der MaxBreite -1 habe ich quasi die Spitze abgerechnet. Denn diese stellt einfach die mittlere (dunkelGrün) Reihe dar:

    Im Bildbeispiel haben wir also eine Breite von 7
    Somit zählt die äussere Schleife von 0 bis (7-1)/2 also bis 3!
    0,1,2,3 das sind 4 Wiederholungen.
    Warum ergibt es 4 Wiederholungen bei Breite 7? Ganz einfach: Die Lehrzeichen!
    Wir haben eine Reihe mit 4 Lehrzeichen, eine mit 3, eine mit 2 und die letzte mit ein Leerzeichen!
    Wenn der User eine Breite von 9 will haben wir 5 Reihen statt 4 und somit 5 mögliche Leerzeichenanzahle:
    1 mit 5 Leerzeichen
    2 mit 4 Leerzeichen
    3 mit 3 Leerzeichen
    4 mit 2 Leerzeichen
    5 mit 1 Leerzeichen

    Denn wir müssen ja sowieso nur von einer "Seite" aus Leerzeichen einbauen, da rechts eine NewLine also neue Zeile anfängt.

    Gut! Soweit zu unserem äusseren Zählschleife.

    Zur nächsten Zeile:

    VB.NET-Quellcode

    1. Dim outputLine As String = ""


    Ich definiere hier eine Variable als Zeichenkette. Sie dient uns um den "Satz" aufzubauen. Wenn du dir das Bild oben nochmals ansehen könnstes: die zweite Reihe heisst der Satz "___111"
    Also 3x Leerzeichen und 3x Zeichen1
    Aber hier habe ich ja nur eine Leere Zeichenkette definiert. Das aufbauen des Satzes kommt in den nächsten 2 Schleifen!

    Die erste innere Schleife: Das einbauen von Leerzeichen

    VB.NET-Quellcode

    1. For a As Integer = (MaxBreite - 1) / 2 To i Step -1
    2. outputLine += " "
    3. Next


    Um die Leerzeichen in einem Satz (also pro Reihe) einzugeben, zählen wir hier von a = (7-1)/2 also wenn der Nutzer die Breite 7 angibt:
    a = 3 bis i
    i ist unsere aktuelle Reihe mit start 0 und der Step ist der Schritt, also jedesmal einen schritt zurück (-1)
    Wenn wir also beim Spitz oben sind, zählen wir 3 bis 0 herunter.
    Das macht beim Spitz 4x Leerzeichen die in unsere Zeichenkette eingegeben werden.
    Nun haben wir eine Zeichenkette mit 4 Leerzeichen.

    Jetzt kommt die zweite Schleife zum Einsatz! Das aufbauen der Tanne:

    VB.NET-Quellcode

    1. For a As Integer = 0 - i To i
    2. outputLine += Zeichen1
    3. Next


    Hier ist es etwas anders, die anzahl von Zeichen1 also Tannenfläche, ist bei einem niedrigen i (also zur spitze hin) ja kleiner.
    Daher hatte ich mir hier gedacht: a startet bei 0 aber startet immer wie früher desto weiter i ist.
    Daher das -i !
    Und zählt bis zum aktuellen i hoch.
    wenn wir also beim Spitz oben anfangen, haben wir ja i = 0
    also 0 - 0 = 0 bis 0
    das wäre eine Wiederholung. Somit kommt zu unserem Satz der aus 4 Leerzeichen besteht nun 1x ein Zeichen1 hinzu!
    voila! Schon haben wir die erste Reihe und können sie mit der nächsten Zeile darstellen:

    VB.NET-Quellcode

    1. Console.WriteLine(outputLine)


    Dann wird i um 1 hochgezählt.
    Somit i = 1
    Die erste Schleife geht dann also von 3 zu 1
    Das macht: 3,2,1 also 3 Wiederholungen. (1 weniger als bei der ersten Reihe mit i = 0)
    Damit hat unser NEU aufgebauter Satz (outputLine) nur 3 statt 4 Leerzeichen!

    Bei der zweiten Schleife zählen wir ja a = 0 - i bis i
    also 0-1 bis 1
    Mal sehen: -1,0,1 das sind also 3 Wiederholungen!
    Somit kommt zum Satz wo bereits 3 Leerzeichen sind 3 Zeichen1 hinzu

    Auch das wird dargestellt mit Console.WriteLine und i wird wieder um +1 hochgezählt.
    Jetzt haben i = 2

    Du kennst nun das Spiel:

    Schleife1 => 3 zu 2
    3, 2 somit 2 Wiederholungen. Damit hat unser NEUER Satz nur 2 Leerzeichen

    Schleife2 => 0-2 zu 2 also => -2 bis 2
    -2,-1,0,1,2 das sind also 5 Wiederholungen
    Unser Satz mit 2 Leerzeichen bekommt 5x Zeichen1 hinter dran gehängt und wird wieder angezeigt.

    :) Cool oder? Schon haben wir die 3 Reihen von Oben nach Unten.

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Hutti“ ()

    Modulo ist dein Freund :)

    Hi.

    Am Besten mit Modulo eine Bedingung nutzen.

    - i ist der Schleifenwert. -

    VB.NET-Quellcode

    1. If i Mod 2 = 0 Then ' ist der Rest der Teilung gleich Null dann Treffer
    2. 'Mach was.
    3. 'z.B. jeder zweite ist eigentlich eine zweite...
    4. End If


    VB.NET-Quellcode

    1. If i Mod 3 = 0 Then ' ist der Rest der Teilung gleich Null dann Treffer
    2. 'Mach was.
    3. 'z.B. jeder dritte ist eigentlich eine zweite plus eins...
    4. End If


    VB.NET-Quellcode

    1. Dim abstand As Integer = 4
    2. If i Mod abstand = 0 Then ' ist der Rest der Teilung gleich Null dann Treffer
    3. 'Mach was.
    4. 'z.B. jeder Abstand ist eigentlich der Abstand ...
    5. End If


    Hoffe das hilft.

    c.u. Joshi

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „Joshi“ ()

    Für derartiges, bevorzuge ich Extension Methods, weil einfach anwendbar und auch wiederverwendbar.

    VB.NET-Quellcode

    1. Imports System.Runtime.CompilerServices
    2. Module IntegerExtensions
    3. <Extension>
    4. Public Function isOdd(ByVal value As Integer) As Boolean
    5. Return value Mod 2 = 0
    6. End Function
    7. End Module

    Die anwendung kann dann so aussehen:

    VB.NET-Quellcode

    1. Dim MyValue As Integer = 3
    2. If MyValue.isOdd Then
    3. ' Mach was.
    4. End If

    Michelleisback schrieb:


    Das mache ich am besten mit If oder?


    Das ist natürlich auch möglich!

    VB.NET-Quellcode

    1. if(MaxBreite Mod 2 = 1) then
    2. ' weitermachen
    3. else
    4. ' fehler -> nochmals eingeben
    5. endif


    Du scheinst noch am Anfang der ganzen Materie zu sein, ich will dich daher auf keinen Fall mit zu vielen Varianten überfallen!
    Dennoch würde ich dir gerne auch einen anderen Weg aufzeigen:

    Du hast ja bereits eine Möglichkeit eingebaut auf die "nicht eingabe" oder eingabe von 0 zu reagieren.


    VB.NET-Quellcode

    1. Console.WriteLine("Bitte maximale Breite eingeben!")
    2. MaxBreite = 0
    3. Do While MaxBreite = 0
    4. breite = Console.ReadLine()
    5. If IsNumeric(breite) Then
    6. MaxBreite = CInt(breite)
    7. End If
    8. Loop


    Wir könnten ja dieses nur etwas erweitern?
    Dass nicht nur bei IsNumeric reagiert sondern evtl auch bei einer geraden Zahl?

    Das eine Zahl z.b 7 Mod 2 eine 1 ergibt, da sie einen Rest aufweist, ist uns ja jetzt klar.
    Wir müssten diese Bedingung nur noch richtig einbauen.

    VB.NET-Quellcode

    1. Console.WriteLine("Bitte gib eine ungerade Ganzzahl an für die maximale Breite:")
    2. Do While (MaxBreite = 0)
    3. breite = Console.ReadLine()
    4. If (IsNumeric(breite) And breite Mod 2 = 1) Then
    5. MaxBreite = CInt(breite)
    6. Else
    7. Console.WriteLine("Eingabe ungültig, erneuter Versuch:")
    8. End If
    9. Loop


    So könnte das z.B aussehen. Die Interaktion fängt genau so an wie du es geschrieben hast, mit der Bitte zur Eingabe.
    Ich habe hier lediglich die Bedingungen bereits bei der Bitte angegeben, damit der User auch weiss, was erwartet wird.
    Auch die While-Schleife und deren Bedingung können wir so belassen, wie von dir bereits aufgebaut.
    Interessant wird es sobald der User einen Wert eingegeben hat und dieser bei der If-Abfrage kontrolliert wird.
    Du kontrollierst da bereits ob es eine Zahl ist. Wie wäre es dort auch schon nach ungerade oder gerade zu kontrollieren?
    Mit einer AND haben wir auch schon das Resultat, wo wir haben wollen.

    Es gibt x-Varianten wie man diese Angelegenheit lösen kann. Dieses ist nur eines von vielen.

    Hoffe dir wurde gut geholfen
    Kleiner Angriff von der Flanke: bitte kein VB6-IsNumeric (siehe empfohlene VS-Einstellungen) und zum Thema And gibt es das hier: Der Unterschied zwischen And und AndAlso/Or und OrElse
    Von daher von mir noch ein bisken Gewürz gestreut:

    VB.NET-Quellcode

    1. Dim WidthText = Console.ReadLine()
    2. Dim Width As Integer = 0
    3. If Not Integer.TryParse(WidthText, Width) OrElse Width Mod 2 = 0 Then Return
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.

    VaporiZed schrieb:


    Kleiner Angriff von der Flanke: bitte kein VB6-IsNumeric


    Stimmt! nicht daran gedacht. Ich selbst nutze ja auch TyParse statt IsNumeric.

    VaporiZed schrieb:


    zum Thema And gibt es das hier: Der Unterschied zwischen And und AndAlso/Or und OrElse


    Hierfür ein Hilfreich, da ich noch nie was von AndAlso ect gehört hatte. Löst viele Probleme ohne zweite Abfrage. Danke