2017-10-27 2 views
1

Ich versuche, ein Pascal-Dreieck in C++ zu machen. Aber ich konnte das nicht tun! Was ist falsch an meinem Code?Pascal-Dreieck in C++

#include <iostream> 
using namespace std; 

int main() 
{ 
    int rows = 5; 
    int currentNumber = 1; 
    int numbers; 
    int tempNumber; 
    bool odd; 

    for(int i = 0; i < rows; i++) 
    { 
     numbers = i+1; 
     if(i%2 != 0) { 
      odd = true; 
     } else { 
      odd = false; 
     } 
     for(int j = 0; j < (rows/2)-(numbers/2); j++) 
     { 
      cout << " "; 
     } 
     if(odd) 
     { 
      cout << " "; 
     } 

     currentNumber = 1; 
     tempNumber = 0; 
     for(int k = 0; k < numbers; k++) 
     { 
      cout << currentNumber << " "; 

      if(k > numbers/2) { 
       currentNumber-=tempNumber; 
       tempNumber-=currentNumber; 
      } else { 
       currentNumber+=tempNumber; 
       tempNumber+=currentNumber; 
      } 
     } 
     cout << endl; 
    } 

    cout << "test"; 
} 

Und der Ausgang ist unter:

1 
    1 1 
    1 1 2 
1 1 2 5 
1 1 2 5 -3 
test 

Antwort

3

Das erste, was ich tun würde, ist keine Sorgen über die tatsächliche Anordnung der Zahlen, wenn sie gedruckt sind. Dies ist ein ähnliches Konzept über die gesamte Programmierung hinweg. Sie möchten die Frage, wie Dinge dargestellt werden, die "Ansicht" von den Dingen in Daten, das "Modell", trennen. Nun, da Sie eine konzeptionelle Basis für die Strukturierung des Codes haben, würde ich auch Klassenstrukturen und -objekte verwenden, da Sie sagen, dass C++ das ist, was Sie versuchen zu üben, das sich hauptsächlich auf das Paradigma der objektorientierten Programmierung (OOP) konzentriert. Mit diesen Ideen können wir beginnen, einen Weg zu finden, wie wir das Dreieck schaffen wollen.

Was wollen wir die Verfahrens Produktion der folgenden Struktur erreichen:

 1 
    1 1 
    1 2 1 
    1 3 3 1 
1 4 6 4 1 

dies zu erreichen, beeinflussen wir wirklich schaffen wollen:

1 
1,1 
1,2,1 
1,3,3,1 
1,4,6,4,1 

Wenn Sie von den obigen Diagrammen bemerken, wir können folgern, dass wir beginnend mit dem Axiom (die allererste Iteration/etwas, von dem angenommen wird, dass es da ist, bevor wir überhaupt anfangen), das in diesem Fall einfach eine Zeile ist, die nur die Zahl 1 enthält, jede Produktion (jede gegebene Iteration, die hat eine Regel, um es zu erzeugen, beginnend mit dem Axiom, 1) wird gegeben, indem man die zwei Werte in der darüberliegenden Reihe hinzufügt, die den gleichen Index und den nächsten Index haben. Aus Gründen des Algorithmus gehen wir davon aus, dass, wenn die Produktion keine Zahl findet, wir sagen, dass die Zahl existiert, aber nicht gezeigt wird, und wir annehmen, dass es 0 ist. (Wenn es alles ist Weg auf der linken Seite, gibt es keinen ersten Wert, und wenn es auf der rechten Seite ist, gibt es keinen zweiten Wert)

Also das bedeutet, wenn Sie auf mein zweites Diagramm schauen, haben wir die erste Zeile, die nur 1 ist aber wir werden so tun, als ob es wirklich 0,1,0 ist. Das gibt uns eine Pyramide mehr wie:

0,1,0 
0,1,1,0 
0,1,2,1,0 
0,1,3,3,1,0 
0,1,4,6,4,1,0 

