Pascal在C ++中的三角形

时间:2017-10-27 21:53:58

标签: c++ pascals-triangle

我正在尝试用C ++制作一个Pascal三角形。但我做不到!我的代码出了什么问题?

#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";
 }

输出如下:

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

2 个答案:

答案 0 :(得分:3)

我要做的第一件事就是不要担心数字在打印时的实际排列方式。这是一个跨所有编程的类似概念,你想要分离对事物如何显示的关注,从数据中的事物的“视图”,“模型”。现在你有了构造代码的概念基础,我也会使用类结构和对象,因为你说C ++是你想要实践的东西,主要集中在面向对象编程(OOP)范例。有了这些想法,我们就可以开始想出如何创建三角形的方法。

我们想要实现的是以下结构的程序化生产:

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

实现这种影响我们真的想要创建:

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

如果您从上面的图中注意到,我们可以推断出从公理开始(第一次迭代/假设在我们开始之前就存在的东西),在这种情况下,它只是一行只包含数字{{1我们可以看到每个生产(任何给定的迭代,其中有一些规则来生成它,首先从公理开始,1)是通过在它上面的行中添加两个值来给出的,它们具有相同的索引和下一个索引。为了算法,我们假设如果生产找不到数字,我们会说数字存在但没有显示,我们假设它是0.(如果它是全部的在左侧的方式,没有第一个值,如果它在右侧一直没有第二个值)

这意味着如果你看看我的第二张图,我们的第一行只是1,但我们会假装它真的是1。这给了我们更像金字塔:

0,1,0

最重要的部分是公理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 ,我们假设它是1。现在让我们弄清楚我们的“生产”的代码,即创建行的方法,给定它之前的行。我们想要创建一个函数,它将从前一行中获取一个数字列表,并创建下一行,假设它在任一侧用0,1,0填充。该功能可能如下所示:

0

实际上,这就是我们所需要的。现在你只需要使用一个技巧在它们之间放置空格并打印出来。我不会在这里这样做,但我会告诉你如何使用这个函数来产生三角形的几行:

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;
}

我已经把它放到了一个类对象中,而且还像一个实际的pascal三角形一样打印它作为练习,我想你应该尝试一下,并花时间真正思考{{{ 1}}方法。

答案 1 :(得分:3)

如果您将三角形想象为左对齐(https://en.wikipedia.org/wiki/Pascal%27s_triangle#Overall_patterns_and_properties),那么它可以显示为二维数组:

#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;
    }

打印:

enter image description here