# Tannebaum mit while-Schleife



## Schmirley (25. Feb 2011)

Hallo Leute.

Bin absoluter java noob.
Ich möchte das Tannenbaumproblem gerne mit einer (oder mehreren) while-Schleifen lösen. Warum nicht mit "for"?weil: zu Übungszwecken. Eingabe soll nur die maximale Sternanzahl sein, die der Baum in der untersten Reihe hat. Ich weiß, wie man beispielsweise x Sterne in x Zeilen mit einer while Schleife ausgibt. Leider nicht die Lösung des Problems.
Die Zeilenanzahl hier ist ja; falls gerade - Zeilenanzahl = Sternanzahl/2
                                       falls ungerade - Zeilenanzahl = (Sternanzahl+1) /2

Mein Problem ist, dass ich nicht genau weiß, wie man nach jedem Durchlauf die Sterne ausgibt. Startwert ist 1.
In der nächsten Zeile sollen dann 3 Sterne, dann 5 ... ausgegeben werden.
Dazu kommt dann ja noch das Leerzeichenproblem.
Ich möchte keine Komplettlösung, sondern gerne einen Ansatz.
Alles hoch und runterzählen führt bei mir zu Fehlern oder nicht zu dem was ich will.

Das ist mein Grundgerüst:


```
JAVA]import java.io.*;

class Tannenbaum
{

 
  public static void main ( String[] args ) throws IOException

  {
    BufferedReader input = new BufferedReader(new InputStreamReader(System.in));

    String eingabe;

    int maxstern, i, j, zeile;
 
    System.out.println("maximale anzahl der sterne pro zeile: ");

    eingabe = input.readLine();

    maxstern = Integer.parseInt(eingabe); 

    // 

    while()
      {

      }  

   }   

}
```


----------



## Final_Striker (25. Feb 2011)

Du brauchst in deiner while-Schleife, eine while-Schleife die Leerzeichen und eine zweite while-Schleife die Sterne ausgibt.


----------



## Schmirley (25. Feb 2011)

Hi,

erst einmal danke, dass sich überhaupt jmd. mit solch einer Lapalie beschäftigt. 

Ich hätte gerne einen Ansatz für die Sternchenausgabe. (das mit den Leerzeichen müsste ja dann äquivalent gehen).

Also mein Startwert ist 1.
ein Sternchen in der ersten Zeile

wenn ich jetzt aber eine while Schleife durchlaufe, habe ich immer das Problem, dass so lange hochgezählt wird, so dass dann maxstern in einer Zeile ausgegeben wird. wie kann ich die while Schleife unterbrechen, so dass folgendes passiert.

gib 1 st. aus,    nächste zeile

zähle 2 hoch und gib 3 st. aus  nächste zeile

zähle 2 hoch und gib 5 st. aus.

ich check das einfach nicht

Dies ist ein ähnliches Programm, aber das zählt die sterne ja nicht pro zeile nacheinander rauf. Kann ich hier irgendeinen ansatz finden? Ohne, dass ich am Anfang die Zeilenanzahl mit eingebe.



```
import java.io.*;

class Sternchen

{

  public static void main ( String[] args ) throws IOException

  {
    BufferedReader input = new BufferedReader(new InputStreamReader(System.in));

    String eingabe;

    int zeilenanzahl, sternenanzahl, zeile, stern;

    System.out.println("anzahl der zeilen: ");

    eingabe = input.readLine();

    zeilenanzahl = Integer.parseInt(eingabe);

    System.out.println("anzahl der sterne pro zeile: ");

    eingabe = input.readLine();

    sternenanzahl = Integer.parseInt(eingabe); 

    zeile = 1;

    while (zeile <= zeilenanzahl) 

    {
       stern = 1;

         while ( stern <= sternenanzahl )

         {
           System.out.print("*");
  
           stern = stern + 1;
         }

         System.out.println();        
       
         zeile = zeile + 1;


    }
  

  }


}
```


----------



## abcjk (26. Feb 2011)

Hallo,

du musst die Zeilenanzahl nicht mit eingeben sondern kannst sie ja auch wie von dir selber im ersten Post angegeben berechnen, dadurch weißt du schon mal wie hoch dein Baum wird.


