如何通过删除或大写小写字母来判断字符串是否可以转换为另一个字符串?

时间:2016-08-27 22:07:21

标签: perl

在perl中,我有两个输入字符串,例如ahueFFggLKyHFFGLK。我希望能够在没有小写字母组的情况下迭代输入的所有可能组合(ahueg ... ahau ... hegy等)所以在每次迭代中都会删除小写字母,剩下的小写字母会大写:

ah:
  ueFFggLKy                (UEFFGGLKY)
^^

au:
 h eFFggLKy                (HEFFGGLKY)
^ ^

hegy:
a u FF gLKy | a u FFg LKy  (AUFFGLKY)
 ^ ^  ^     |  ^ ^   ^

auegy:
 h  FF gLK  |  h  FFg LK    (HFFGLK)
^ ^^  ^   ^   ^ ^^   ^  ^    -^--^-

最后一个选项(auegy)就是答案,我希望能够迭代字母以确定我是否能够将ahueFFggLKy转换为HFFGLK而无需修改任何字母大写字母。此示例将返回"YES"

如果fOoBarBAR之类的输入出现,我无法将fOoBar转换为BAR,因为O中的fOoBar是资本化的。我的程序将返回"NO"

有人可以向我提供一个如何做到的perl示例吗?

2 个答案:

答案 0 :(得分:1)

我认为我理解了你的要求:第一个字符串可以通过删除或上限任何小写字母进行转换,并且你想知道第二个字符串是否可以通过这种方式从第一个字符串派生出来

我建议您可以将第二个字符串转换为正则表达式模式来实现此目的。如果第二个字符串中的每个大写字母必须与第一个字母中相应的大写或小写字母匹配,并且任意数量的插入小写字母,则转换是可能的。否则它不是

该程序实现了这个想法

use strict;
use warnings 'all';
use feature 'say';

my @pairs = (
    [ qw/ ahueFFggLKy HFFGLK / ],
    [ qw/ fOoBar      BAR    / ],
);

for my $pair ( @pairs ) {
    my ($s1, $s2) = @$pair;
    printf "%s => %s -- %s\n", $s1, $s2, contains($s1, $s2) ? 'YES' : 'NO';
}

sub contains {
    my ($s1, $s2) = @_;

    my $re = join ' \p{Ll}* ', map { "(?i: $_ )" } $s2 =~ /\p{Lu}/g;
    $re = qr/ ^ \p{Ll}* $re \p{Ll}* $ /x;

    $s1 =~ $re;
}

输出

ahueFFggLKy => HFFGLK -- YES
fOoBar => BAR -- NO


要从STDIN读取像@pairs这样的数组,您可以编写类似这样的内容

my @pairs;

{
    local $/;
    my @input = split ' ', <>;
    push @pairs, [ splice @input, 0, 2 ] while @input > 1;
}

答案 1 :(得分:0)

有点不合理的解决方案,但它似乎输出了你需要的东西。

#!/usr/bin/perl
use warnings;
use strict;

use List::Util qw{ all };

my ($str1, $str2) = qw( ahueFFggLKy HFFGLK );

my @small_indices;
push @small_indices, pos($str1) - 1 while $str1 =~ /[[:lower:]]/g;

my @present = (0) x @small_indices;
until (all { $_ } @present) {
    my $try = $str1;
    for my $i (reverse 0 .. $#present) {
        substr $try, $small_indices[$i], 1,
            $present[$i] ? substr $str1, $small_indices[$i], 1
                         : q();
    }

    if (uc $try eq $str2) {
        print $present[$_] ? q() : substr $str1, $small_indices[$_], 1
            for 0 .. $#present;
        print ":\n";

        my $j = 0;
        for my $i (0 .. length($str1) - 1) {
            my $char = substr $str1, $i, 1;
            if ($char eq uc $char || $present[$j++]) {
                print $char;
            } else {
                print '.';
            }
        }
        print "\n";
    }

    my $idx = 0;
    $present[$idx] = 0, ++$idx while $present[$idx];
    $present[$idx] = 1;
}

它构建一个指示符函数@present,它表示字符串中存在小写字母。通过将1添加到与函数对应的二进制数来迭代@present的所有可能值。