【问题标题】:How do I find the specific amount/frequency of positive, negative, and zero integers in a file? (Perl)如何找到文件中正整数、负整数和零整数的具体数量/频率? (Perl)
【发布时间】:2017-06-24 20:29:43
【问题描述】:

我正在尝试打开一个文件,对其进行扫描,然后让程序打印出正数、负数和零的数量。我有程序成功打开文件,但找到“频率”是给我带来麻烦的地方。上课那天我病了,似乎找不到与我的具体提示有关的帮助。这是我到目前为止所拥有的:

#!/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 文件,每行有一个数字。

【问题讨论】:

  • 你真的需要像chomp ($infile); #Chomps the $infile Variable.这样的cmets吗?
  • 是的,我们的教授更喜欢我们拥有这些。另外,我添加了错误的代码开始。这就是我所拥有的。我只需要找出文件中有多少个 0 整数。

标签: perl file input integer frequency


【解决方案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 的返回码。如果你这样做,那么你会发现其他情况,比如文件不可读,或者是一个损坏的符号链接或一堆其他问题。

例如

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

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

【讨论】:

  • 另外值得指出的是,存在性测试是多余的,因为无论如何都必须检查open 的状态。
  • 请注意:redundant 在美式英语中的意思可能更像是 excessivelavish超出正常范围。例如,双因素身份验证是“冗余”安全性。这就是为什么我在这些页面中坚持多余的
【解决方案2】:

您可以使用&lt;=&gt; 运算符来准确获取您想要的内容。根据perldoc perlop

二进制“&lt;=&gt;”返回 -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
        };

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-01
    • 1970-01-01
    • 2010-10-18
    • 2014-12-18
    • 2018-09-05
    • 2015-10-01
    相关资源
    最近更新 更多