----------



## Schmirley (26. Feb 2011)

ok. so weit so gut. das hatte ich bei meinen versuchen auch schon eingebaut. 
ich krieg das immer noch nicht mit dem hochzählen und gleich die anzahl der sternchen ausgeben und dann erst weiterzählen hin. 
ick weiß auch gar nicht, was ich an nem freitag abend hier mache  ick hol mir grad erst mal nen bier. vielleicht flutscht es ja dann besser und die grauen zellen arbeiten wieder 


```
JAVA]import java.io.*;
 
class Tannenbaum
{
 
 
  public static void main ( String[] args ) throws IOException
 
  {
    BufferedReader input = new BufferedReader(new InputStreamReader(System.in));
 
    String eingabe;
 
    int maxstern, i, j, zeile;
 
    System.out.println("maximale anzahl der sterne pro zeile: ");
 
    eingabe = input.readLine();
 
    maxstern = Integer.parseInt(eingabe); 
 
    zeile = 1;
 
    while (zeile <= (maxstern/2))
      {
       
      while()  ??????
        {

         }
     
      System.out.println();
      zeile = zeile + 1;
      }  
 
   }   
 
}
```


----------



## Final_Striker (26. Feb 2011)

Ich habe dir doch geschrieben, dass die in deiner while-Schleife die über die Zeilen läuft, zwei while-Schleifen brauchst. Du hast aber immer noch nur eine drin.


----------



## Hemme (26. Feb 2011)

Hallo

Wieso kürzt du deinen Code nicht erst einmal, bevor du dich um das eigentlich Problem kümmerst.
Leg doch die Anzahl Zeilen mal zuerst in einer festen Variable fest und rechne dann weiter.

Also und wie bereits gesagt wurde, brauchst du zwei while-Schleifen.

Wieso nicht in die Richtigung:

(Ich nehme einfach mal die Zahl 5)


```
while ( anzZeilen kleiner ist als 5 ) {
        
        while ( Berechnung für anz Sternchen ) {
         
        }

        while ( Berchnung für anz Leerstellen ) {

        }

   }
```


----------



## Schmirley (26. Feb 2011)

so neuerTag neues Glück 

Ich hab das ganze jetzt erstmal nur für eine ungerade Anzahl für Sternchen geschrieben. Prinzipiell hast du Recht, wäre mit deiner Version erstmal kürzer. Aber das ist eigentlich nicht mein Poblem. 

Ich habe jetzt mal die while Schleife für die Leerzeichen geschrieben und habe das gleiche Problem wie vorher. Er gibt immer bloß 1 Leerzeichen pro Zeile aus. Ich kriege meinen Gedankenfehler einfach nicht rausradiert. 



```
import java.io.*;

class Tannenbaum
{

  static void   print    (String s) { System.out.print(s); }
  
  static void   println  (String s) { System.out.println(s); }

  public static void main ( String[] args ) throws IOException

  {
    BufferedReader input = new BufferedReader(new InputStreamReader(System.in));

    String eingabe;

    int maxstern, i, j, zeile;
 
    System.out.println("maximale anzahl der sterne pro zeile: ");

    eingabe = input.readLine();

    maxstern = Integer.parseInt(eingabe); 

    zeile = 1;  

    i = 1;

    j = ((maxstern+1) / 2);

  

    while (zeile <= ((maxstern+1) / 2))

      {

      while (i <= j)

         {   
          System.out.println("_");

          i = i+1;

          
         }       
 
      
       System.out.println(); 
 
       zeile = zeile+1;
 
       j = j-1;
         


      }


      
  }   

}
```


----------



## abcjk (26. Feb 2011)

Hallo,

es fehlt immer noch die zweite bzw. dritte while Schleife.
Wie im Post von Hemme zu sehen sind es insgesamt drei while Schleifen.
Dass immer nur ein Leerzeichen ausgegeben wird liegt daran, dass du System.out.println verwendest.
Nimm stattdessen System.out.print her und mach den Zeilenumbruch nach dem ausführen beider while-Schleifen extra.


----------



## Schmirley (26. Feb 2011)

