Explain the Yang Hui triangle in super detail! C language and Python implementation

Yanghui triangle

  • If we don't talk about mathematics, let's talk about its realization.
  • (1) Observing the picture below, we know that the Yang Hui triangle is not a number 1 in the middle , and its value is equal to the sum of the two numbers on its shoulder . Using this rule, we can construct the code and write the middle number.
    Insert picture description here
  • (2) Look at the following form:
  • We conclude that we can use a two-dimensional array to represent the Yang Hui triangle, and observe this graph, combined with the subscripts of the elements in the two-dimensional array, successfully found, the above law (the sum of the numbers on the shoulder) code represents!
  • It is easy to figure out according to the law in the figure, for example: a[8][3] = a[7][2] + a[7][3] , and then write a loop, you can find the value of the number in each row
    Insert picture description here
  • (3) Regarding the law of the number 1 on both sides, it is easier to find out. They are the first and the last respectively. Then another example: In the i-th row , a[i][0] = 1, a[i][i] = 1 realizes that both sides are 1~

C language implementation

  • According to the above analysis, we break down the steps:
  • (1) We found that it is actually a square, and then there is only a lower triangle (right triangle as shown in the figure), so we first construct an n by n two-dimensional array, and use it to store Yang Hui's triangle.
// 打印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;
}

As shown in figure: running result
Insert picture description here

  • (2) We then print out the 1 on both sides , remembering the rule of this 1 . It appears at the beginning and end of a line
// 打印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;
}

The result:
Insert picture description here
** (3) The third step, it is a critical part of the middle of the printing, refer to the above Triangle that picture, we know the following number, equal to its shoulders on two numbers and . Then according to this rule, you can continue to write code to achieve!

After the third step is finished, all the codes are finished.

// 打印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;
}

Print the results to see!
Insert picture description here

  • It was successful, but the result was a bit messy, and the layout in the terminal was not very good!

There are many implementation methods, but after my analysis and consideration, I wrote such a one, I hope it will be helpful to you

Python implementation

Method 1: Based on the previous C language algorithm, write it in Python syntax

  • The insert method can actually be replaced by the append() method, but I want to reflect the steps in the C language algorithm, inserting the 1 on both sides, using insert, regardless of efficiency.
# 纯基本语法
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 implementation (functional programming!)

Method 2: Use sum() and zip functions.

  • This is a solution found on the Internet, it’s really amazing, I can’t think of it
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))

Method 3: map method

  • The same solution found on the Internet
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))

The latter two methods do not use the idea of ​​two-dimensional arrays, so they are more open-minded and free from stickiness! Essentially, it is the addition of two numbers on the shoulders. But using misplacement, etc., to construct the sum of the two numbers on the shoulder, and to solve the problem of 1 on both sides at the same time, it is really amazing~ Divergence of thinking

Guess you like

Origin blog.csdn.net/pythonstrat/article/details/112785574