【问题标题】:Perl : Get array of all possible cases of a stringPerl:获取字符串所有可能情况的数组
【发布时间】:2015-07-17 23:11:43
【问题描述】:

我需要得到一个字符串的所有可能情况的数组。就像这里写的一样:

Combination of all possible cases of a string

如何在 Perl 中有效地做到这一点?

我想要这样的东西:

print "$_\n" for GetCases('perl');

# Output:
perl
Perl
...
pERl
...
PERL

注意

我标记了glob,因为它是我想要提供结果的函数,所以像我这样的人稍后会找到问题。然而,问题不仅仅在于这种特殊的使用案例。

相关问题:Should I insert some code when asking for idea?

【问题讨论】:

  • 太棒了。你有什么问题?
  • 嗯,不,不是真的。 Stack Overflow 旨在帮助人们解决编码问题。如果我们可以看到我们正在修复的代码,这样做会容易得多。或者实际上 - 他们实际上试图做的一个例子,因为这样做你会更好地了解适当的答案。您上面的问题现在看起来很像 XY 问题,因为您要解决的问题是不区分大小写的 glob。这要容易得多。
  • “这不会分散那些想成为第一的人的注意力” 这是否意味着我认为的意思——你想象贡献者之间的竞赛是为了获得第一个答案并因此得分,你尝试过的一个例子可能会减慢这些人的速度?虽然可能会有这样的人,但最好的海报只是试图写出他们能写出的最佳答案
  • @Borodin,我不认为这意味着你认为它意味着什么。有几种方法可以更快地获得reputation。有时人们会做出一个原始的答案,然后对其进行润色。没有别的意思了。
  • @Borodin,正是上面评论中所说的。人们对 stackexchange 有不同的目标和需求。询问我的 65 次重复练习的方法之一是,如果你的问题不如两个词那么清楚,你会在答案中消除歧义,部分是因为人们很着急,部分是因为他们太着急了懒得明白自己想要什么。在我的first question 中可以看到,太多的代码使它变得过于复杂和不清楚。

标签: string perl permutation glob case-insensitive


【解决方案1】:

如果您的目标是使用 if for glob,那么您可以使用 glob 的内置模式生成

my $filename = 'File.CSV';

my $test = $filename =~ s/([a-z])/sprintf '{%s,%s}', uc($1), lc($1)/iegr;

say $test, "\n";
say for glob $test;

输出

{F,f}{I,i}{L,l}{E,e}.{C,c}{S,s}{V,v}

FILE.CSV
FILE.CSv
FILE.CsV
FILE.Csv
FILE.cSV
FILE.cSv
FILE.csV
FILE.csv
FILe.CSV
FILe.CSv
FILe.CsV
FILe.Csv
FILe.cSV
FILe.cSv
FILe.csV
FILe.csv
FIlE.CSV
FIlE.CSv
FIlE.CsV
FIlE.Csv
FIlE.cSV
FIlE.cSv
FIlE.csV
FIlE.csv
FIle.CSV
FIle.CSv
FIle.CsV
FIle.Csv
FIle.cSV
FIle.cSv
FIle.csV
FIle.csv
FiLE.CSV
FiLE.CSv
FiLE.CsV
FiLE.Csv
FiLE.cSV
FiLE.cSv
FiLE.csV
FiLE.csv
FiLe.CSV
FiLe.CSv
FiLe.CsV
FiLe.Csv
FiLe.cSV
FiLe.cSv
FiLe.csV
FiLe.csv
FilE.CSV
FilE.CSv
FilE.CsV
FilE.Csv
FilE.cSV
FilE.cSv
FilE.csV
FilE.csv
File.CSV
File.CSv
File.CsV
File.Csv
File.cSV
File.cSv
File.csV
File.csv
fILE.CSV
fILE.CSv
fILE.CsV
fILE.Csv
fILE.cSV
fILE.cSv
fILE.csV
fILE.csv
fILe.CSV
fILe.CSv
fILe.CsV
fILe.Csv
fILe.cSV
fILe.cSv
fILe.csV
fILe.csv
fIlE.CSV
fIlE.CSv
fIlE.CsV
fIlE.Csv
fIlE.cSV
fIlE.cSv
fIlE.csV
fIlE.csv
fIle.CSV
fIle.CSv
fIle.CsV
fIle.Csv
fIle.cSV
fIle.cSv
fIle.csV
fIle.csv
fiLE.CSV
fiLE.CSv
fiLE.CsV
fiLE.Csv
fiLE.cSV
fiLE.cSv
fiLE.csV
fiLE.csv
fiLe.CSV
fiLe.CSv
fiLe.CsV
fiLe.Csv
fiLe.cSV
fiLe.cSv
fiLe.csV
fiLe.csv
filE.CSV
filE.CSv
filE.CsV
filE.Csv
filE.cSV
filE.cSv
filE.csV
filE.csv
file.CSV
file.CSv
file.CsV
file.Csv
file.cSV
file.cSv
file.csV
file.csv

