Perl函数:findOddCount

时间:2017-12-04 17:34:13

标签: perl

您好,

我正在尝试编写一个Perl findOddCount函数,该函数在给定列表中找到一个奇数次出现的值。

#!/usr/bin/perl

sub findOddCount{
    @array1 = $_[0];
    $res=0;
    for( $i=0; $i < $#array1; $i++) {
            $res=($res ^ $array1[i])
            }
    return $res
}

@a1 = (1,1,2,2,3,3,4,4,5,5,6,7,7,7,7);
@a2 = (10,10,7,7,6,6, 2,2,3,3,4,4,5,5,6,7,7,7,7,10,10);
@a3 = (6,6,10,10,7,7,6,6, 2,2,3,3,4,4,5,5,6,7,7,7,7,10,10);
@a4 = (10,10,7,7, 2,2,3,3,4,4,5,5,7,7,7,7,10,10,6);
@a5 = (6,6);
@a6 = (1);

print "odd value in a1 is "; print findOddCount(@a1); print "\n";
print "odd value in a2 is "; print findOddCount(@a2); print "\n";
print "odd value in a3 is "; print findOddCount(@a3); print "\n";
print "odd value in a4 is "; print findOddCount(@a4); print "\n";
print "odd value in a5 is "; print findOddCount(@a5); print "\n";
print "odd value in a6 is "; print findOddCount(@a6); print "\n";

预期产出:

odd value in a1 is 6
odd value in a2 is 6
odd value in a3 is 6
odd value in a4 is 6
odd value in a5 is 0
odd value in a6 is 1

但是,我的实际输出显示全部为0:

odd value in a1 is 0
odd value in a2 is 0
odd value in a3 is 0
odd value in a4 is 0
odd value in a5 is 0
odd value in a6 is 0

任何帮助将不胜感激。感谢。

2 个答案:

答案 0 :(得分:2)

如何在sub中使用参数以及其他一些缺陷存在直接错误。但是,即使清理完了,发布的代码中的方法也无法满足您的需求。

这是第一个工作版本

use warnings;
use strict;
use feature 'say';

my @test_data = ( 
     [1,1,2,2,3,3,4,4,5,5,6,7,7,7,7],
     [10,10,7,7,6,6, 2,2,3,3,4,4,5,5,6,7,7,7,7,10,10],
     [6,6,10,10,7,7,6,6, 2,2,3,3,4,4,5,5,6,7,7,7,7,10,10],
     [10,10,7,7, 2,2,3,3,4,4,5,5,7,7,7,7,10,10,6],
     [6,6],
     [1] 
);

for my $ra (@test_data) 
{
    say "For: @$ra";
    if (my @odds = odd_count(@$ra)) {
        say "\tValue(s) with odd count: @odds";
    }   
    else {
        say "\tNo values show odd number of times.";
    }   
}

sub odd_count {
    my %cnt;
    ++$cnt{$_} for @_;
    return grep { $cnt{$_} % 2 } keys %cnt;
}

评论

  • 始终使用use warnings;use strict;启动程序。很难夸大这些pragmas are的重要性。它不是迂腐;它直接有助于每一行代码

  • 参数作为标量的标量列表传递给函数。因此,对于func(@ary),函数中的@_具有({1}}元素(别名)。您的代码采用第一个元素@ary,并且所有内容都必须是错误的

  • 上面的子代表一个数组,因为它减少了代码和处理。但是:(1)大数组通过引用传递,$_[0](2)因为odd_count($ra) 别名参数,如果在sub中更改了调用者的数据可能会改变。见this post。如果这是一个问题,请创建一个可以使用的本地副本,@_my @ary = @_如果您通过了参考

  • my @ary = @{ $_[0] };$#array1中最后一个元素的索引,而不是元素的数量;因此,您需要@array1,而不是$i <= $#array1; ......

  • 但几乎不需要C风格的<循环。通过以下方式迭代索引:for

  • ^ operator,它按顺序返回其操作数XOR-ed,不能在此处执行您想要的操作,因为您的代码不能处理相同的元素组,但是盲目地贯穿所有这些。此外,代码只能记录一个值

  • 我使用哈希来收集值的计数,非常常见,for my $i (0..$#ary)

  • postfix notation
  • 要查找奇数,我使用grep,过滤那些值为奇数的键

答案 1 :(得分:0)

尝试在代码中插入一些调试语句,以查看代码是否正在执行您认为应该执行的操作。同时将use strictuse warnings放在脚本的顶部(以及每个脚本的顶部)。那些pragma帮助开始和经验丰富的Perl程序员捕获拼写错误以及许多其他不是我真正想做的结构。

use strict;
use warnings;

sub findOddCount {
    my @array1 = $_[0];
    print STDERR "Length of \@array1 is ",0+@array1,", expected ",0+@_,"\n";
    my $res=0;
    print STDERR "\$#array1 is $#array1, expected $#_\n";
    for (my $i=0; $i < $#array1; $i++) {
        $res=($res ^ $array1[$i]);
        print STDERR "\$array1[$i] is $array1[$i], value for \$res is $res\n";
    }
    return $res
}