【问题标题】:List all combinations of strings that together cover all given elements列出一起覆盖所有给定元素的所有字符串组合
【发布时间】:2017-07-20 14:15:51
【问题描述】:

假设我得到了以下字符串:

1:{a,b,c,t}
2:{b,c,d}
3:{a,c,d}
4:{a,t}

我想制作一个程序,为我提供这些字符串的所有不同组合,其中每个组合都必须包含每个给定的字母。 所以例如上面的组合是字符串 {1&2, 1&3, 2&3&4, 1&2&3&4, 2&4}。

我正在考虑使用 for 循环来执行此操作,程序将查看第一个字符串,查找缺少哪些元素,然后通过列表查找具有这些字母的字符串。但是我认为这个想法只会找到两个字符串的组合,而且它需要列出程序中的所有字母,这似乎很不经济。

【问题讨论】:

  • 2&4 不包括每个字母吗?还有1&2&3&4?
  • 是的,感谢您指出我的错误

标签: r string combinations


【解决方案1】:

我认为这样的事情应该可行。

sets <- list(c('a', 'b', 'c', 't'),
             c('b', 'c', 'd'),
             c('a', 'c', 'd'),
             c('a', 't'))

combinations <- lapply(2:length(sets),
                       function(x) combn(1:length(sets), x, simplify=FALSE))
combinations <- unlist(combinations, FALSE)
combinations
# [[1]]
# [1] 1 2
# 
# [[2]]
# [1] 1 3
# 
# [[3]]
# [1] 1 4
# 
# [[4]]
# [1] 2 3
# 
# [[5]]
# [1] 2 4
# 
# [[6]]
# [1] 3 4
# 
# [[7]]
# [1] 1 2 3
# 
# [[8]]
# [1] 1 2 4
# 
# [[9]]
# [1] 1 3 4
# 
# [[10]]
# [1] 2 3 4
# 
# [[11]]
# [1] 1 2 3 4

u <- unique(unlist(sets))
u
# [1] "a" "b" "c" "t" "d"

Filter(function(x) length(setdiff(u, unlist(sets[x]))) == 0, combinations)
# [[1]]
# [1] 1 2
# 
# [[2]]
# [1] 1 3
# 
# [[3]]
# [1] 2 4
# 
# [[4]]
# [1] 1 2 3
# 
# [[5]]
# [1] 1 2 4
# 
# [[6]]
# [1] 1 3 4
# 
# [[7]]
# [1] 2 3 4
# 
# [[8]]
# [1] 1 2 3 4

【讨论】:

  • 很好的答案,有没有办法编辑它,所以它不在列表中计算 NA。例如如果我让sets&lt;- list(c("a", "b", "c", NA), c("a", "b", "c")),我想得到和sets&lt;- list(c("a", "b", "c"), c("a", "b", "c"))一样的结果
  • @user7512228 您可以在计算开始时使用sets &lt;- lapply(sets, na.omit) 删除缺失值;如果您不想修改sets,请使用临时变量。
【解决方案2】:

首先... 有时间我会编辑这个答案。以下结果取决于选择的顺序。我还没有弄清楚如何展平列表。如果我可以展平它,我会对每个结果进行排序,然后删除重复项。

v = list(c("a","b","c","t"),c("b","c","d"),c("a","c","d"),c("a","t"))

allChars <- Reduce(union, v) # [1] "a" "b" "c" "t" "d"

charInList <- function(ch, li) which(sapply(li, function(vect) ch %in% vect))
locations <- sapply(allChars, function(ch) charInList(ch, v) )
# > locations
# $a
# [1] 1 3 4
# 
# $b
# [1] 1 2
# 
# $c
# [1] 1 2 3
# 
# $t
# [1] 1 4
# 
# $d
# [1] 2 3

findStillNeeded<-function(chosen){
  haveChars <- Reduce(union, v[chosen]) 
  stillNeed <- allChars[!allChars %in% haveChars] 
  if(length(stillNeed) == 0 ) return(chosen) #terminate if you dont need any more characters
  return ( lapply(1:length(stillNeed), function(i) { #for each of the characters you still need
    loc <- locations[[stillNeed[i]]] #find where the character is located
    lapply(loc, function(j){
      findStillNeeded(c(chosen, j)) #when you add this location to the choices, terminate if you dont need any more characters
    }) 
  }) )

}

result<-lapply(1:length(v), function(i){
  findStillNeeded(i)
})

【讨论】:

  • 非常感谢,能否请您解释一下函数 charInList 的输入是什么?即:什么是ch和li?
猜你喜欢
  • 2015-03-18
  • 2018-06-29
  • 1970-01-01
  • 2015-07-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多