如何修改我的程序以打印出Pascal的三角形?

所以首先帕斯卡三角是这样的:如何修改我的程序以打印出Pascal的三角形?

您看到的第一行是零第i行。

当你是一名计算机科学家时,这并不罕见 。

C(N,K)= N:

在帕斯卡三角形每个术语可以与下式的组合来预测!/[k! *(n - k)!],其中“n”是行,“k”是从零到n的任何整数。

所以由此可以得出帕斯卡三角可以用(N,K)组合预测:

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

帕斯卡三角基本上是二项式概率:

(H + T)^ N#你翻转双面硬币“N”次,它的土地上的“正面”或“反面”和你收集的频率(H + T)^ 3 = 1(H^3)+ 3(H^2)(T)+ 3(H)每个在一组系数中,对于n = 3,我们得到扩展: (T^2)+1(T^3),其中这些系数: 1,3,3,1在帕斯卡三角形的第3行。


我定义了一个阶乘,和组合,并能够与一些循环Perl代码获得帕斯卡三角的任何行的 系数号(!):

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.

}

如果我运行代码,并要求杨辉三角的第8行,我得到这样的:

Which row of Pascal's triangle to display: 8 

1 8 28 56 70 56 28 8 1

这对杨辉三角的第8行完全正确的。如果我从第0行循环到Pascal三角形的第8行,我会得到所有正确的Pascal三角形行,但它看起来不像一个三角形(它看起来更像一个盒子),所以我怎么修改我的代码来调整缩进。

如果我想要显示8行Pascal三角形,我该如何决定缩进第一行多少?我怎样才能做出一个“三角形”?

回答:

这是因为数事项布局的变化的宽度棘手。

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

但事实并非如此,除了前几行外;数字需要不同的空间。一种补救措施是使用固定宽度的数字,并使用该宽度调整缩进和分隔。

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

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是通过手工设定提前

# (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

回答:

左对齐三角形:

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;

}

中心三角形:

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);

}

回答:

这里是做的另一种方式:

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";

}

它怎么办?在打印的最大数量适合的第一个奇数宽度内适合每个数字。这是因为数字是用空格分隔的,并且会使每个宽度均匀(并且对于奇数三角形行可以将其整除)。然后使用printf来格式化数字。例如%5d将在5个字符内对齐数字。在除了最后一行之外的每行之前使用' ' x N生成一串N空格的必要空格。

的8帕斯卡三角:13

# 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

杨辉三角:

# 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个元素的总和。

该解决方案也是如何使用数组的 (引用)的一个很好的示例。

一个有趣的特点是,缩进从 中间元计算的最后一行(以最大的值)英寸

要提供三角形的美丽外观,单元格大小必须是偶数。 “基本”缩进是这个尺寸的一半。 每行的实际缩进是这个基本尺寸,乘以相应的 数字,从行索引和总行数得出。

use strict; 

use warnings;

use feature qw(say);

use POSIX qw(ceil);

my $rowCnt = 14; # How many rows

say "Pascal Triangle with $rowCnt rows:";

# Rows container, filled with a single row (containing single 1)

my @rows = ([ 1 ]);

my ($lastRow, $row, $ind);

# Generate/add further rows

for ($ind = 1; $ind < $rowCnt; $ind++) {

$lastRow = $rows[$#rows]; # Last row gathered so far

push(@rows, getNextRow($lastRow));

}

$lastRow = $rows[$#rows];

# Middle elem. of the last row

my $midElem = $$lastRow[($rowCnt - 1)/2];

# No of digits + separator, rounded up to even

my $elemSize = ceil((length($midElem) + 1)/2) * 2;

my $shf = $elemSize/2; # Shift size for a sigle step

# Print rows

for ($ind = 0; $ind < $rowCnt; $ind++) {

my $row = $rows[$ind];

my $spc = $shf * ($rowCnt - $ind - 1);

printRow($spc, $row, $elemSize);

}

sub getNextRow { # Create the next row and return the reference to it

my $lastRow = $_[0]; # Read param

my @row = (1); # Start the new row from a single 1

for (my $i = 0; $i < $#$lastRow; $i++) {

push(@row, $$lastRow[$i] + $$lastRow[$i + 1]);

}

push(@row, 1); # Add terminating 1

return \@row; # Result - reference to the created row

}

sub printRow { # Print a row of the triangle

my ($leadSpc, $row, $elemSize) = @_; # Read params

# Leading spaces and the initial element (always 1)

printf("%s1", ' ' x $leadSpc);

# Print the rest of the row

for (my $i = 1; $i <= $#$row; $i++) {

printf("%*d", $elemSize, $$row[$i]);

}

print("\n");

}

以上是 如何修改我的程序以打印出Pascal的三角形? 的全部内容, 来源链接: utcz.com/qa/259170.html

回到顶部