输入n值,使用递归函数,求杨辉三角形中各个位置上的值。
一个大于等于2的整型数n
题目可能有多组不同的测试数据,对于每组输入数据,
按题目的要求输出相应输入n的杨辉三角形。
6
1 1 1 2 1 1 3 3 1 1 4 6 4 1 1 5 10 10 5 1
#include
#include
/*
*非递归方式
*/
/*int main(void)
{
int num;
int a[100][101];//使用二维数组这一数据结构!
while (scanf("%d",&num) != EOF)
{
for (int i = 0; i < num-1; i++)
{
a[i][0] = 1;
a[i][i + 1] = 1;
for (int j = 1; j <= i; j++)
{
a[i][j] = a[i - 1][j - 1] + a[i - 1][j];
}
}
for (int i = 0; i < num - 1; i++)
{
printf("%d", a[i][0]);
for (int j = 1; j <= i + 1; j++)
{
printf(" %d", a[i][j]);
}
printf("\n");
}
}
return 0;
}*/
typedef struct preline{
int a[100][100];
}pre_line;
pre_line output(int,pre_line);
int main(void)
{
int num;
while (scanf("%d", &num) != EOF)
{
pre_line li;// = (struct preline)malloc(sizeof(struct preline));
output(num,li);
//free(&li);
}
return 0;
}
pre_line output(int n,pre_line li)
{
pre_line li_new;
if (n == 2)
{
li_new.a[0][0] = 1;
li_new.a[0][1]= 1;
printf("%d %d\n",li_new.a[0][0],li_new.a[0][1]);
return li_new;
}
else
{
int i = n - 2; //最后一行的数组行号
li_new= output(n - 1,li);//递归实现,打印前面的三角,并返回最后一排的数字
li_new.a[i][0] = 1;
li_new.a[i][i + 1] = 1;
for (int j = 1; j<= i; j++)
{
li_new.a[i][j] = li_new.a[i - 1][j] + li_new.a[i - 1][j - 1];
}
printf("%d", li_new.a[i][0]);
for (int j = 1; j <= i + 1; j++)
{
printf(" %d", li_new.a[i][j]);
}
printf("\n");
return li_new;
}
}
就是先定义一个二维数组,然后进行问题求解。顺便说一句,数据结构真的很重要,因为我一开始想的还是用一维数组来做,之后有点招架不住。
因为最近刚好又回顾了一遍有关递归的算法,于是又寻(zuo)思(si)使用递归的方法来求解问题。
面前首先遇到的难题就是怎么把数组在两个函数之间传递。因为除了Base Case 之外的其他每一行打印都必须要前一行的数据。所以我在递归函数里必然要返回前一行的数据。
之后搜索了一下这个问题,看到可以用结构体的方法传递多维数组。
于是,入坑。因为真的是还不熟悉结构体的用法。
于是,一开始是在传递结构体的指针。结构体声明如下:
typedef struct preline{
int a[100][100];
}*pre_line;
这时才恍然大悟,依昔记得当时C语言老师每次定义结构体,使用时不忘先malloc一下。
话不多说,我马上又去初始化了一下。
可是运行时,第一行正确打印“1 1”,第二行中间那个值却十分怪异。
一步步调试发现,每次递归调用函数完返回后,即使赋值给了li_new,可是li_new里的数据全都是“新鲜"的-------应该说是未初始化的。
这才恍然大悟--------因为传递的是指针变量,当output()每次执行完成之后,里面的li_new会自动销毁,所以即使外层li_new得到了上一层的地址,指向的地区也已经没有了已经赋值的数组。
跳出大坑
既然传递结构体指针行不通,那么直接传递结构体是否可行呢? 结果是肯定的。
函数返回后会将output()函数中li_new的内存按位拷贝给外层的li_new;所以li_new里面的数组值也会被完全保留下来。在递归中使用结构体和平时使用时还是有很大区别的。
马不停蹄地改完代码,一步步运行,终于发现打印第二行时,上一层调用的output()传递过来的数组信息都保存下来了。
至此,本次Debug之旅圆满结束。当然以后的路还很长,我一定会坚持下去。只要今天比昨天进步一点,总有一天我会有质的飞跃。
CRN,你一定要加油!
看到有人的迭代方法和我的不太一样,贴过来,学习一下。 来自 http://blog.csdn.net/acmman/article/details/25913255
#include
#include
int a[100][100];
int Fun(int n,int m)
{
if(a[n][m]!=0)//之前已经计算过的值,下次再次调用的时候就没有必要再次递归运算了
return a[n][m];
if(m==1)
return 1;
if(m==n)
return 1;
else
{
a[n][m]=Fun(n-1,m)+Fun(n-1,m-1);
return a[n][m];
}
}
int main()
{
int i,j,n,m;
while(scanf("%d",&n)!=EOF)
{
memset(a,0,sizeof(a));
for(i=1;i<=n;i++)
{
if(i==1) continue;
for(j=1;j<=i;j++)
{
if(j!=1)
printf(" ");
printf("%d",Fun(i,j));
}
puts("");
}
}
return 0;
}