我正在尝试用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
答案 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;
}
打印: