Perl-在增量值列表中查找缺失的数字
我需要找到一种方法来查找大序列中的无、一个或多个缺失值(200000多个) 这些值从文档中提取并放入文本文件中。 由于提取,值之间会有空格,因此可以使用类似这样的内容:Perl-在增量值列表中查找缺失的数字,perl,Perl,我需要找到一种方法来查找大序列中的无、一个或多个缺失值(200000多个) 这些值从文档中提取并放入文本文件中。 由于提取,值之间会有空格,因此可以使用类似这样的内容:$str=~s/^\s+|\s+$//g 提取看起来像这样(由2、3或4个空格分隔): 有没有一种简单的方法可以直接从文本文件中提取这些值,并使用Perl查找缺少的值 谢谢大家! 有没有一种简单的方法可以直接从文本文件中提取这些值 最简单的方法就是这样做。它删除了所有空白,并提取了数字 my @numbers = do{
$str=~s/^\s+|\s+$//g
提取看起来像这样(由2、3或4个空格分隔):
有没有一种简单的方法可以直接从文本文件中提取这些值,并使用Perl查找缺少的值
谢谢大家!
有没有一种简单的方法可以直接从文本文件中提取这些值
最简单的方法就是这样做。它删除了所有空白,并提取了数字
my @numbers = do{
open my $fh, '<', 'document.txt' or die $!;
local $/;
<$fh> =~ /\d+/g;
};
输出
如果您只有整数,您可以迭代整个过程并保留最新的数字,然后检查当前的数字是否还有一个。我遗漏了语法分析
use strict;
use warnings;
my @missing;
my $last;
while ( my $current = <DATA> ) {
$last ||= $current - 1; # start out with one less than the first
push @missing, $current unless $last + 1 == $current;
$last = $current;
}
p @missing;
__DATA__
120000
120001
120003
120004
120005
使用严格;
使用警告;
我的“失踪”;
我的最后一美元;
while(my$current=){
$last | |=$current-1;#从比第一个少一个开始
推送@missing,$current,除非$last+1==$current;
$last=$current;
}
p@缺失;
__资料__
120000
120001
120003
120004
120005
您需要在循环内部初始化$last
,并将其设置为比第一个数字小一个,否则将始终包含第一个数字
@missing
将包含120003
是否保证对源序列进行排序?是否有内联或单独的行也可以使用?注意,序列始终是排序的,当然,除非缺少一个数字:)我可以提取数据,以便每个数字也在新行上。“我可以提取数据,这样每个数字也会出现在新行上。“。您应该用这些信息更新您的问题…这样就可以将文本文件中的所有值转换为数字,对吗?然后下一步就是从中查找缺少的值。@Markpw:Yes。Exactly@simbabque当前位置我回答了部分问题。鉴于OP在s/^\s+\s+$//g
上的诡计,这似乎是一个特别的问题。奇怪的是,没有完全回答所有的问题,却得到了反对票!这就是为什么我发表评论,但没有投票。@simbabque:我没想到你会投票。您比这更聪明。可能需要更新答案,该答案还显示了如何提取每个OP中所有在同一行的数字,以覆盖所有基数。@stevieb,and.$last | |=$current-1
| |
表示?@ssr|
组合了(即|
)和赋值运算符=
。如果左侧的值为true,则不会发生任何事情。如果为false,则将右侧的值指定给左侧的值。因此,这基本上是这样的:如果未设置$last
,则将其设置为$current
减1。您还可以将其表示为$last=$current-1,除非$last
。
use strict;
use warnings 'all';
use feature 'say';
use Number::Range;
my @numbers = do {
open my $fh, '<', 'document.txt' or die $!;
local $/;
<$fh> =~ /\d+/g;
};
my $range = Number::Range->new(@numbers);
my @sections = $range->rangeList;
my $all = Number::Range->new("$sections[0][0]..$sections[-1][-1]");
$all->delrange($range->range);
say scalar $all->range;
120002
use strict;
use warnings;
my @missing;
my $last;
while ( my $current = <DATA> ) {
$last ||= $current - 1; # start out with one less than the first
push @missing, $current unless $last + 1 == $current;
$last = $current;
}
p @missing;
__DATA__
120000
120001
120003
120004
120005