您好,
我正在尝试编写一个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
任何帮助将不胜感激。感谢。
答案 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)
要查找奇数,我使用grep,过滤那些值为奇数的键
答案 1 :(得分:0)
尝试在代码中插入一些调试语句,以查看代码是否正在执行您认为应该执行的操作。同时将use strict
和use 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
}