递归删除相邻的重复字符

时间:2013-12-10 10:09:02

标签: perl

我有一个字符串说

$str = "hhiiishs aappllee eerrffdd"

我想从字符串中递归删除相邻的重复字符。我不知道如何写递归。我编写了一个不递归的代码,但是如果我们按字符串传递

就可以工作
use strict;
use warnings;

    my $str = "AABBCCDEEFDDS asdwdwws ffoorr";

    sub remove {
        my $var1 = "";
        my $str = $_[0];
        my @arr = split (//, $str);
        my $f = "";
        foreach (0..$#arr) {
            if ( $arr[$_] eq $var1) {
                next;
                #substr ( $str, $_)
            } else {
                $var1 = $arr[$_];
                $f = "$f"."$arr[$_]";
            }
        }
        $f = "$f"." ";
        return $f;
    }

请指导我如何在Perl中编写递归。

3 个答案:

答案 0 :(得分:2)

你可以尝试,

$str =~ s/(.)\1+/$1/g;

给出

hishs aple erfd

答案 1 :(得分:1)

使用递归可能不是最佳选择,但下面是一个递归函数。

#!/usr/bin/perl

use strict;
use warnings;

my $foo = "aabbccddeeffgg hhiijjkkllmmnnoo pp";
print reDup($foo), "\n";

sub reDup {
    my @string = split ('', shift); #split string into array of characters
    my $val;
    for my $i( 0..$#string){

        if(defined($val) && $string[$i] eq $val){
            @string[$i..$#string] = @string[($i+1)..$#string];  #if last char checked = current char, shift the array to the left.
            pop @string;    #Above leaves unwanted element at the end, so pop it off 
            my $str = join('', @string);
            return reDup($str); #do it all again
        }
        $val = $string[$i];
    }
    return join('', @string);   #when the for loops if statement is never executed, it must contain no duplicates.
}

答案 2 :(得分:1)

sub _remove_adjacent {
   my $out = shift;
   if (@_ == 0) {
      return $out;
   }
   elsif (@_ == 1) {
      return $out.$_[0];
   }
   elsif ($_[0] eq $_[1]) {
      shift;
      return _remove_adjacent($out.shift(@_), @_);
   } else {
      return _remove_adjacent($out.shift(@_), @_);
   }
}       

sub remove_adjacent {
   my ($in) = @_;
   return _remove_adjacent('', split(//, $in));
}

当然,这是纯粹的尾递归,因此它可以内联到循环中。

sub remove_adjacent {
   my ($in) = @_;

   my @in = split(//, $in);
   my $out = '';
   while (1) {
      if (@in == 0) {
         last;
      }
      elsif (@in == 1) {
         $out .= $in[0];
         last;
      }
      elsif ($in[0] eq $in[1]) {
         shift(@in);
         $out .= shift(@in);
      } else {
         $out .= shift(@in);
      }
   }

   return $out;
}

这可以进一步清理,但它表明递归在这里是一种纯粹的浪费。