【讨论】:

  • 谢谢,这就是我的目标。但是,我写了 Note 尤其是为了获得有关获取所有案例的答案。请您稍微编辑一下答案,以便完全回答问题吗?
  • @theoden:它怎么不能完全回答这个问题?
  • 它显示了您如何使用glob。我要求得到所有案件。这不是任何形式的严格,它只是误解了这个问题:我感兴趣的是如何创建一个通用案例列表,并提到了我遇到此类问题的任务。但我已经为您提供的优质有用的代码投了赞成票。
  • 谢谢,但我碰巧使用glob 并不意味着代码搜索文件。正如您在我的回答中看到的,它只是按照您的要求生成所有大小写混合的字符串。自己尝试一下,并为 $filename 尝试不同的值——这些名称不必存在
【解决方案2】:

我会考虑:

  • 遍历可能性的数量。 (2^长度)。
  • 以二进制形式打印“计数”,因为这会给出位掩码。
  • 使用该位掩码在每次迭代中翻转位。

类似这样的:

#!/usr/bin/env perl

use strict;
use warnings;

my $string = "abcde";

for my $mask ( 0 .. 2**length($string) - 1 ) {
    my @bits = split( '', sprintf( "%0" . length($string) . "b\n", $mask ) );

    for ( split( '', $string ) ) {
        if ( shift @bits ) {tr/a-z/A-Z/}
        print;
    }
    print "\n";
}

这适用于转换的纯字母字符串,但它总是会生成 2^length 字符串,并且任何 不是 字母的字符都会创建重复项。

'abcdef' 将生成 'abcdeF, abcdEf, abcdEF...ABCDEF' 的大小写变体。但是 '12345678' 将生成 256 个相同的字符串。

如果有问题,处理这种情况的最简单方法是使用字符串哈希而不是数组,并使用keys 提取唯一值。

但是,正如您在 cmets 中所指出的:

我需要不区分大小写的 glob 来查找文件夹中的所有文件,而不管大小写。由于我无法让 glob 不区分大小写地工作,因此我认为将所有可能的字符串情况提供给它是最好的出路。在我看来,没有比 Perl 更好的语言来处理这些事情了,但我不知道没有猴子代码怎么办。

您想要的是查看File::Glob - 特别是:nocase 参数。

【讨论】:

  • 这会产生很多重复,其中目标字符串中有非字母字符
  • 是的,这是真的。最初引用的问题是关于“普通”字母字符串的,并且生成方式几乎相同,这就是我这样做的原因。
  • 和平,这只是文件名。我正在编写一个简单的程序来快速访问我的观点。但是,@Borodin,您能否提供一个更清洁的解决方案?
  • OP 将处理哪些字符串的问题远不清楚。我认为您至少应该指出像12345678 这样的字符串将产生12345678 的256 个副本
  • 引用的帖子说:“我想要一个程序来生成:Abcdefghij ABcdef.. . . aBcdef.. . ABCDEFGHIJ”这就是我正在做的。不过我会修改明确。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-03-20
  • 2015-12-30
  • 1970-01-01
  • 1970-01-01
  • 2017-11-11
相关资源
最近更新 更多