perl6 排列匹配
perl6 Permutation match
我仍在尝试进行排列匹配,我想知道是否有人有更好的方法来做到这一点。我想以任何顺序匹配数组中的所有模式,即匹配数组中项目(字符串或其他对象)的排列。例如,如果数组是 (1,2,3),则如果字符串以任意顺序包含 1、2 和 3,则为真;即,如果字符串包含 (1,2,3).
的排列,则为真
我现在的是这样的:
my @x = < one eins uno yi two zwei dos er one one one two two two >;
my @z = < one eins uno yi two zwei dos er one one one two two two foo >;
my $y = "xxx one eins uno yi two zwei dos er xxx";
sub matchAllWords($aString, @anArray) {
my $arraySize = @anArray.elems;
if $arraySize == 0 { False; }
elsif $arraySize == 1 {
($aString.match(/:i "@anArray[0]" /)).Bool;
} else {
my $firstCheck = ($aString.match(/:i "@anArray[0]"/)).Bool;
if $firstCheck {
$firstCheck
and
(matchAllWords($aString, @anArray[1..*]));
} else {
return False;
}
}
}
say matchAllWords($y, @x);
# result is True, but it should NOT be True because $y should not
# match permutations of @x which contains multiple identical elements
# of "one" and "two"
say matchAllWords($y, @z); # False as expected;
问题是我的函数匹配数组中所有唯一的单词,但无法区分重复单词的排列。我可以添加越来越多的代码来判断一个词是否已匹配,但是更多的代码来实现一个简单的想法,"permutation match",是 un-perl-ly。有什么建议么?谢谢
新答案
根据大家的意见,这里重述一下我现在理解的问题,然后是一个新的解决方案:
测试字符串 Y
是否包含 Z
中的所有字符串,一个 Bag (multiset) 字符串,具有正确的复制计数/多重性。
my \Z = < one eins uno yi two zwei dos er two > .Bag ;
my \Y = "xxx one eins uno yi two zwei dos er two xxx" ;
sub string-matches-bag ($string, $bag) {
for $bag.kv -> $sub-string, $copy-count {
fail unless ($string ~~ m:g/ $sub-string /).elems == $copy-count
}
True
}
say string-matches-bag Y, Z
旧答案
say so $y.words.all eq @z.any
这行代码的解释在这个答案的最后一部分。
我发现你的问题很混乱。但我希望这个答案是您想要的,或者至少足以让事情朝着正确的方向发展。
我发现您的数据令人困惑。您的 $y
中有两个 'xxx'
单词,但任一数组中都有 none。所以那个位不能匹配。你的 @z
中有一个 'foo'
。那应该是 'xxx'
吗?你的 $y
中有一个 'one'
,但两个数组至少有 两个 'one'
。这是个问题吗?
我发现你的叙述也很混乱。
对于这个答案,我假设 @z
末尾有一个 xxx
,关键评论是:
a simple idea, "permutation match"
say so $y.words.all eq @z.any
so
returns 右侧表达式的布尔值计算(True
或 False
)。
so
右边的表达式使用Junctions。它的英文散文摘要是'all of the "words" in $y
, taken one at a time, are string equal to at least one element of @z
'.
这是您要求的简单解决方案吗?
我仍在尝试进行排列匹配,我想知道是否有人有更好的方法来做到这一点。我想以任何顺序匹配数组中的所有模式,即匹配数组中项目(字符串或其他对象)的排列。例如,如果数组是 (1,2,3),则如果字符串以任意顺序包含 1、2 和 3,则为真;即,如果字符串包含 (1,2,3).
的排列,则为真我现在的是这样的:
my @x = < one eins uno yi two zwei dos er one one one two two two >;
my @z = < one eins uno yi two zwei dos er one one one two two two foo >;
my $y = "xxx one eins uno yi two zwei dos er xxx";
sub matchAllWords($aString, @anArray) {
my $arraySize = @anArray.elems;
if $arraySize == 0 { False; }
elsif $arraySize == 1 {
($aString.match(/:i "@anArray[0]" /)).Bool;
} else {
my $firstCheck = ($aString.match(/:i "@anArray[0]"/)).Bool;
if $firstCheck {
$firstCheck
and
(matchAllWords($aString, @anArray[1..*]));
} else {
return False;
}
}
}
say matchAllWords($y, @x);
# result is True, but it should NOT be True because $y should not
# match permutations of @x which contains multiple identical elements
# of "one" and "two"
say matchAllWords($y, @z); # False as expected;
问题是我的函数匹配数组中所有唯一的单词,但无法区分重复单词的排列。我可以添加越来越多的代码来判断一个词是否已匹配,但是更多的代码来实现一个简单的想法,"permutation match",是 un-perl-ly。有什么建议么?谢谢
新答案
根据大家的意见,这里重述一下我现在理解的问题,然后是一个新的解决方案:
测试字符串 Y
是否包含 Z
中的所有字符串,一个 Bag (multiset) 字符串,具有正确的复制计数/多重性。
my \Z = < one eins uno yi two zwei dos er two > .Bag ;
my \Y = "xxx one eins uno yi two zwei dos er two xxx" ;
sub string-matches-bag ($string, $bag) {
for $bag.kv -> $sub-string, $copy-count {
fail unless ($string ~~ m:g/ $sub-string /).elems == $copy-count
}
True
}
say string-matches-bag Y, Z
旧答案
say so $y.words.all eq @z.any
这行代码的解释在这个答案的最后一部分。
我发现你的问题很混乱。但我希望这个答案是您想要的,或者至少足以让事情朝着正确的方向发展。
我发现您的数据令人困惑。您的 $y
中有两个 'xxx'
单词,但任一数组中都有 none。所以那个位不能匹配。你的 @z
中有一个 'foo'
。那应该是 'xxx'
吗?你的 $y
中有一个 'one'
,但两个数组至少有 两个 'one'
。这是个问题吗?
我发现你的叙述也很混乱。
对于这个答案,我假设 @z
末尾有一个 xxx
,关键评论是:
a simple idea, "permutation match"
say so $y.words.all eq @z.any
so
returns 右侧表达式的布尔值计算(True
或 False
)。
so
右边的表达式使用Junctions。它的英文散文摘要是'all of the "words" in $y
, taken one at a time, are string equal to at least one element of @z
'.
这是您要求的简单解决方案吗?