Der wichtigste Teil ist das Axiom 1, die wir annehmen werden 0,1,0 sein. Lassen Sie uns nun den Code für unsere "Produktion" herausfinden, dh die Methode, eine Zeile zu erstellen, vorausgesetzt, die Zeile davor. Wir möchten eine Funktion erstellen, die eine Liste von Zahlen aus der vorherigen Zeile aufnimmt und die nächste Zeile erstellt, vorausgesetzt, dass sie mit unseren 0 s auf jeder Seite aufgefüllt ist. Diese Funktion könnte etwa so aussehen:

std::vector<int> produceNextRow(std::vector<int> previousRow) { 
    std::vector<int> nextRow; 

    int left, right = 0; 
    /* For each of the numbers in the previous row, plus one more 
    because each next row has one more value than the last */ 
    for(int i = 0; i < previousRow.size()+1 ; i++) { 

    // If we're all the way on the left we need 'left' to be our imaginary 0 
    if(i == 0) { 
     left = 0; 
    } else { 
     /* Otherwise we want it to be the value in the same position of the 
     previous row which is slightly to the left, hence -1 */ 
     left = previousRow[i-1]; 
    } 

    // If we're all the way on the right, we need 'right' to be our imaginary 0 
    if(i == previousRow.size()) { 
     right = 0; 
    } else { 
    /* Otherwise we want it to be the value of the previous row, at the same 
     position */ 
     right = previousRow[i]; 
    } 

    /* Finally we add left and right, to get our new number, then we put it into 
    the next row */ 
    nextRow.push_back(left+right); 
    } 

    // Let's return our new row we created 
    return nextRow; 
} 

In Wirklichkeit ist das alles, was wir brauchen. Jetzt müssen Sie nur einen Trick verwenden, um Leerzeichen dazwischen zu legen und auszudrucken. Ich will nicht, dass hier tun, aber ich werde Ihnen zeigen, wie diese Funktion nutzen, ein paar Zeilen des Dreiecks zu erzeugen:

int main(int argc, char *argv[]) { 

    // Vector of vectors of ints! This is our entire triangle 
    std::vector<std::vector<int>> triangle; 
    std::vector<int> axiom {1}; 

    // Lets put our axiom into the triangle first 
    triangle.push_back(axiom); 

    // Alright, for the sake of example lets do some number of productions like 6 
    int productions = 6; 
    for(int i=0; i < productions ; i++) { 
    triangle.push_back(produceNextRow(triangle[i])); 
    } 

    /* Now lets print out our triangle, you'd replace this with something fancy 
    that maybe computs how many spaces are required, and makes the triangle look 
    better. I'll leave that as an excersize for you */ 

    // For each row in the triangle 
    for(int i=0; i < triangle.size() ; i++) { 
    // For each number in the row 
    for(int j=0; j < triangle[i].size() ; j++) { 
     // print that number followed by a comma and a space 
     std::cout << triangle[i][j] << ", "; 
    } 
    // print a new line after each row 
    std::cout << std::endl; 
    } 

    return 0; 
} 

Ich habe links diese in ein Klassenobjekt setzen, und auch ziemlich Druck Es ist wie ein echtes Pascal-Dreieck als Übungen für Sie, ich denke, Sie sollten es ausprobieren und verbringen Zeit wirklich darüber nachzudenken, was in der produceNextRow Methode vor sich geht.

3

Wenn Sie Ihr Dreieck als linksbündig (https://en.wikipedia.org/wiki/Pascal%27s_triangle#Overall_patterns_and_properties) vorstellen, dann kann sie als 2D-Array dargestellt werden:

#include <iomanip> //setw 
.... 

    static int const size = 20; 
    int const width = 6; 
    int cell[size][size+1]; 

    for (int i = 0; i < size; ++i) 
    { 
     cell[i][0] = 1; 
     cell[i][i + 1] = 0; 

     std::cout << std::string((size - i) * width/2, 0x20) << cell[i][0]; 

     for (int j = 1; j <= i; ++j) 
     { 
      cell[i][j] = cell[i - 1][j - 1] + cell[i - 1][j]; 
      std::cout << std::setw(width) << cell[i][j]; 
     } 

     std::cout << std::endl; 
    } 

Drucke:

enter image description here