also das mit dem println habe ich jetzt verändert. den zeilenumbruch habe ich jetzt auch nach den while-schleifen gemacht. nun wird eine zeile mit drei leerzeichen ausgegeben. das hab ich ja alles schon durch  

und nochmal: ich weiß, dass ich mehr while-schleifen benötige, aber ich gebe mich im moment auch erst mal damit zufrieden, dass mir die korrekte anzahl von leerzeichen oder sternchen pro zeile ausgegeben wird. das andere müsste ja dann äquivalent funktionieren. ich mach doch jetzt nicht noch mehr verschachtelungen, wenn ich nicht mal eins der probleme lösen kann. ich weiß, dass ich irgendwo einen gedankenfehler habe, auf den ich nicht komme. drücke ich mich denn so sch... aus, dass keiner mein problem erkennt. ich dachte, bei all den pro´s, die hier rumschwirren, wär das ne ganz leichte sache. ich bin echt am verzweifeln. und das hört sich jetzt nur so böse an, weil ich meinen rechner gleich schrotte  

ich krieg nämlich langsam das gefühl, ich bin doof und das bin ich nicht gewohnt :shock:




```
import java.io.*;

class Tannenbaum
{

  static void   print    (String s) { System.out.print(s); }
  
  static void   println  (String s) { System.out.println(s); }

  public static void main ( String[] args ) throws IOException

  {
    BufferedReader input = new BufferedReader(new InputStreamReader(System.in));

    String eingabe;

    int maxstern, i, j, zeile;
 
    System.out.println("maximale anzahl der sterne pro zeile: ");

    eingabe = input.readLine();

    maxstern = Integer.parseInt(eingabe); 

    zeile = 1;  

    i = 1;

    j = ((maxstern+1) / 2);

  

    while (zeile <= ((maxstern+1) / 2))

      {

      while (i <= j)

        {   
         System.out.print("_");

         i = i+1;

          
        }       
 
             
        j = j-1;
        
               
        zeile = zeile+1;
 

      }

       System.out.println();
      
  }   

}
```


----------



## Murray (27. Feb 2011)

System.out.println() sorgt doch dafür, dass eine neue Zeile begonnen wird. Insofern spricht manches dafür, dass diese Anweisung ans Ende der äußeren Schleife gehört (z.B. hinter zeile = zeile +1) und nicht erst hinter diese Schleife.


----------



## Schmirley (27. Feb 2011)

so. ick weiß nicht mehr weiter. habe zwar geschrieben, dass ich keine komplettlösung will, aber kann mir jetzt bitte jmd. sagen was in der while schleife stehen muss, damit folgendes ausgegeben wird.

_
__
___
____

usw.

wie gesagt, ich hoffe, wenn ich das mit den leerzeichen hinbekomme, dass das mit den sternen dann so ähnlich funktioniert. danke.


----------



## jgh (27. Feb 2011)

wer wird denn gleich die Flinte ins Korn werfen^^:

deine erste while-Schleife ist für die Zeilen, deine zweite für die "Spalten"...logischerweise musst du nach Durchlauf deiner zweiten Schleife, den Zähler i wieder auf 0, bzw. bei dir auf 1 setzen...dann hast du zumindest schonmal so eine Bild:

__________
_________
________
_______
______
_____
____
___
__
_


```
while (zeile <= ((maxstern + 1) / 2))

		{

			while (i <= j)

			{
				System.out.print("_");

				i = i + 1;

			}

			j = j - 1;

			zeile = zeile + 1;
			System.out.println();
			i = 1;

		}
```


----------



## Hemme (27. Feb 2011)

Warum eigentlich so schwierig? Es geht doch viel einfacher...???:L

Du kannst ja die maximale Zeilenanzahl eingeben. (Bsp. wieder 5)
Und eine mit der Variable "zeile" kannst du ohne Probleme die Leerzeichen berechnen..

In der 1. Zeile müssen 4 Leerzeichen ausgegeben werden..
In der 2. Zeile 3..
usw.

-> anzLeerzeichen = maxZeilen - zeile;

Dann musst du nach jedem Durchlauf nur noch "zeile" jedesmal um eines erhöhen..


