# Pascalsches Dreieck



## dmidi (31. Dez 2009)

hallo leute,
ich muss ein pascalsches dreieck auf der standardausgabe ausgeben und bekomme es iwie nicht auf die reihe...
vll könnt ihr mir helfen
ich habe eine main und eine operationsklasse



```
public class Pascal
{
    public static void main(int l)
    {
        l = In.readInt();
        int [] [] a = new int [2*l-1] [l];
        a = Ops.berechneEintraege(a, l);
        Ops.gebeDreieckaus(a, l);
    }
}
```


```
public class Ops
{
   public static int [] [] berechneEintraege(int [] [] a, int l)
   {
       for (int zeile = 0; zeile < a.length; zeile++)
        {
            for (int spalte = 0; spalte < a[0].length; spalte++)
            {
                if (l - 1 + zeile == spalte || l - 1 - zeile == spalte) a[zeile] [spalte] = 1;
                else if (zeile > 0) a[zeile] [spalte] = a [zeile - 1] [spalte - 1] + a [zeile - 1] [spalte + 1];
                else a[zeile] [spalte] = 0;
            }
        }
        return a;
    }
    
    public static void gebeDreieckaus(int [] [] a, int l)
    {
        for (int zeile = 0; zeile < a.length; zeile++)
        {
            for (int spalte = 0; spalte < a[0].length; spalte++)
            {
                if (a [zeile] [spalte] == 0 && spalte < l - 1) Out.print(" ");
                if (a [zeile] [spalte] != 0 && spalte < l - 1) Out.print(a [zeile] [spalte]);
                if (a [zeile] [spalte] == 0 && spalte == l - 1) Out.println(" ");
                else Out.println(a [zeile] [spalte]);
            }
        }
    }
}
```


----------



## Marco13 (31. Dez 2009)

```
for (int spalte = 0; spalte < a[0].length; spalte++)
{
... 
    else if (zeile > 0) a[zeile] [spalte] = a [zeile - 1] [spalte - 1] + ....
```
Da greifst du auf *a[x] [spalte - 1]* zu, obwohl spalte 0 ist. 

Du solltest überlegen und dazusagen, ob das ganze am ende so

```
0 0 X 0 0 
0 X 0 X 0 
X 0 X 0 X
```
oder so

```
X00 
XX0
XXX
```
im Array liegen soll. Letzeres wäre vermutlich weniger fummelig.


----------



## dmidi (1. Jan 2010)

soll aber wie ersteres aussehn...


----------



## Marco13 (1. Jan 2010)

Ja... wenn du den Array mal mit

```
public static void printArray(int a[][])
    {
        for (int i=0; i<a.length; i++)
        {
            for (int j=0; j<a[i].length; j++)
            {
                System.out.printf("%3d ",a[i][j]);
            }
            System.out.println();
        }
    }
```
ausgibst, wirst du sehen, dass die indizes nicht ganz stimmen.... Die Allokation
[c]int [] [] a = new int [2*l-1] [l];[/c]
sieht auch schon unpassend aus - eigentlich sollte es ja [zeilen][spalten] sein, oder?


----------



## dmidi (1. Jan 2010)

stimmt das müsste umgekehrt sein, hab auch den operator geändert in:



```
public static int [] [] berechneEintraege(int [] [] a, int l)
   {
       for (int zeile = 0; zeile < a.length; zeile++)
        {
            for (int spalte = 0; spalte < a[0].length; spalte++)
            {
                if (l - 1 + zeile == spalte || l - 1 - zeile == spalte) a[zeile] [spalte] = 1;
                else if (zeile > 0 && spalte < l - 1 && spalte > 0) a[zeile] [spalte] = a [zeile - 1] [spalte - 1] + a [zeile - 1] [spalte + 1];
                else a[zeile] [spalte] = 0;
            }
        }
        return a;
    }
```

aber funktioniert immer noch nicht


----------



## Marco13 (1. Jan 2010)

Wenn eine Zeile aussieht wie die

```
else if (zeile > 0 && spalte < l - 1 && spalte > 0) 
    a[zeile] [spalte] = a [zeile - 1] [spalte - 1] + a [zeile - 1] [spalte + 1];
```
dann sollte man sich grundsätzlich überlegen, ob man das nicht einfacher machen kann.

