【Java基础】实现打印“杨辉三角形”

28 篇文章 0 订阅
22 篇文章 0 订阅

杨辉三角,是二项式系数在三角形中的一种几何排列,在中国南宋数学家杨辉1261年所著的《详解九章算法》一书中出现。在欧洲,帕斯卡(1623—-1662)在1654年发现这一规律,所以这个表又叫做帕斯卡三角形。帕斯卡的发现比杨辉要迟393年,比贾宪迟600年。


一、杨辉三角的性质

我们从这张杨辉三角示意图上发现,杨辉三角的每行行首与每行结尾的数都为1。而且,每个数等于其左上及其右上二数的和。这样我们发现,杨辉三角左右对称。

那么我们就可以通过这些基本概念把这个杨辉三角同我们所说的组合数即二项式系数联系在一起:

我们发现,第i行的第j个数,我们可以用CjiCij来表示从ii个元素中选取jj个元素的组合数。(注意,这里的第i行是从0计数)并且,由于对称性,我们可以发现,杨辉三角中第n行的第m个数恒等于本行的第n-m+1个数。与二项式系数知识点进行结合,我们会发现(1+x)n(1+x)n展开后,各次数的系数正好对应第nn行的每一项。

二、杨辉三角代码实现的递推公式

在很多题目中,我们常常需要用打表的形式先处理出杨辉三角矩阵,然后再以此为基础进行程序求解。那么我们打表的时候如果手存表格的话,不仅浪费考试时间,而且保证不了空间范围和正确性,这个时候需要我们使用递推的手段用程序处理出表格。

根据杨辉三角的性质,推出以下的递推公式:

C[i][j]=C[i−1][j]+C[i−1][j−1];

三、实现方式

3.1 使用数组的方式

根据上面的性质,如果我们要打印一个11行的杨辉三角形,我们可以将整个排列看做是一个n行,0-n列的矩阵,再结合上面的性质8,我们将这个矩阵用一个二维数组来实现,如下图:

完整代码:

package com.example.demo;

/**
 * @author Biyu
 * @projectName demo
 * @className: YangHui
 * @description //TODO
 * @date: 2023-01-22 23:28
 */
public class YangHui {
    public static void main(String[] args) {
        yangHui(10);
    }

    private static void yangHui(int row) {
        //定义row行,但暂时每行的列数先不定义
        int[][] values = new int[row][];
        for (int i = 0; i < values.length; i++) {
            //行0有1列,行1有2列,....,行n有n+1列
            values[i] = new int[i + 1];
            for (int j = 0; j < values[i].length; j++) {
                //根据性质1,每行的首尾都为:1
                if (j == 0 || j == values[i].length - 1) {
                    values[i][j] = 1;
                } else if (i > 1) {
                    //根据性质8,除首尾外的其它数字 = 上方数 + 上方左侧的数
                    values[i][j] = values[i - 1][j] + values[i - 1][j - 1];
                }
            }
        }
        print(values);
    }

    private static void print(int[][] values) {
        for (int i = 0; i < values.length; i++) {
            for (int j = 0; j < values[i].length; j++) {
                System.out.printf("%-4d", values[i][j]);
            }
            System.out.println();
        }
    }
}

数组的方式比较好理解,但需要创建二维数组,效率较低,接下来我们看一下不需要数组的写法。

3.2不使用数组的方式

  • 算法说明

根据递推公式:C[i][j]=C[i−1][j]+C[i−1][j−1];

第n行的m个数可表示为 C(n-1,m-1),即为从n-1个不同元素中取m-1个元素的组合数。

我们将其表示为C(i , j)的组合数,那么就有以下算法:

1、例如:i=3、j=2的位置上,值为C(3,2),即(3*2)/(1*2)=3/1 * 2/2 = 3
2、例如:i=5、j=3的位置上,值为C(5,3),即(5*4*3)/(1*2*3)= 5/1 * 4/2 * 3/3 = 5 * 2 * 1 = 10
3、例如:i=7、j=4的位置上,值为C(7,4),即(7*6*5*4)/(1*2*3*4) = 7/1 * 6/2 * 5/3 * 4/4 = 35

代码实现

package com.example.demo;

/**
 * @author Biyu
 * @projectName demo
 * @className: YangHui
 * @description //TODO
 * @date: 2023-01-22 23:28
 */
public class YangHui {
    public static void main(String[] args) {
        //yangHui(10);
        yangHui2(10);
    }

    private static void yangHui2(int n) {
        for (int i = 0; i < n; i++) {
            for (int j = 0; j <= i; j++) {
                //计算每列的值
                int value = 1;
                for (int k = 0; k < j; k++) {
                    value = value * (i - k) / (k + 1);
                }
                System.out.printf("%-4d", value);
            }
            System.out.println();
        }
    }

    private static void print(int[][] values) {
        for (int i = 0; i < values.length; i++) {
            for (int j = 0; j < values[i].length; j++) {
                System.out.printf("%-4d", values[i][j]);
            }
            System.out.println();
        }
    }
}

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

宝爷~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值