从perl中的文本文件中获取1,2和3位数字的总和



假设在文件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";

最新更新