-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 numbers\n \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
4

3 回答 3

0

首先,导入sumfromList::Util使数字数组的求和更容易。

如果它是一个相对较小的文件(它可能是),如果您先将它们全部拉入一个数组并根据需要对它们进行 grep,事情会容易得多

所以在你打开你的文件后......

use List::Util 'sum';

my @nums = <$fh>;
chomp @nums;    # Remove trailing newlines;

my @values;

print "Sum of all 3 digits numbers\n";
@values = grep { length == 3 } @nums;
print join( ' + ', @values ), ' = ', sum( @values ), "\n";

print "Sum of all numbers starting with a digit 7\n";
@values = grep { index( $_, 7 ) == 0 } @nums;
print join(' + ', @values), ' = ', sum( @values ), "\n";

print "Sum of all numbers ending with a digit 8\n";
@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 numbers\n";
print join(' + ', @len_3), ' = ', sum( @len_3 ), "\n";
# ...

您拥有的“案例”越多,您需要跟踪的数组就越多。有更好的方法来做到这一点——例如将数组引用存储为哈希值——但如果你刚刚学习,现在可能会有点混乱。

于 2016-01-19T09:55:07.133 回答
0

我会这样处理它:

#!/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总和,但我想我会提供一个非模块。

于 2016-01-19T10:18:52.987 回答
-1

您可以使用正则表达式完成所有操作。

while( <$fh> ) {
   $sum1+= $_   if /^\d$/;
   $sum2+= $_   if /^\d{2}$/;
   $sum3+= $_   if /^\d{3}$/;
   $sum7+= $_   if /^7\d*$/;
   $sum8+= $_   if /^\d*8$/;
}

如果您将数字列在列表中,您可以将它们打印为:

local $" =  ' + ';
print "@sum1 = $sum1";
于 2016-01-19T09:06:03.413 回答