超细节讲解杨辉三角!C语言与Python实现

11 篇文章 0 订阅

杨辉三角

  • 我们不讲数学,就讲它的实现吧。
  • (1)观察下图,我们知道,杨辉三角,中间不是 1 的数,它的值,等于它肩上两个数字的和。利用这一点规律,我们就可以构造出代码,写出中间的数 。
    在这里插入图片描述
  • (2)再看下面的这个形式的:
  • 我们得出 可以用二维数组表示杨辉三角,并观察这个图,结合二维数组中元素的下标,成功找到,上面的规律(肩上数之和)的代码表示!
  • 根据图中的规律很容易推敲出来,例如: a[8][3] = a[7][2] + a[7][3] , 再写个循环,就可以求每行的数的值
    在这里插入图片描述
  • (3) 关于 两边数字 1 的规律,那就更容易发现了。 分别是第一个后最后一个。 那么 还举例子: 第 i行a[i][0] = 1, a[i][i] = 1 就实现了两边为 1 了~

C语言实现

  • 根据上面的分析,我们分解步骤:
  • (1) 我们发现他其实是一个 正方形,然后只有下三角(如图的直角三角形),所以我们首先构造出来一个 n 乘 n的 二维数组,用它来存储 杨辉三角。
// 打印100行杨辉三角
#include<stdio.h>
int main()
{
	int yang[50][50] = {0};
	int i, j, m;


	// 打印杨辉三角
	for(i=0; i<50; i++)
	{
		// 这里只打印二维数组的杨辉三角部分没所以 j <= i
		for(j=0; j<=i; j++)
		{
			m = yang[i][j];
			printf("%d", m);
		}	
		printf("\n");
	}
	return 0;
}

如图:运行结果
在这里插入图片描述

  • (2) 我们接着打印出来两边的 1, 记住这个1 的规律。 它是在 一行中的 行首和行尾出现的
// 打印100行杨辉三角
#include<stdio.h>
int main()
{
	int yang[25][25] = {0};
	int i, j, m;

	// 补充代码打印杨辉三角两边的 1
	// 输出每行的1,位置是行首和 行尾,对应的下标是 [][0] , [][i].  i为当前行,以0开始 
	for(i=0; i<25; i++)
	{
		
		yang[i][0] = 1;
		yang[i][i] = 1;
	}

	// 打印杨辉三角
	for(i=0; i<25; i++)
	{
		for(j=0; j<=i; j++)
		{
			m = yang[i][j];
			printf("%d", m);
		}	
		printf("\n");
	}
	return 0;
}

运行结果:
在这里插入图片描述
** (3) 第三步,就到了关键的 中间部分的打印了,参考上面的正三角那张图片,我们知道, 下面的数,等于它肩膀上 两个数的。那么根据此规律,又可以继续写代码实现了!

第三步写完,也是所有代码都写完啦

// 打印100行杨辉三角
#include<stdio.h>
int main()
{
	int yang[25][25] = {0};
	int i, j, m;

	// 输出每行的1,位置是行首和 行尾,对应的下标是 [][0] , [][i].  i为当前行,以0开始 
	for(i=0; i<25; i++)
	{
		yang[i][0] = 1;
		yang[i][i] = 1;

		// 补充代码,打印一行中间的数字
		for(j=1; j<i; j++)
		{
			// 注意 j的取值,从每行的第二个数字,到倒数第二个数字,因为第一个最后的数字是 1固定的
			// 按照数的值 是它肩上两个数的和
			yang[i][j] = yang[i-1][j-1] + yang[i-1][j];	
		}
		
	}

	// 打印杨辉三角
	for(i=0; i<25; i++)
	{
		for(j=0; j<=i; j++)
		{
			m = yang[i][j];
			printf("%d  ", m);  // 为了格式好看,我们在这里加上两个空格,隔开数字!!!
		}	
		printf("\n");
	}
	return 0;
}

打印结果看看!
在这里插入图片描述

  • 是成功的,不过结果有点乱,终端里的排版不是很好!

有很多实现方法,不过经过我的分析考虑,写出来这么一种,希望对你有帮助

Python实现

方法一: 基于前面C语言的算法,用Python语法写一遍
  • 其中的 insert 方法实际上都可以用 append() 方法代替,但是我想体现出 C语言算法中的步骤,插入两边的1 ,用 insert,不考虑效率。
# 纯基本语法
yang = []
n = int(input("请输入你想打印的杨辉三角层数:"))
for i in range(0, n):
    temp = []
    temp.insert(0, 1)
    for j in range(1, i):
        num = yang[i-1][j-1] + yang[i-1][j]
        temp.append(num)
    # 因为 insert方法会在指定位置位置增加一个 值,若原本位置上有值,那么将被后移,造成第一行有两个1, 所以加个判断
    if i > 0:
        temp.insert(i, 1)
    yang.append(temp)

for k in yang:
    print(k) 

Python实现(函数式编程!)

方法2: 利用 sum() 及 zip 函数。
  • 这种是在网上找到的解法,真的厉害,想不到
def generate(numRows):

        l1 = [1]
        l2 = []
        n = 0
        while n<numRows:
            l2.append(l1)
            # 这里的 本质算法还是一样的 ,在列表前后分别加上 [0], 再利用zip 和sum 函数进行计算。 既解决了
            # 两边都是1 的问题, 也造成原来的元素错位。sum 求和,就等于是两肩上的数求和!! 厉害!并且只运用一层循环。
            l1 = [sum(t) for t in zip([0]+l1, l1+[0])] 
            n += 1
        return l2

print(generate(8))
方法3:map方法
  • 同样在网上找到的解法
def generate(numRows):

        if numRows==0:
            return []
        l1 = [[1]]
        n = 1
        while n<numRows:
            # 利用 map 函数 和匿名函数实现,本质和 zip num 实现是一样的,也是错位   
            l1.append(list(map(lambda x,y:x+y, [0]+l1[-1], l1[-1]+[0])))
            n += 1
        return l1

print(generate(8))

后两种方法没有利用 二维数组的思想,所以思想更加开阔,跳出拘泥! 本质都是 肩上两数相加。 但是使用了错位 等,构造出肩上两个数字和,并且同时解决 两边1 的问题,真的厉害~ 思维发散

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值