zoukankan      html  css  js  c++  java
  • 杨辉三角

    杨辉三角

    前言

      关于杨辉三角,相信大家都很熟悉,忘记的同学请自行Wiki。下面引用一张 Wiki 上的图作为知识回顾。

    上面这张图可以简要概括出以下几点:

    1.每行数左右对称,且都是以1开始和结束的正整数。

    2.行数递增的同时,列数也在递增。

    3.两条斜边上的1除外,其它的元素值均由其上部两个数之和。

    如何用编程的方式实现打印(下三角)

    首先来看一下运行结果的截图:

    如上图,这是一个以下三角(直角三角形)的形式打印出来的,观察上面这张图,很容易就会使人联想到用一个矩阵来存储所有的数值,打印的时候只打印下三角即可。

    第1步:首先构建一个10x10的矩阵

    第2步:观察发现列下标为0的元素都为1,且行列下标值相等的元素也都为1

    第3步:其余元素均可由 array[i][j] = array[i-1][j] + array[i-1][j-1] 计算得到

    开始编写代码:【C语言实现】

    void PrintTriangle()
    {
        int arr[10][10]={0};
        int i,j;
        for(i=0;i<10;i++)
        {
            for(j=0;j<=i;j++)
            {
                if(j==0 || i==j)
                    arr[i][j]=1;
                else
                    arr[i][j]=arr[i-1][j]+arr[i-1][j-1];
                printf("%-4d", arr[i][j]);
            }
            printf("
    ");
        }
    }

    现在,我们固定了数组的大小。如果我们想拥有一个可以通过输入,选择打印行数的的方法,怎么办呢?把方法改为 PrintTriangle(int n) { int arr[n][n]={0}; ... } 不幸的是,这段代码在 C 中编译无法通过,因为 C 语言中数组定义要求的是一个常量表达式。

    那么,我们换成 C# 来试试:

    static void PrintTriangle(int n)
    {
        int[,] arr = new int[n, n];
        int i, j;
        for (i = 0; i < arr.GetLength(0); i++)
        {
            for (j = 0; j <= i; j++)
            {
                if (j == 0 || i == j)
                    arr[i, j] = 1;
                else
                    arr[i, j] = arr[i - 1, j] + arr[i - 1, j - 1];
                Console.Write(arr[i, j].ToString().PadRight(3));
            }
            Console.WriteLine();
        }
    }

    令人欣慰的是 C# 没有编译错误,我们完全可以在 C# 中使用变量定义数组。为什么 C# 支持而 C 不支持呢?这个已经超出本文的主旨了,有兴趣的同学可以搜索相关资料。

    现在,我们来思考另一个问题:我们只使用了一半的数组空间,而另一半却白白浪费掉了,实在可惜。有没有一种方式,可以让我们直接计算出相关元素的值,而无需用数组来做临时存储呢?为了阅读方便,我把上面的图贴在此处,仔细观察,是否可以用数学计算来表示每个元素的值。

    现在以列作为单位来观察其中的规律,每次循环进来都会首先打印 1,那么,我们就可以在每次内层循环进入的时候打印出 1,解决第1列。

    第2列参考循环中 i,j 值得变化,恰好 i-j 是第2列的值。

    第3列,继续来验证并总结这个规律,想啊想,想啊想。数学没学好,是硬伤啊。。呵呵

    你想到了吗?^_^  【C】

    void PrintTriangle(int n)
    {
        int num, i, j;
    
        for(i=0; i < n; i++)
        {
            num = 1;
            for(j=0; j <= i; j++)
            {
                printf("%-3d ", num);
                num = num * (i-j)/(j+1);
            }
            printf("
    ");
        }
    }


    是的,重点就是这个:num = num * (i-j)/(j+1) 。

    最后,我们来看另一种实现方式:

    1

    =======

    1 1

       1 1

    -----------

    1  2  1

    =======

    1  2  1

        1  2  1

    -------------

    1 3   3   1

    以此类推,我们只要在第2行开始,对 11 进行移位后相加运算就可以了。

    看一段 Python 的实现:

     def triangle(n):
         row = [1]
         k = [0]
         for x in range(n):
             print row
             row = [l+r for l,r in zip(row+k, k+row)]
  • 相关阅读:
    推荐一篇好文加上一些补充
    我也来写一个俄罗斯方块
    使用canvas绘制一个时钟
    断句:Store all parameters but the first passed to this function as an array
    Observer Pattern
    web worker 的 self
    练练断句
    as 什么意思?
    natively 在本地机器
    in mind (不是 切记 的意思)
  • 原文地址:https://www.cnblogs.com/kanlei/p/3426767.html
Copyright © 2011-2022 走看看