提问者:小点点

我怎样才能以各种可能的方式拆分字符串?


给定单词<code>abcd</code>,我将如何构造以下嵌套列表?

[ (abcd) (a bcd) (ab cd) (abc d) (a b cd) (a bc d) (ab c d) (a b c d) ]

这就是以各种可能的方式拆分单词,同时保持字母顺序。

Nemokosch 在#raku初学者上向我指出了 .teams 和模块截图,但我无法将它们放在一起。


共2个答案

匿名用户

你可以

> < li>

获取字符串枚举的所有组合(第0个除外),以确定拆分位置

然后在这些位置上剪断枚举修饰的字符串

  • 动态生成条件块

最后,取消对枚举的修饰并连接拆分的值:

use v6.e.PREVIEW;  # for `snip`

my $s  = "abcd";
my @ps = $s.comb.pairs;

my $res = (1..^$s.chars
              ==> combinations()
              ==> map({ @ps.snip: (&{.key < $OUTER::_} for $_) })
              ==> map( *>>.value>>.join ));

得到

>>> $res
((abcd) (a bcd) (ab cd) (abc d) (a b cd) (a bc d) (ab c d) (a b c d))

(wamba的答案更为简洁,但据我所知,它并不懒惰,在较大的字符串(例如,“abcd”x 5)上执行速度稍慢,所以我保留这个答案。)

以下是中间结果:

# Enumerated string
>>> @ps = $s.comb.pairs
[0 => a 1 => b 2 => c 3 => d]

# Combinations of the enumeration except 0s
# these are the splitting points actually
>>> $combs = (1..^$s.chars).combinations
(() (1) (2) (3) (1 2) (1 3) (2 3) (1 2 3))

从这些分裂点中,我们可以生成,例如,(*.key

# The output is actually different, but this is for demonstration
>>> $combs.map({ (&{.key < $OUTER::_} for $_) })
((), (*.key < 1), (*.key < 2), (*.key < 3), (*.key < 1, *.key < 2) ... (*.key < 1, *.key < 2, *.key < 3)

(第一个空的“条件”便于后面生成字符串,所以我们不单独处理这种情况。)

对于每个组合,例如(1,2),我们迭代this(for$_)并生成条件。1和2将依次是该后形式for循环中的$_,但如果我们输入{. key

在这一点上,经过剪辑后,我们有:

>>> $combs.map({ @ps.snip: (&{.key < $OUTER::_} for $_) }).raku
(((0 => "a", 1 => "b", 2 => "c", 3 => "d"),).Seq, ((0 => "a",), (1 => "b", 2 => "c", 3 => "d")).Seq, ((0 => "a", 1 => "b"), (2 => "c", 3 => "d")).Seq, ((0 => "a", 1 => "b", 2 => "c"), (3 => "d",)).Seq, ((0 => "a",), (1 => "b",), (2 => "c", 3 => "d")).Seq...)

我们有所需的拆分,除了有额外的包:枚举和拆分到chars。所以我们撤消。comb.pairs在开头用完成

匿名用户

您可以将< code>match与< code>:exhaustive一起使用:

"abcd"
andthen .match: /^ (\w+)+ $/,:ex
andthen .map: *.[0].put