假設陣列是 (1,2,3,4,5,6,7,8,9),另一個子陣列是 (2,3,4) 有沒有檢查子陣列模式是否的函式(完全精確的順序)存在于陣列中?在這種情況下,它將回傳任何表明它存在的指標(索引)。如果陣列中存在多個子陣列,例如 (4,2,3,4,2,3,4),也需要處理重復項。如果它碰巧匹配多次,例如: Array = (2,3,2,3,2,2,3,2) Sub Array = (2,3,2) 將按順序回傳匹配的起始索引:0 ,2,5 或者如果它洗掉,將導致 (3,2)
編輯:元素不必是 num
uj5u.com熱心網友回復:
沒有內置方法,但很容易撰寫:
#!/usr/bin/env perl
use warnings;
use strict;
use feature qw/say/;
# Takes two arrayrefs of numbers.
#
# Returns the first index in the first one where the second list appears, or
# -1 if not found.
sub find_sublist( ) {
my ($haystack, $needle) = @_;
my $nlen = @$needle;
my $hlen = @$haystack;
return -1 if $hlen == 0 || $nlen == 0;
HAYSTACK_POS:
for (my $n = 0; $n <= $hlen - $nlen; $n ) {
for (my $m = 0; $m < $nlen; $m ) {
if ($haystack->[$n $m] != $needle->[$m]) {
next HAYSTACK_POS;
}
}
return $n;
}
return -1;
}
# Takes two arrayrefs of numbers.
#
# Returns a list of the starting indexes of the first list
# of every run of the second list. Returns an empty list if
# there are no matches.
sub find_sublists( ) {
my ($haystack, $needle) = @_;
my $nlen = @$needle;
my $hlen = @$haystack;
my @positions;
return @positions if $hlen == 0 || $nlen == 0;
HAYSTACK_POS:
for (my $n = 0; $n <= $hlen - $nlen; $n ) {
for (my $m = 0; $m < $nlen; $m ) {
if ($haystack->[$n $m] != $needle->[$m]) {
next HAYSTACK_POS;
}
}
push @positions, $n;
}
return @positions;
}
# Takes two arrayrefs of numbers.
#
# Returns a new list that is the first one with every non-overlapping run of
# the second second list removed.
sub remove_sublists( ) {
my @haystack = @{$_[0]};
my $needle = $_[1];
while ((my $pos = find_sublist @haystack, $needle) != -1) {
splice @haystack, $pos, @$needle;
}
return @haystack;
}
my @list1 = (1,2,3,4,5,6,7,8,9);
my @list2 = (4,2,3,4,2,3,4);
my @list3 = (2,3,2,3,2,2,3,2);
say find_sublist(@list1, [2, 3, 4]); # Returns 1
say find_sublist([2,9,3,4], [2,3,4]); # Returns -1
my @positions = find_sublists(@list2, [2,3,4]); # 1,4
say join(",", @positions);
@positions = find_sublists(@list3, [2,3,2]); # 0,2,5
say join(",", @positions);
say join(",", remove_sublists(@list1, [2,3,4])); # 1,5,6,7,8,9
say join(",", remove_sublists(@list3, [2,3,2])); # 3,2
uj5u.com熱心網友回復:
如果輸入是由您perl的整數表示的數字(如圖所示),您可以使用
# Indexes
my $pattern = pack "W*", @pattern;
my $array = pack "W*", @array;
my @indexes;
push @indexes, $-[0] while $array =~ /\Q$pattern/g;
# Removal
my $pattern = pack "W*", @pattern;
my $array = pack "W*", @array;
$array =~ s/\Q$pattern//g;
@array = unpack "W*", $array;
它如何處理重疊。
/---\ /---\ Removed
2,3,2 from 2,3,2,3,2,2,3,2
\---/ Not removed
請注意,如果您可以將輸入映射到數字,這也有效。
my ( %map_f, @map_r );
for ( @array, @pattern ) {
if ( !exists{ $map{ $_ } } ) {
$map_f{ $_ } = @map_r;
push @map_r, $_;
}
}
my $pattern = pack "W*", @map_f{ @pattern };
my $array = pack "W*", @map_f{ @array };
$array =~ s/\Q$pattern//g;
@array = @map_r[ unpack "W*", $array ];
這不是最好的演算法,但通過將作業從 Perl 轉移到正則運算式引擎,它應該非常快。
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/490744.html
下一篇:使TLD陣列在gtld下
