如何在文件中找到正整数,负整数和零整数的具体数量/频率? (Perl的)

时间:2017-02-07 14:35:15

标签: perl file input integer frequency

我正在尝试打开文件,扫描它,并让程序打印出正数,负数和零数。我有程序成功打开文件,但找到“频率”是给我带来麻烦的。我在上课的那天病了,似乎无法找到与我的具体提示相关的帮助。以下是我到目前为止的情况:

#!/usr/bin/perl
use strict;
use warnings;
my ( $ctrZ ) = ( 0 );
while( my $num = <DATA> ) {
        chomp($num);
        ## print "num=[$num]\n";
        if ( $num =~ /^-\d+$/ ) {
                $ctrZ++;
        }

printf("freq(0):%9s\n", $ctrZ );

exit;
__DATA__
19
-22
498
512
15
-932
0
22
808
17
-32

注意:我们的教授给了我们一个文件供我们使用。它是一个.txt文件,每行都有一个数字。

2 个答案:

答案 0 :(得分:1)

您的代码存在一些问题,但主要问题是:

if ($infile) { 
        $Pos_Int++;
        $Neg_Int++;
        $Zer_Int++;
}

那只是评估文件名$infile的内容。它永远是真的,因此你总是将所有的计数器增加一个。

所以你在这里所做的一切基本上是计算线条。

我还建议,你不需要:

open(FHIN, '<', $infile); #Opens the file prompted by user. 
my @lines = <FHIN>; #Variable storing the number of lines in the file.
chomp( @lines ); 
close(FHIN); 

打开文件,将其读入数组,然后迭代数组?

为什么不用while循环逐行(它也使用更少的内存)。

另外 - 好的风格是使用词法文件句柄而不是大写名称,这是全局范围。

所以:

open ( my $input, '<', $infile ) or die $!;  #check return code for errors. 
while ( my $line = <$input> ) { #iterate the input line by line, setting $_ for each. 
    $Pos_Int++ if $line > 0;
    $Neg_Int++ if $line < 0;
    $Zer_Int++ if $line == 0; 
}

应该做的伎俩 - 但请记住它不做任何输入验证。如果有必要,正则表达式可以帮助那里。

此外:

if (-e $infile) { #If the file can't be found, it will exit.

    } else {
        print ("No such file exists. Program closing.\n");
            exit;
}

这是多余的,因为您可以 - 并且应该 - 从open捕获返回代码。如果你这样做,那么你会发现其他条件,如文件不可读,或者是一个破损的符号链接或一堆其他问题。

E.g。

open ( my $input, '<', $infile ) or die "Problem opening file: $!";

$!会给你一个更有意义的错误代码 - 它会告诉你'没有这样的文件或目录'和'权限被拒绝'之间的区别。

答案 1 :(得分:-1)

您可以使用<=>运算符来准确获取所需内容。根据{{​​3}}:

  

二进制“<=>”返回-1,0或1,具体取决于左侧   参数在数值上小于,等于或大于右   参数。

所以:

$ perl -MData::Dumper -wne '$count{$_ <=> 0}++; END { print Dumper(\%count); }' numbers.txt

假设 numbers.txt 包含以下内容:

111
0
-892
-664
21
0
63
868
-351
-263
467
-58
625
724
0
0
990
107
-739
-501
-386
909
-96
0
-735

输出将是:

$VAR1 = {
          '0' => 5,
          '1' => 10,
          '-1' => 10
        };