如何消除perl中子串的重复

时间:2012-10-28 15:39:31

标签: perl substring

我试图在每次出现'E'时打破一个字符串。但是在输出中我想跳过那些早先在前一个破损循环中到达的子串。例如。如果我取一个字符串$s='ABCDEABCDEABCDEABCD',其中'E'出现在字符串中的第5,10和15位置,那么由于位置10处的断裂而出现的子串不应出现在由位置断裂引起的子串中15.下面给出的脚本在'E'的每个位置都会断开。但我无法阻止子串重复。请帮忙!

my $s = 'ABCDEAXBCDEAYBCDEAZBCD';
my @where; my @array;my @final;
my $result; my $j; 

for ($j = 0; $j <= 2; $j++) {

    $where[j] = index($s,"E",$where[j-1]) + 1;
    push @array, $where[j];
}


for my $array (@array) {

    substr($s, $array-1, 1) = "\0";
    my @a = split(/E(?!P)/, $s);
    substr($s, $array-1, 1) = 'E';

    $_ =~ s/\0/E/g foreach (@a);
    $result = join ("E,", @a).'E'; 
    @final  = split(/,/, $result);
    print "@final\n";
}

我得到的输出是:

ABCDEAXBCDE AYBCDE AZBCDE
ABCDE AXBCDEAYBCDE AZBCDE
ABCDE AXBCDE AYBCDEAZBCDE

预期产出:

ABCDEAXBCDE AYBCDE AZBCDE
ABCDE AXBCDEAYBCDE
AXBCDE AYBCDEAZBCDE

1 个答案:

答案 0 :(得分:2)

我不明白你的问题的目的/描述,但是你可以添加一个哈希来跟踪你之前看到的子串并删除它们,方法是将最后一个循环改为:

my %seen;
for my $array (@array) {
  substr($s, $array-1, 1) = "\0";
  my @a = split(/E(?!P)/, $s);
  substr($s, $array-1, 1) = 'E';
  $_ =~ s/\0/E/g foreach (@a);
  $result = join ("E,", @a).'E'; 
  @final = grep { !exists $seen{$_} } split(/,/, $result);
  $seen{$_}=1 for @final;
  print "@final\n";
}

将输出更改为:

ABCDEAXBCDE AYBCDE AZBCDE
ABCDE AXBCDEAYBCDE
AXBCDE AYBCDEAZBCDE

您的代码看起来已经从C翻译过。如果您试图更清楚地描述您想要做什么,也许有人可以帮助您使用更具惯用性的Perl版本。