九度OJ 1073 杨辉三角形

题目描述:

输入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;

看到和正确代码的不同了吗?结果在编译时都没有通过,说是指针li使用前没有初始化。

这时才恍然大悟,依昔记得当时C语言老师每次定义结构体,使用时不忘先malloc一下。

话不多说,我马上又去初始化了一下。

可是运行时,第一行正确打印“1 1”,第二行中间那个值却十分怪异。

一步步调试发现,每次递归调用函数完返回后,即使赋值给了li_new,可是li_new里的数据全都是“新鲜"的-------应该说是未初始化的。

这才恍然大悟--------因为传递的是指针变量,当output()每次执行完成之后,里面的li_new会自动销毁,所以即使外层li_new得到了上一层的地址,指向的地区也已经没有了已经赋值的数组。


跳出大坑

既然传递结构体指针行不通,那么直接传递结构体是否可行呢?  结果是肯定的。

函数返回后会将output()函数中li_new的内存按位拷贝给外层的li_new;所以li_new里面的数组值也会被完全保留下来。在递归中使用结构体和平时使用时还是有很大区别的。

马不停蹄地改完代码,一步步运行,终于发现打印第二行时,上一层调用的output()传递过来的数组信息都保存下来了。

九度OJ 1073 杨辉三角形_第1张图片  至此,本次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;
}


你可能感兴趣的:(OJ,C语言,OJ,结构,调试)