Ein Tipp: Mach es dir nicht so schwer und so kompliziert - Berechne die Einträge so, wie sie berechnet werden. Oben in der Mitte steht eine 1. Das könntest du direkt hinschreiben, und dafür die äußere Schleife bei 1 loslaufen lassen:

```
a[0][l-1] = 1;
for (int zeile = 1; zeile < a.length; zeile++)
..
```
Dann gilt nämlich für ALLE andere Array-Einträge: a[z] = a[z-1][s-1]+a[z-1][s+1]. (Beachte auch, dass der Array am Anfang sowieso lauter 0en enthält - das [c]else array[x][y] = 0;[/c] ist also sowieso überflüssig). Der Zugriff auf z-1 ist sicher, weil die Schleife ja bei 1 lösläuft. Der Zugriff auf [s-1] und [s+1] könnte aber zu einer ArrayIndexOutOfBoundsException führen. (Eine elegante Möglichkeit, das zu verhindern wäre, den Array nicht w=(l*2-1) sondern w=(l*2+1) breit zu machen, und die innere Schleife von 1 bis w-1 laufen zu lassen - dann stünde in der inneren Schleife wirklich nur noch die einzige Zeile [c]a[z] = a[z-1][s-1]+a[z-1][s+1][/c]!). Wenn die Breite aber (l*2-1) sein soll, musst du (nur noch) sicher stellen, dass nicht auf diese ungültigen Indizes zugeriffen wird. Das Muster dafür könnte dann sowas sein wie

```
int obenLinks = 0;
int obenRechts = 0;
if (...) obenLinks = ...
if (...) obenRechts = ...
a[z][z] = obenLinks+obenRechts;
```


----------



## maxinquaye (2. Jan 2010)

Ich weiß nicht ob Dir das hilft, aber rekursiv programmiert ist das ganz kurz:

```
public int pas(int n, int k)
{
if(n == 0 || k == 0 || n == k)
return 1;
else
return pas(n - 1, k - 1) + pas(n - 1, k);
}
```


----------



## dmidi (2. Jan 2010)

also leute danke schon mal für die hilfe bis dahin....
habe jetzt die operationsklasse noch einmal überarbeitet, die dürfte jetzt stimmen denke ich:


```
public class Ops
{
   public static int [] [] berechneEintraege(int [] [] a, int l)
   {
       a[0][l-1] = 1;
       for (int zeile = 1; zeile < a.length; zeile++)
        {
            for (int spalte = 1; spalte < 2*l; spalte++)
            {
                a[zeile] [spalte] = a [zeile - 1] [spalte - 1] + a [zeile - 1] [spalte + 1];
            }
        }
        return a;
    }
    
    public static void gebeDreieckaus(int [] [] a, int l)
    {
        for (int zeile = 0; zeile < a.length; zeile++)
        {
            for (int spalte = 1; spalte < a[0].length; spalte++)
            {
                if (spalte == 2*l) Out.println("");
                if (a [zeile] [spalte] == 0) Out.print(" ");
                else Out.print(a [zeile] [spalte]);
            }
        }
    }
}
```

wenn ich aber meine klasse zum starten öffne, tut sich iwie nix, die virtual maschine hört nicht auf zu arbeiten...
woran liegt das jetzt?
hier nochmal die startklasse:


```
public class Pascal
{
    public static void main(int l)
    {
        l = In.readInt();
        int [] [] a = new int [l] [2*l+1];
        a = Ops.berechneEintraege(a, l);
        Ops.gebeDreieckaus(a, l);
    }
}
```


----------



## Marco13 (2. Jan 2010)

Welche Methode soll sie denn auch ausführen... es gibt keine main. Zumindest keine Richtige. Die main muss IMMER 
[c]public static void main(String args[]) {[/c]
sein - also immer einen String-Array übergeben bekommen.


```
public class Pascal
{
    public static void main(String args[])
    {
        int l = In....
...
```


----------



## dmidi (2. Jan 2010)

oh ok, vielen dank, jetzt funktioniert auch alles.....:applaus:


----------

