加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

数组 – 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);

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读