```
int anzDurchlauf = maxZeilen;     

     while (anzDurchlauf  > 0 ) {
          
          anzLeerzeichen = maxZeilen-zeile;      

          while ( anzLeerzeichen > 0 ) {
               
               System.out.print(" ");
               anzLeerzeichen--:
          }
        
        anzDurchlauf--;
        zeile++;
        System.out.println();
     }
```

Ist zwar in eine andere Richtung, aber ich hoffe es hilft.


----------



## Schmirley (27. Feb 2011)

vielen herzlichsten dank für beide antworten.  es lag bei meinem programm dann ja wirklich nur an "i". war wirklich super hilfreich. habe gerade nicht viel zeit, aber ich hoffe, mit dem ansatz bekomme ich den rest auch hin. werde ich selbsverständlich dann auch voller stolz posten, auch wenns für die meisten hier ein wahrscheinlich ehr lächerliches problem ist


----------



## newSchmirnew (27. Feb 2011)

Der zu zeichnende Tannenbaum ist wohl einfach ein Dreieck.

Ein paar grundsätzliche Sachen musste dir überlegen:

1) es soll ein n x m großes Feld ausgegeben werden
2) in jeder Zeile sollen x Leerzeichen, y Sterne und nochmals x Leerzeichen ausgegeben werden

zu 1): ein nxm-Feld mithilfe von zwei geschaltete Schleifen erreicht werden; auch eine Schleife mit darin enthaltener Alternative ist möglich. Eine Zählvariable i=0 kann bis n inkrementiert werden, eine andere, j=0, kann jeweils bis m inkrementiert werden.

zu 2): Leerzeichen, Sterne und Leerzeichen können jeweils auch mit Schleifen ausgegeben, deren Zählvariablen sich durch Berechnungen mit der aktuellen Zählvariable i ergeben.


```
final int to = 5;
for (int i = 1; i <= to; i++) { // i: Zeilennummer
    for (int j = 0; j < (to - i) / 2; j++) { // j: Leerzeilen davor
        System.out.print(' ');
    }
    for (int j = 0; j < i; j++) { // j: Sterne
        System.out.print('*');
    }
    for (int j = 0; j < (to - i) / 2; j++) { // j: Leerzeilen danach
        System.out.print(' ');
    }
    System.out.println();
}
```

Was ausgegeben wird sieht noch nicht ganz richtig aus, aber mit kleinen Änderungen kann es durchaus ansehnlich werden 

Für mich sind for-Schleifen übersichtlicher, aber jede for-Schleife kann ja zu vollwertigen while-Schleifen umgeschrieben werden, mit einiger Variablentrickserei


----------



## Schmirley (28. Feb 2011)

So. Ich habe es endlich geschafft. Danke für die Hilfe. Ich hoffe, dass meine nächsten Programme mich nicht so zum verzeifeln bringen 

Hier ist mein fertiges Programm und es läuft einwandfrei.


```
import java.io.*;

class Tannenbaum
{

  
  public static void main ( String[] args ) throws IOException

  {
    BufferedReader input = new BufferedReader(new InputStreamReader(System.in));

    String eingabe;

    int maxstern, i, j, h, zeile;
 
    System.out.println("maximale anzahl der sterne pro zeile: ");

    eingabe = input.readLine();

    maxstern = Integer.parseInt(eingabe); 

    zeile = 1;  

    j = ((maxstern-1) / 2);

    h = 1;

    while (zeile <= ((maxstern+1) / 2))

    {

      i = 1;

      while (i <= j)

      {   
         
        System.out.print("_");

        i = i+1;

      }       
 
        i=1;
                        
        while (i <= h && h <= maxstern)

        {
         
          System.out.print("*");

          i=i+1;
        }
             
      j = j-1;
    
      h = h+2;
               
      zeile = zeile+1;
 
      System.out.println();

    }

  }   

}
```


----------



## Hephaistosone (5. Aug 2015)

Also.. Ich gehe solche Sachen prinzipiell erstmal mit nem guten alten Struktogramm an..
So in der Form..:

Das macht es wesentlich übersichtlicher und man erspart sich viel Zeit beim tüfteln, finde ich...


----------



## Joose (5. Aug 2015)

Gibt es einen bestimmten Grund so einen alten Thread auszugraben?


----------

