假设在文件number_list.txt中给出了一组数字。从以下类别中查找文件中的数字总和:
Sum of all 1 digits numbers
Sum of all 2 digits numbers
Sum of all 3 digits numbers
Sum of all numbers starting with a digit 7
Sum of all number ending with a digit 8
在 Perl 中编写代码以查找上述总和
例:如果我们有"number_list.txt"
23
258
1
24
57
76
85
72
4
654
958
6
46
358
那么我们需要得到这样的答案
Sum of all 1 digits numbers
1 + 4 + 6 = 11
Sum of all 2 digits numbers
23 + 24 + 57 + 76 + 85 + 72 + 46 = 383
Sum of all 3 digits numbers
258 + 654 + 958 + 358 = 2228
Sum of all numbers starting with a digit 7
76 + 72 = 148
Sum of all number ending with a digit 8
258 + 358 + 958 = 1574
到目前为止,我已经做到了。
#!/usr/bin/perl
use strict;
use warnings;
my $filename = "numbers.txt";
open( my $fh, '<', $filename ) or die "Can't open $filename: $!";
my @array1;
my @array2;
my @array3;
my @array4;
print "n n";
while ( my $line = <$fh> ) {
#if ( length($line) == 1)
#{
# push (@array1, $line);
#}
if ( length($line) == 2)
{
push (@array2, $line);
}
if ( length($line) == 3)
{
push (@array3, $line);
}
if ( length($line) == 4)
{
push (@array4, $line);
}
}
#print "n Sum of all digits numbersn n";
#for each (@array1) {
# print "$_";
# }
my $sum1 = 0;
my $sum2 = 0;
my $sum3 = 0;
print "n n Sum of all 1 digits numbers of:n n";
for each my $num2 (@array2) {
print "$num2";
$sum1 = $sum1 + $num2;
}
print "n Sum = $sum1";
print "n n Sum of all 2 digits numbers of:n n";
for each my $num3 (@array3) {
print "$num3";
$sum2 = $sum2 + $num3;
}
print "n Sum = $sum2";
print "n n Sum of all 3 digits numbers of:n n";
foreach my $num4(@array4) {
print "$num4";
$sum3 = $sum3 +$num4;
}
print "n Sum = $sum3";
所以我很难以简单的方式制作这个程序。有什么简单的方法必须做这个程序吗?
而且我也很难得到
Sum of all numbers starting with a digit 7
Sum of all number ending with a digit 8
首先,从List::Util
导入sum
,使数字数组求和更容易。
如果它是一个相对较小的文件(可能是这样),如果您先将它们全部拉到一个数组中并在需要时对其进行 grep,事情就会容易得多
所以在你打开你的文件后...
use List::Util 'sum';
my @nums = <$fh>;
chomp @nums; # Remove trailing newlines;
my @values;
print "Sum of all 3 digits numbersn";
@values = grep { length == 3 } @nums;
print join( ' + ', @values ), ' = ', sum( @values ), "n";
print "Sum of all numbers starting with a digit 7n";
@values = grep { index( $_, 7 ) == 0 } @nums;
print join(' + ', @values), ' = ', sum( @values ), "n";
print "Sum of all numbers ending with a digit 8n";
@values = grep { index( reverse($_), 8 ) == 0 } @nums;
print join(' + ', @values), ' = ', sum( @values ), "n";
理想情况下,您将任何重复的代码(例如总和的打印)放在sub
中。每次重新键入相同的代码时,都会增加出错的机会。
如果您想通过流式传输文件来做到这一点,那么您将不得不随时跟踪多个数组
my (@len_3, @len_4, @len_5, @start_7, @end_8);
while (my $n = <$fh>) {
if ( length $n == 3 ) {
push @len_3, $n;
}
# ...
if ( index($n, 7) == 0 ) {
push @start_7, $nl=;
}
}
print "Sum of all 3 digits numbersn";
print join(' + ', @len_3), ' = ', sum( @len_3 ), "n";
# ...
您拥有的"案例"越多,您需要跟踪的数组就越多。有更好的方法可以做到这一点 - 例如将数组引用存储为哈希值 - 但如果你只是学习,那现在可能有点混乱。
我会这样处理它:
#!/usr/bin/perl
use strict;
use warnings;
use Data::Dumper;
use List::Util qw ( sum );
my %numbers;
my %startswith;
open( my $fh, '<', "numbers.txt") or die $!;
while (<$fh>) {
my ( $num, $start_num ) = m|((d)d*)|;
push( @{ $numbers{length($num)} }, $num );
push( @{ $startswith{$start_num} }, $num );
}
close ( $fh );
print Dumper %numbers;
print Dumper %startswith;
foreach my $len ( sort keys %numbers ) {
print "Sum of all $len digits numbers:n";
print join( "+", @{ $numbers{$len} } ), "n";
print sum ( @{$numbers{$len}}),"n";
}
foreach my $first ( sort keys %startswith ) {
print "Sum of all numbers starting with $first:n";
print join( "+", @{ $startswith{$first} } ), "n";
print sum ( @{ $startswith{$first} } ), "n";
}
这给出了以下输出:
Sum of all 1 digits numbers:
1+4+6
11
Sum of all 2 digits numbers:
23+24+57+76+85+72+46
383
Sum of all 3 digits numbers:
258+654+958+358
2228
Sum of all numbers starting with 1:
1
1
Sum of all numbers starting with 2:
23+258+24
305
Sum of all numbers starting with 3:
358
358
Sum of all numbers starting with 4:
4+46
50
Sum of all numbers starting with 5:
57
57
Sum of all numbers starting with 6:
654+6
660
Sum of all numbers starting with 7:
76+72
148
Sum of all numbers starting with 8:
85
85
Sum of all numbers starting with 9:
958
958
并且将隐式支持任意长度数字。(你可以用List::Util
来表示总和,但我想我会提供一个非模块。
您可以使用正则表达式完成所有操作。
while( <$fh> ) {
$sum1+= $_ if /^d$/;
$sum2+= $_ if /^d{2}$/;
$sum3+= $_ if /^d{3}$/;
$sum7+= $_ if /^7d*$/;
$sum8+= $_ if /^d*8$/;
}
如果将数字放入列表,则可以将它们打印为:
local $" = ' + ';
print "@sum1 = $sum1";