首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >我如何修改我的程序,以打印出帕斯卡的三角形?

我如何修改我的程序,以打印出帕斯卡的三角形?
EN

Stack Overflow用户
提问于 2017-12-03 01:51:44
回答 4查看 3.5K关注 0票数 3

首先,帕斯卡的三角形看起来是这样的:

你看到的第一行是零第一行。

当你是一名计算机科学家的时候,这没什么不寻常的。

Pascal三角形中的每一个项都可以用公式组合来预测:

C (n,k) = n!/ k *( n )!,其中"n“是行,"k”是从零到n的任意整数。

因此,Pascal三角形可以用(n,k)组合来预测:

这就是你在上图中看到的。

Pascal三角形基本上是二项式概率:

(H + T)^n #你抛出一个双面硬币"n“次,它落在”正面“或”尾巴“上,你用一组系数收集每个硬币的频率,对于n= 3,我们得到展开式:

(H + T)^3 = 1(H^3) + 3(H^2)(T) + 3(H)(T^2) + 1(T^3),其中这些系数: 1,3,3,1位于Pascal三角形的第3行。

我定义了一个阶乘(!)和一个组合,并且能够通过一些循环Perl代码在Pascal三角形的任意行上得到系数数:

代码语言:javascript
运行
复制
use strict;
use warnings;

# Note the first row is row 0.
print("\nWhich row of Pascal's triangle to display: ");
my $row = <STDIN>; # The row that you want to display # This is also n. 
my $terms = $row + 1; # The number of terms is one more than the row number. 

Pascal_Row($row); # Print the Pascal numbers for that row. 

# Function displays the numbers for a row of Pascal's triangle. 
#######################################################
sub Pascal_Row
{
    my $row = shift; # Row is passed in. 

    for(my $k = 0; $k < $row + 1; $k++) # k alternates, but not the row which is n. 
    {
        print(combination($row, $k), "\t") # Print each row. 
    }
    print("\n"); # Print a newline after each time this function is called.
}

# This computes the factorial of a number.
###########################################
sub factorial
{
    my $number = shift; # argument. 
    my $factorial_number = 1; # initalize the factorial. 

    for(my $i = 1; $i <= $number; $i++)
    {
        $factorial_number *= $i; # compute the factorial, by multiplying all terms up to and including number.
    }

    return $factorial_number; # Return the factorial number. 
}

# Computes a matehmatical combination usually denoted as C(n, k)
# where n is the row number, and k is each item in a row of Pascal's traingle 
sub combination
{
    my($n, $k) = @_; # from input. 

    # This is the mathematical formula for a combination. 
    my $combination_number = factorial($n) / (factorial($k) * factorial($n - $k));

    return $combination_number # And returning it. 
}

如果我运行代码并请求Pascal三角形的第8行,我得到如下信息:

代码语言:javascript
运行
复制
Which row of Pascal's triangle to display: 8
1       8       28      56      70      56      28      8       1

帕斯卡三角形的第8行完全是这样。如果我将它从0行循环到Pascal三角形的第8行,我将得到Pascal三角形的所有正确行,但它看起来不像三角形(看起来更像一个框),所以我如何修改代码来调整缩进。

如果要显示Pascal三角形的8行,如何决定缩进第一行的量?我怎么才能做一个“三角形”?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2017-12-03 06:50:56

这是一个棘手的问题,因为不同的数字宽度对布局很重要。

每一行需要缩进行中数字间隔的一半,适当地乘以(最后一行为零,行为第一行为1) --也就是说,如果数字本身都是相同宽度的。

但情况并非如此,除了前几行;数字占用的空间各不相同。一种解决办法是对数字使用固定宽度,并使用该宽度调整缩进和分离。

首先计算所有行,以便找到数字的最大宽度。

代码语言:javascript
运行
复制
use warnings;
use strict;
use feature 'say';
use List::Util qw(max);

my $max_row = (shift || 8); 

my @rows = map { pascal_row($_) } 0..$max_row-1;

my $max_num_wd = max map { length } @{$rows[-1]};
my $pad = 1;  # choice (must be non-zero)
my $sep     = ' ' x ($max_num_wd + 2*$pad);
my $lead_sp = ' ' x ($max_num_wd +   $pad);

for my $n (0..$#rows) {
    say $lead_sp x ($max_row-1-$n),
        join $sep, map { sprintf "%${max_num_wd}d", $_ } @{$rows[$n]};
}

sub pascal_row {
    my ($row) = @_;
    return [ map { n_over_k($row, $_) } 0..$row ];
}

sub n_over_k {
    my ($n, $k) = @_; 
    return factorial($n) / (factorial($k) * factorial($n - $k));
}

