首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >从for循环中删除重复的数字

从for循环中删除重复的数字
EN

Stack Overflow用户
提问于 2019-08-13 04:55:17
回答 1查看 162关注 0票数 1

我在R中有以下代码(由Mark -Finding all possible combinations of numbers to reach a given sum发布),它允许我将数字加到目标值上。但是,我希望代码返回所有可能的组合,而不重复相同的数字,并将删除的数字存储在单独的列表中。我需要分配索引值吗?

代码语言:javascript
运行
复制
x <- c(55,10,13,26,34,72,51,96,13)

subset_sum = function(numbers,target,partial=0){
  if(any(is.na(partial))) return()
  s = sum(partial)
  if(s > target) return()
  if(between(s,target-3,target)) print(sprintf("%s = %s",paste(partial[-1],collapse=" "),s))
  for(i in seq_along(numbers)){
      n = numbers[i]
      remaining = numbers[(i+1):length(numbers)]
      subset_sum(remaining,target,c(partial,n))
    }
}

subset_sum(x,60)

#The actual output is:
[1] "10 13 34 = 57"
[1] "26 34 = 60"

#I expect the output as (no repetition of 34):
[1] 26 34 = 60

提前感谢!

EN

回答 1

Stack Overflow用户

发布于 2019-09-23 10:19:34

RcppAlgos包(我是作者)就是专门为这个任务构建的。下面是一个利用comboGeneral的解决方案,它用于生成有或没有重复以及多集的组合。我们还可以使用constraintFuncomparisonFunlimitConstraints来约束输出

代码语言:javascript
运行
复制
library(RcppAlgos)
mySubsetSum <- function(x, myTarget, repeats = FALSE) {
    if (0 %in% x)
        x <- x[-which(x == 0)]

    if (repeats) {
        tbl <- table(x)
        vals <- as.numeric(names(tbl))
        myfreqs <- unname(tbl)
    } else {
        vals <- unique(x)
        myfreqs <- rep(1, length(vals))
    }

    ## Add zero length(vals) - 1 times
    myfreqs <- c(length(vals) - 1, myfreqs)
    vals <- c(0L, vals)

    combs <- comboGeneral(vals, length(vals), freqs = myfreqs, 
                          constraintFun = "sum", 
                          comparisonFun = "==", 
                          limitConstraints = myTarget)

    lapply(1:nrow(combs), function(x) combs[x, combs[x,] != 0])
}

mySubsetSum(x, 60)
[[1]]
[1] 26 34

mySubsetSum(x, 60, TRUE)
[[1]]
[1] 26 34

[[2]]
[1] 13 13 34

它是用C++编写的,以获得最大的速度。以下是一个演示其效率的示例:

代码语言:javascript
运行
复制
set.seed(42)
s <- sample(-50:50, 20)
s
[1]  42  43 -22  31  12  -1  19 -38  11  14  -9  41  33 -28 -10  30  38 -41 -11  -5

system.time(bigTest <- mySubsetSum(s, 170))
 user  system elapsed 
0.039   0.000   0.040

length(bigTest)
[1] 2135

## Over 1 million total combinations
comboCount(c(0, s), 20, freqs = c(19, rep(1, 20)))
[1] 1048575

以下是bigTest的输出示例

代码语言:javascript
运行
复制
bigTest[1:5]
[[1]]
[1] -41 -38 -28 -22 -10  -5  11  12  14  19  30  31  33  38  41  42  43

[[2]]
[1] -41 -38 -28 -22  -9  -5  -1  11  12  14  19  30  31  33  38  41  42  43

[[3]]
[1] -41 -38 -28 -22  -1  11  12  19  30  31  33  38  41  42  43

[[4]]
[1] -41 -38 -28 -11 -10  -5  12  14  19  30  31  33  38  41  42  43

[[5]]
[1] -41 -38 -28 -11  -9  -5  -1  12  14  19  30  31  33  38  41  42  43

## View the last 5 combinations
bigTest[length(bigTest) - 4:0]
[[1]]
[1] 12 14 31 33 38 42

[[2]]
[1] 14 19 30 31 33 43

[[3]]
[1] 11 12 14 19 30 41 43

[[4]]
[1] 11 12 14 19 31 41 42

[[5]]
[1] 11 12 14 19 33 38 43


all(sapply(bigTest, sum) == 170)
[1] TRUE

您还可以查找在某个范围内具有和的组合。看起来OP最初是有这个想法的,因为OP使用了来自dplyrbetween (至少我认为它来自dplyr)。

代码语言:javascript
运行
复制
sumRange <- comboGeneral(c(0, s), 20, freqs = c(19, rep(1, 20)), 
                         constraintFun = "sum", 
                         comparisonFun = c(">", "<"), 
                         limitConstraints = c(155, 165))

all(rowSums(sumRange) > 155 & rowSums(sumRange) < 165)
[1] TRUE
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57468130

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档