解释我怀疑的最简单方法就是一个例子......所以这是:
我在perl中有一组带有一组间隔的数组,我需要获得互补的间隔,换句话说,就是那个集合的反映像。从:
@ ary1 = qw(23-44 85-127 168-209)
印刷间隔:23-44,85-127,168-209。
将其转换为:
...- 22,45-84,128-167,210 -...
非常感谢您的考虑!
答案 0 :(得分:4)
如果间隔已经排序且不重叠:
#!/usr/bin/perl
use warnings;
use strict;
use List::MoreUtils qw{ natatime };
my @ary1 = qw(23-44 85-127 168-209);
my $diff = 1;
my $pair = natatime 2, '...',
map({ map { $diff *= -1; $_ + $diff }
split /-/
} @ary1),
'...';
my @compl;
while (my ($from, $to) = $pair->()) {
push @compl, "$from-$to";
}
print "@compl\n";
<强>输出强>
...-22 45-84 128-167 210-...
答案 1 :(得分:3)
use warnings;
use strict;
use Set::IntSpan;
my @ary1 = qw(23-44 85-127 168-209);
my $spec = join ',', @ary1;
my $set = Set::IntSpan->new($spec);
my $list = $set->holes();
print "$list\n";
__END__
45-84,128-167
答案 2 :(得分:0)
您可能更喜欢此解决方案,其效果类似于@Choroba
的答案。
我使用@pairs
显示了结果Data::Dump
数组,它显示了数组的内容(如果您需要进一步处理它),print
,它会输出文本符合你在问题中的要求。
use strict;
use warnings;
my @input = qw/ 23-44 85-127 168-209 /;
my $begin;
my @pairs;
for (@input) {
next unless /(\d+)-(\d+)/;
push @pairs, [ $begin // '...', $1-1 ];
$begin = $2+1;
}
push @pairs, [ $begin, '...' ];
use Data::Dump;
dd \@pairs;
print join(', ', map join('-', @$_), @pairs), "\n";
<强>输出强>
[["...", 22], [45, 84], [128, 167], [210, "..."]]
...-22, 45-84, 128-167, 210-...
答案 3 :(得分:0)
要迂腐,如果给定的集合包含-Inf或+ Inf,则所提供的解决方案都不起作用,例如:('...-22', '45-84', '128-167', '210-...')
。
如果区间被排序并且不重叠并且数据总是符合给定的语法,这里的解决方案也适用于上述情况(这与{{1提供的非常相似) }}):
@Borodin