如何计算Perl中出现的奇数



我有一个Perl程序,它应该计算元素在数组中出现的次数,如果元素出现的次数是奇数,则打印出元素的值。

这是我的密码。

#!/usr/bin/perl
use strict;
use warnings;
sub FindOddCount($)
{
my @arraynumber = @_; 
my $Even = 0;
my $i = 0;
my $j = 0;
my $array_length = scalar(@_);
for ($i = 0; $i <= $array_length; $i++)
{   
my $IntCount = 0;
for ($j = 0; $j <= $array_length; $j++)
{
if ($arraynumber[$i] == $arraynumber[$j])
{
$IntCount++;
print($j);
}
}
$Even = $IntCount % 2;
if ($Even != 0)
{
return $arraynumber[$i];
}
}   
if ($Even == 0)
{   
return "none";
}   
}
my @array1 = (1,1,2,2,3,3,4,4,5,5,6,7,7,7,7);
my @array2 = (10,10,7,7,6,6,2,2,3,3,4,4,5,5,6,7,7,7,7,10,10);
my @array3 = (6,6,10,7,7,6,6,2,2,3,3,4,4,5,5,6,7,7,7,7,10.10);
my @array4 = (10,10,7,7,2,2,3,3,4,4,5,5,7,7,7,7,10,10,6);
my @array5 = (6,6);
my @array6 = (1);
my $return_value1 = FindOddCount(@array1);
my $return_value2 = FindOddCount(@array2);
my $return_value3 = FindOddCount(@array3);
my $return_value4 = FindOddCount(@array4);
my $return_value5 = FindOddCount(@array5);
my $return_value6 = FindOddCount(@array6);
print "The Odd value for the first array is $return_value1n";
print "The Odd value for the 2nd array is $return_value2n ";
print "The Odd value for the 3rd array is $return_value3n ";
print "The Odd value for the 4th array is $return_value4n ";
print "The Odd value for the 5th array is $return_value5n ";
print "The Odd value for the sixth array is $return_value6n ";

这是我的结果。

第一个数组的奇数值为15第一个数组的奇数值为21第一个数组的奇数值为21第一个数组的奇数值为19第一个数组的奇数值为2第一个数组的奇数值是1

如果你不能判断。它打印数组中所有元素的计数,而不是返回出现奇数次的元素。此外,我还得到了这个错误。

在OddCount.pl第17行的数值eq(==(中使用未初始化的值。

第17行是比较第一个数组和第二个数组的地方。然而,这些值是明确实例化的,当我把它们打印出来时,它们就起作用了。问题出在哪里?

为数组构建一个频率哈希,然后遍历它以查看哪些元素具有奇数

use warnings;
use strict;
use feature 'say';
my @ary = qw(7 o1 7 o2 o1 z z o1);  # o1,o2  appear odd number of times
my %freq;
++$freq{$_} for @ary;
foreach my $key (sort keys %freq) { 
say "$key => $freq{$key}" if $freq{$key} & 1;
}

这比问题中的代码简单得多,但也很容易修复。请参见下文。

部分钞票

  • ++$freq{$_}将散列%freq中的密钥$_的值增加1,或者如果密钥不存在,则将其添加到散列中(通过自动激活(,并将其值设置为1。因此,当一个数组最后用这个代码迭代时,散列%freq包含键的数组元素和它们的值的元素计数

  • 测试$n & 1使用逐位AND——如果$n设置了最低位,则为true,因此如果它是奇数

  • ++$freq{$_} for @ary;是语句修饰符,为@ary的每个元素运行语句,其中当前元素由$_变量别名

这会打印

o1=>3o2=>1

奇数频率元素(如果有的话(的打印按元素的字母顺序排列。请更改为可能需要的任何特定顺序,或者告诉我。


对问题中代码的评论,这是正确的,有两个简单的修复。

  • sub FindOddCount($)中,它以错误的方式使用原型。我怀疑这是不需要的,所以我们不要纠缠于它——只需放弃它,使其成为sub FindOddCount

  • 循环中的索引包括数组的长度(<=(,因此在最后一次迭代中,它们试图索引到数组的最后一个元素。因一个错误而关闭。这可以通过将条件更改为< $array_length(而不是<=(来解决,但在上读取

  • 没有理由使用C样式循环,甚至没有理由对索引进行迭代。(此处需要,因为使用了数组中的位置。(脚本语言提供了更清洁的方式

    foreach my $i1 (0 .. $#arraynumber) { 
    my $IntCount = 0;      
    foreach my $i2 (0 .. $#arraynumber) { 
    if ( $arraynumber[$i1] == $arraynumber[$i2] ) { 
    ...
    

    0..N是范围运算符,它创建该范围内的数字列表。语法CCD_ 16是数组CCD_ 17中最后一个元素的索引。这正是我们所需要的。因此不需要阵列长度的

  • 用于检查代码的多(六(个数组可以通过使用引用以更好、更容易的方式进行操作;有关复杂数据结构的教程perldsc,尤其是数组的页面perlol

简而言之:当您删除原型并通过一个错误修复时,您的代码似乎是正确的。


不仅是脚本编写,例如,C++11引入了基于范围的循环

for (auto var: container) ...  // really const auto&, or auto&, or auto&&

链接(标准参考(显示

用作传统for循环的可读性更强的等价物[…]

使用哈希计算for循环中出现的次数。然后使用grep打印所需元素,如下所示:

#!/usr/bin/env perl
use warnings;
use strict;
use feature qw( say );
my @array = (10,10,7,7,6,6,2,2,3,3,4,4,5,5,6,7,7,7,7,10,10);
my %cnt;
# Count each element of the array:
$cnt{$_}++ for @array;
# Print only the array elements that occurred an odd number of times,
# separated by ", ":
say join q{, }, grep { $cnt{$_} % 2 } @array;
# 6, 6, 6

相关内容

  • 没有找到相关文章