1

假设我有三个词"blue""red""pink"

我希望生成所有字母组合,其中我从“蓝色”中取出两个字母,然后从“红色”中添加两个字母,然后从“粉红色”中添加两个字母,例如

blrdpk

uerdin

ETC...

在 R 中,我通过将每个单词的字符分配到一个列表元素中来编码我的三个单词

words <- list( list("b","l","u","e"),  list("r","e","d"),  list("p","i","n","k") )

我知道我可以使用lapplywithcombn(words[[i]],m=2)从每个单词中获取 2 个字母的所有组合。

我有两个问题:

  1. 是否有更高级的 combn() 版本,它允许您从使用递归列表给出的不同“桶”中选择和连接组合?

  2. 如果没有 combn() 的高级版本,连接三个单词中每个单独的 2 个字母组合的最佳方法是什么?

  3. 如果我想从每个单词中获得不同数量的字母,有没有一种简单的方法可以做到这一点?[从答案之一中的用户评论中添加]

4

2 回答 2

4

可能有更高级的版本combn,但它已经相当先进了。例如,您可以通过指定FUN参数将函数应用于每个组合。将它与 expand.grid 和 Reduce 结合起来,你会得到类似的东西

Reduce(paste0, expand.grid(lapply(words, function(x) {
  combn(x, m=2, FUN=paste0, collapse="")
})))

编辑: 如果要从每个单词中选择的字母数量不同,则可以将此数字添加为单词列表中每个元素的属性,然后将该属性m用作combn. 例如,要为第一个单词选择一个字母,从第二个单词中选择两个字母,从第三个单词中选择三个字母:

for(i in seq_along(words)) {
  attr(words[[i]], "n") <- i
}

Reduce(paste0, expand.grid(lapply(words, function(x) {
  combn(x, m=attr(x, "n"), FUN=paste0, collapse="")})))

或者,您可以在 geektrader 的回答中使用 mapply。

于 2013-02-26T01:32:41.877 回答
2

这是从单词列表和要从每个单词中选择的字符数列表到所需结果的解决方案

> words
[1] "blue" "red"  "pink"
> wordsplit <- strsplit(words, split="")
> wordsplit
[[1]]
[1] "b" "l" "u" "e"

[[2]]
[1] "r" "e" "d"

[[3]]
[1] "p" "i" "n" "k"

> lengths <- c(2, 1, 3)
> combos <- expand.grid(mapply(function(word, n) combn(word,m=n, FUN=paste0, collapse=""), wordsplit, lengths))
> head(combos)
  Var1 Var2 Var3
1   bl    r  pin
2   bu    r  pin
3   be    r  pin
4   lu    r  pin
5   le    r  pin
6   ue    r  pin

> do.call('paste0', combos)
 [1] "blrpin" "burpin" "berpin" "lurpin" "lerpin" "uerpin" "blepin" "buepin" "beepin" "luepin" "leepin" "ueepin" "bldpin" "budpin" "bedpin" "ludpin"
[17] "ledpin" "uedpin" "blrpik" "burpik" "berpik" "lurpik" "lerpik" "uerpik" "blepik" "buepik" "beepik" "luepik" "leepik" "ueepik" "bldpik" "budpik"
[33] "bedpik" "ludpik" "ledpik" "uedpik" "blrpnk" "burpnk" "berpnk" "lurpnk" "lerpnk" "uerpnk" "blepnk" "buepnk" "beepnk" "luepnk" "leepnk" "ueepnk"
[49] "bldpnk" "budpnk" "bedpnk" "ludpnk" "ledpnk" "uedpnk" "blrink" "burink" "berink" "lurink" "lerink" "uerink" "bleink" "bueink" "beeink" "lueink"
[65] "leeink" "ueeink" "bldink" "budink" "bedink" "ludink" "ledink" "uedink"
于 2013-02-26T02:13:19.830 回答