sub factorial {
    my ($n) = @_;        
    my $fact = 1;
    $fact *= $_ for 2..$n;
    return $fact;
}

这将打印正确的布局。$pad是一个任意整数,用于超过最大数字宽度的额外空间,用于缩进和分离;它必须>0来协调它们。(分离需要上面行中的数字的左和右空间,因此是2的因子。)

原始代码,在计算时打印,因此$max_num_wd是手动设置的。

代码语言:javascript
运行
复制
# (includes and subs same as above except for List::Util)    
my $max_row = (shift || 8); 

my $max_num_wd = 4; # maximum width of numbers
my $pad        = 1; # choice (non-zero)
my $sep     = ' ' x ($max_num_wd + 2*$pad);
my $lead_sp = ' ' x ($max_num_wd +   $pad);

for my $n (0..$max_row-1) {
    my @row = @{ pascal_row($n) };
    say $lead_sp x ($max_row-1-$n),
        join $sep, map { sprintf "%${max_num_wd}d", $_ } @row;
}

这打印一个正确的布局,数字最多4位宽,或$max_num_wd需要调整.

票数 2
EN

Stack Overflow用户

发布于 2017-12-03 06:42:34

左对角三角形:

代码语言:javascript
运行
复制
my $MAX_VAL_SIZE = 5;

for my $n (0...$N) {
   my @row;
   for my $k (0..$n) {
      push @row, C($n, $k);
   }

   say join "  ", map sprintf("%*d", $MAX_VAL_SIZE, $_), @row;
}

中心三角形:

代码语言:javascript
运行
复制
sub center {
   my ($n, $s) = @_;
   my $pad_len = $n - length($s);
   my $pad_len_l = int($pad_len/2);
   my $pad_len_r = $pad_len - $pad_len_l;
   return ( " " x $pad_len_l ) . $s . ( " " x $pad_len_r );
}

my $MAX_VAL_SIZE = 5;

for my $n (0...$N) {
   my @row;
   for my $k (0..$n) {
      push @row, C($n, $k);
   }

   my $row = join "  ", map center($MAX_VAL_SIZE, $_), @row;
   say center(($N+1)*($MAX_VAL_SIZE+2)-2, $row);
}
票数 3
EN

Stack Overflow用户

发布于 2017-12-03 11:46:52

下面是另一种方法:

代码语言:javascript
运行
复制
use strict;
use warnings;

sub fact {
  my $n = shift;
  return 1 if $n < 1;
  return $n * fact($n - 1);
}

sub n_over_k {
  my $n = shift;
  my $k = shift;
  return fact($n) / ( fact($k) * fact($n - $k) );
}

sub pascal_row {
  my $n = shift;
  return map { n_over_k($n - 1, $_) } (0 .. $n - 1);
}

my $n = shift || 8;

# $maxw is the first odd width where the biggest number will fit
my $max = 0;
map { $max = $_ if $_ > $max } pascal_row($n);
my $maxw = length('' . $max);
$maxw += ($maxw + 1) % 2;

# Print the Pascal´s triangle
foreach my $i (1..$n) {
  print ' ' x ( ( $maxw + 1 ) * ($n - $i) / 2 );
  foreach my $j ( pascal_row($i) ) {
    printf "%${maxw}d ", $j;
  }
  print "\n";
}

怎么做的?在第一个奇数宽度内匹配要打印的数字的最大值。这是因为数字是用空格分隔的,这将使每个宽度成为偶数(对于奇值三角形行,则可以被2除以)。然后使用printf格式化数字。例如,%5d将在5个字符内正确地对齐数字。在每一行前面,除了最后一行外,使用' ' x N生成必要的空格,这将生成一个N空间字符串。

帕斯卡的8三角形:

代码语言:javascript
运行
复制
# pascal.pl 8
                1
              1   1
            1   2   1
          1   3   3   1
        1   4   6   4   1
      1   5  10  10   5   1
    1   6  15  20  15   6   1
  1   7  21  35  35  21   7   1

帕斯卡的13三角形:

代码语言:javascript
运行
复制
# pascal.pl 13
                          1
                        1   1
                      1   2   1
                    1   3   3   1
                  1   4   6   4   1
                1   5  10  10   5   1
              1   6  15  20  15   6   1
            1   7  21  35  35  21   7   1
          1   8  28  56  70  56  28   8   1
        1   9  36  84 126 126  84  36   9   1
      1  10  45 120 210 252 210 120  45  10   1
    1  11  55 165 330 462 462 330 165  55  11   1
  1  12  66 220 495 792 924 792 495 220  66  12   1
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47614514

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档