【问题标题】:How to find Consecutive Numbers Among multiple Arrays?如何在多个数组中找到连续的数字?
【发布时间】:2016-06-24 14:36:07
【问题描述】:

我马上举个例子, 现在假设我有 3 个数组 a,b,c 例如

a = c(3,5)
b = c(6,1,8,7)
c = c(4,2,9)

我必须能够在其中提取连续的三元组,即,

c(1,2,3),c(4,5,6)

但这只是一个例子,我会有一个更大的数据集,甚至超过 10 个数组,因此必须能够找到长度为 10 的连续序列。

那么任何人都可以提供一种算法,在“n”个数组中找到长度为“n”的连续系列。

我实际上是在 R 中做这些事情,所以如果你在 R 中提供你的代码是更好的选择。但是任何语言的算法都非常受欢迎。

【问题讨论】:

  • 一个三元组中的每个元素是否必须来自不同的数组? {2,3,4} 会被视为有效的三元组吗?
  • 是的! , {2,3,4}, {6,7,8} 或 {7,8,9} 无效。

标签: arrays r algorithm permutation number-theory


【解决方案1】:

首先将数据重新组织成一个包含值和数组编号的列表。 对列表进行排序;你会有这样的:

1-2
2-3
3-1 (i.e. " there' s a three in array 1" )
4-3
5-1
6-2
7-2
8-2
9-3

然后循环列表,检查是否实际上有n个连续的数字,然后检查它们是否有不同的数组编号

【讨论】:

  • 好主意(赞成),如果相同的数字在更多向量中可能只有一个困难,但很容易调整解决方案来解决这个问题:)
【解决方案2】:

这是一种方法。这假设在组数中的观察序列中没有中断。这里是数据。

N <- 3
a <- c(3,5)
b <- c(6,1,8,7)
c <- c(4,2,9)

然后我将它们组合在一起并按观察结果排序

dd <- lattice::make.groups(a,b,c)
dd <- dd[order(dd$data),]

现在我在此表中查找代表所有三个组的行

idx <- apply(embed(as.numeric(dd$which),N), 1, function(x) {
    length(unique(x))==N
})

然后我们可以看到三元组

lapply(which(idx), function(i) {
    dd[i:(i+N-1),]
})

# [[1]]
#    data which
# b2    1     b
# c2    2     c
# a1    3     a
# 
# [[2]]
#    data which
# c1    4     c
# a2    5     a
# b1    6     b

【讨论】:

  • 这对于给定的示例非常有效。但是你能帮我组成一个组吗,因为我有“N”个数组,都作为一个列表中的一个列表。
【解决方案3】:

这是一个蛮力方法,如示例中的expand.grid 和三个向量

# get all combinations
df <- expand.grid(a,b,c)

使用combn 计算每个成对组合的差异。

# get all parwise differences
myDiffs <- combn(names(df), 2, FUN=function(x) abs(x[1]-x[2]))

# subset data using `rowSums` and `which`
df[which(rowSums(myDiffs == 1) == ncol(myDiffs)-1), ]

df[which(rowSums(myDiffs == 1) == ncol(myDiffs)-1), ]
   Var1 Var2 Var3
2     5    6    4
11    3    1    2

【讨论】:

  • 有什么想法可以在 expand.grid() 方法中传递“N”列表吗?
  • 我刚刚尝试过,expand.grid 将接受向量列表。您可以使用mgetls 在列表中收集向量。尝试我对this post 的回答来构建这样的列表。
【解决方案4】:

我已经编写了一个小递归函数,它将在您传递的向量中找到所有连续的三元组(至少需要传递三个)。它可能有点粗糙,但似乎有效。

该函数使用省略号... 来传递参数。因此,无论您提供多少参数(即数字向量),它都会将它们放入列表items 中。然后找到每个传递的向量中的最小值及其索引。

然后使用for() 循环创建和迭代与最小三元组对应的向量的索引,其中输出值被传递到输出向量outitems 中的输入向量被修剪并以递归方式再次传递给函数。 只有当所有向量都是NA,即向量中没有更多值时,函数才会返回最终结果。

library(magrittr)

# define function to find the triplets
tripl <- function(...){
  items <- list(...)

  # find the smallest number in each passed vector, along with its index
  # output is a matrix of n-by-2, where n is the number of passed arguments
  triplet.id <- lapply(items, function(x){
    if(is.na(x) %>% prod) id <- c(NA, NA)
    else id <- c(which(x == min(x)), x[which(x == min(x))])
  }) %>% unlist %>% matrix(., ncol=2, byrow=T)


  # find the smallest triplet from the passed vectors
  index <- order(triplet.id[,2])[1:3]
  # create empty vector for output
  out <- vector()

  # go through the smallest triplet's indices
  for(i in index){
    # .. append the coresponding item from the input vector to the out vector
    # .. and remove the value from the input vector
    if(length(items[[i]]) == 1) {
      out <- append(out, items[[i]])
      # .. if the input vector has no value left fill with NA
      items[[i]] <- NA
    }
    else {
      out <- append(out, items[[i]][triplet.id[i,1]])
      items[[i]] <- items[[i]][-triplet.id[i,1]]
    }
  }

  # recurse until all vectors are empty (NA)
  if(!prod(unlist(is.na(items)))) out <- append(list(out), 
                                                do.call("tripl", c(items), quote = F))
  else(out <- list(out))

  # return result
  return(out)
}

可以通过将输入向量作为参数传递来调用该函数。

# input vectors
a = c(3,5)
b = c(6,1,8,7)
c = c(4,2,9)

# find all the triplets using our function
y <- tripl(a,b,c) 

结果是一个列表,其中包含所有必要的信息,尽管是无序的。

print(y)
# [[1]]
# [1] 1 2 3
#
# [[2]]
# [1] 4 5 6
# 
# [[3]]
# [1]  7  9 NA
#
# [[4]]
# [1]  8 NA NA

可以使用sapply()

# put everything in order
sapply(y, function(x){x[order(x)]}) %>% t
#       [,1] [,2] [,3]
# [1,]    1    2    3
# [2,]    4    5    6
# [3,]    7    9   NA
# [4,]    8   NA   NA

问题是,每个向量只使用一个值来查找三元组。 因此它将找不到连续的三元组c(6,7,8),例如c(6,7,11)c(8,9,13)c(10,12,14)。 在这种情况下,它将返回 c(6,8,10)(见下文)。

a<-c(6,7,11)
b<-c(8,9,13)
c<-c(10,12,14)

y <- tripl(a,b,c)
sapply(y, function(x){x[order(x)]}) %>% t
#     [,1] [,2] [,3]
# [1,]    6    8   10
# [2,]    7    9   12
# [3,]   11   13   14

【讨论】:

    猜你喜欢
    • 2021-08-17
    • 1970-01-01
    • 2016-04-27
    • 2016-05-18
    • 2011-12-18
    • 2021-03-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多