@t = qw(a b c d e + g h + j k m n l + h +);
@q = qw(a b c d e f g h i j k l m l j h h);
@s = qw(a b c d e f g h k j k l m l j h h);
foreach (0..$#q){
if($t[$_] eq ($q[$_] && $s[$_])){
print "$t[$_]";
}
print "$t[$_]-$t[$_]\n";
elsif($t[$_] eq '+' && $q[$_] eq $s[$_]){
print"$t[$_]";
}
else{
print "\n";
}
}
预期产出:
abcde+gh [1-8]
jk [10-11]
l+h+ [14-17]
此处@t
基于@q
和@s
的匹配,并根据@t
打印间隔。
我无法获得不匹配的间隔。请给我一个很好的解决方案
答案 0 :(得分:1)
您的代码在第4次编辑时引入了语法错误。您不能将任何代码放在if
的块及其elseif
之外。如果我理解正确,您想知道数组@q
,@s
和@t
何时排队,@t
允许'+'
作为通配符
这是一个解决方案。它使用$start
变量来检查我们是否在一个区间内并存储开头。如果我们在一个间隔或数组的末尾。我们打印间隔长度。可能有更好的格式化方法。最好的方法是引入更复杂的ad-hoc对象。如果您对间隔的开始和结束的索引不感兴趣,代码会更容易。
测试:我稍微重组了一下。此外,如果您已经知道$q[$_] eq $s[$_]
,则无需同时检查$t[$_] eq $s[$_]
和$t[$_] eq $q[$_]
。如果$t[$_] eq "+"
#!/usr/bin/env perl
use strict; # These aren't optional!
use warnings; # Always use them!
use 5.01; # for the // operator and say
my @t = qw(a b c d e + g h + j k m n l + h +);
my @q = qw(a b c d e f g h i j k l m l j h h);
my @s = qw(a b c d e f g h k j k l m l j h h);
my ($start);
sub print_interval{
my $end = shift;
printf((' 'x(8+$start-$end)). # inserting the whitespaces
"[%2d-%-2d]\n", $start, $end);
}
foreach (0..$#q){
my ($te, $qe, $se) = ($t[$_], $q[$_], $s[$_]); # just shorthands
if($qe eq $se && ($te eq "+" || $te eq $qe)){
$start //= $_; # if not set, set it to the current index
print $te;
}elsif (defined $start){
print_interval($_-1);
undef $start;
}
}
if (defined $start){
# if we are still in an interval at the end,
# we'll have to print that too.
print_interval($#q)
}
如果您对定义检查感到不舒服,还可以将$start
设置为-1
并检查0 <= $start
。
这是一个使用中间对象并将结果保存在数组中的解决方案,这样可以实现更好的格式化并且代码结构更好:
# … strict, warnings, array declarations
my ($res,@results);
foreach (0..$#q){
my ($te, $qe, $se) = ($t[$_], $q[$_], $s[$_]);
if($qe eq $se && ($te eq "+" || $te eq $qe)){
$res = {start => $_, string => ''} unless defined $res;
$res->{string} .= $te;
}elsif (defined $res){
$res->{end} = $_-1;
push @results, $res;
undef $res;
}
}
if (defined $res){ # still in interval
$res->{end} = $#q;
push @results, $res;
}
printf "%-9s[%2d-%-2d]\n", @{$_}{qw|string start end|} for @results;
答案 1 :(得分:1)
#!/usr/bin/perl
use strict;
use warnings;
my @t = qw(a b c d e + g h + j k m n l + h +);
my @q = qw(a b c d e f g h i j k l m l j h h);
my @s = qw(a b c d e f g h k j k l m l j h h);
my @current_interval = (); #will store the interval we are currently working on
my @intervals = (); #keeps track of all those intervals
for(0 .. $#t){
if($q[$_] eq $s[$_] and ($q[$_] eq $t[$_] or $t[$_] eq '+')){
push(@current_interval, $_);
}
else{
if(@current_interval){
push(@intervals, [$current_interval[0], $current_interval[$#current_interval]]);
@current_interval = ();
}
}
}
#when exiting the loop we dont want to lose our current interval!
if(@current_interval){
push(@intervals, [$current_interval[0], $current_interval[$#current_interval]]);}
#print intervals
for (@intervals){
my @c = @{$_};
print $c[0],"\t",$c[1],"\n";
}
我得到了你的间隔。 请注意我添加&#34;使用严格;使用警告&#34; - 在将此解决方案添加到项目之前。
问候蒂姆