数组 – Perl – 从数组中提取具有偏移量的数字系列
发布时间:2020-12-16 06:26:27 所属栏目:大数据 来源:网络整理
导读:我试图在整数数组中搜索一系列数字.例如,如果数组由数字1,2,3,10,12,14组成,则可以归纳为 1到3,偏移量为1, 偏移2为10到14 在我的代码下面,我从第二个元素循环遍历数组,跟踪连续数组元素之间的偏移量,如果偏移量发生变化,则创建一个新的“系列”: use strict
我试图在整数数组中搜索一系列数字.例如,如果数组由数字1,2,3,10,12,14组成,则可以归纳为
1到3,偏移量为1, 偏移2为10到14 在我的代码下面,我从第二个元素循环遍历数组,跟踪连续数组元素之间的偏移量,如果偏移量发生变化,则创建一个新的“系列”: use strict; use warnings; my @numbers = (1,14); #array to extract series from my $last_diff; my $start = $numbers[0]; my $end; my @all_series; #array will hold all information on series for my $i (1..($#numbers+1)){ my $diff; if ($i <($#numbers+1)){ $diff = $numbers[$i] - $numbers[$i-1]; } if (!$diff || ( $last_diff && ($last_diff != $diff)) ) { $end = $numbers[$i-1]; my $series = { 'start'=> $start,'end' => $end,'offset'=> $start == $end ? 1 : $last_diff,}; push @all_series,$series; $start = $numbers[$i]; } $last_diff = $diff; } use Data::Dumper; print Dumper(@all_series); 输出如下: $VAR1 = { 'offset' => 1,'end' => 3,'start' => 1 }; $VAR2 = { 'offset' => 1,'end' => 10,'start' => 10 }; $VAR3 = { 'offset' => 2,'end' => 14,'start' => 12 }; 这不是期望的结果,因为最后两个系列可以概括为一个(10到14,偏移2而不是两个系列). 算法中的缺陷与perl无关,但是,也许有人可以给我一个关于如何最好地处理这个问题的提示,也许存在一些perl特定的技巧. 在我的应用程序中,数组中的所有整数都按升序排列,并且不存在重复的数字. 编辑 可以将更多的数字汇总到系列,越好(我想最小化系列的数量!) 解决方法
问题在于三元运算符.如果你使用普通的
offset => $last_diff, 你会注意到有 $VAR2 = { 'offset' => 7,'start' => 10 这在某种程度上是正确的.为了避免这种情况,你可以在推送到@series后取消undef $diff.它会为你的情况产生预期的输出,但仍会将1 2 3 7 10 12 14视为三个序列,从1,7和12开始.你需要的是现在以某种方式使一个更长的句子贪婪. 我试验了以下内容,但你应该测试更多: #!/usr/bin/perl use warnings; use strict; use Data::Dumper; my @numbers = (1,14); my $last_diff; my $start = $numbers[0]; my @all_series; for my $i (1 .. $#numbers + 1) { my $diff; if ($i < $#numbers + 1) { $diff = $numbers[$i] - $numbers[ $i - 1 ]; } # Merge with the last number from the previous series if needed: if (!$last_diff # Just starting a new series. and $i > 2 # Far enough to have preceding numbers. and $diff and $diff == $numbers[ $i - 1 ] - $numbers[ $i - 2 ] ) { $all_series[-1]{end} = $numbers[ $i - 3 ]; $all_series[-1]{offset} = 0 if $all_series[-1]{start} == $all_series[-1]{end}; $start = $numbers[ $i - 2 ]; } if (! $diff or ( $last_diff && ($last_diff != $diff)) ) { push @all_series,{ start => $start,end => $numbers[ $i - 1 ],offset => $last_diff,}; $start = $numbers[$i]; undef $diff; } $last_diff = $diff; } print Dumper(@all_series); (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |