寻找`n1` TRUEs裹在两个`n2` FALSEs之间,n3` TRUEs等之间的'包裹在整个事情 [英] Finding `n1` TRUEs wrapped in between two `n2` FALSEs, the whole thing wrapped in between `n3` TRUEs, etc

查看:137
本文介绍了寻找`n1` TRUEs裹在两个`n2` FALSEs之间,n3` TRUEs等之间的'包裹在整个事情的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

从TRUEs和falses的顺序,我想使返回TRUE是否有系列的至少 N1 TRUEs某处序列中的一个函数。下面是该函数:

From a sequence of TRUEs and falses, I wanted to make a function that returns TRUE whether there is a series of at least n1 TRUEs somewhere in the sequence. Here is that function:

fun_1 = function(TFvec, n1){
    nbT = 0
    solution = -1
    for (i in 1:length(x)){
            if (x[i]){
            nbT = nbT + 1
               if (nbT == n1){
                return(T)
                break
               }
            } else {
                nbT = 0
            }
        }
        return (F) 
}

测试:

x = c(T,F,T,T,F,F,T,T,T,F,F,T,F,F)
fun_1(x,3) # TRUE
fun_1(x,4) # FALSE

然后,我需要返回TRUE如果在给定列表布尔向量,还有一系列至少 N1 TRUEs由至少两个系列的包(一个的函数:在的每边)N2 falses。这里的功能:

Then, I needed a function that returns TRUE if in a given list boolean vector, there is a series of at least n1 TRUEs wrapped by at least two series (one on each side) of n2 falses. Here the function:

fun_2 = function(TFvec, n1, n2){
    if (n2 == 0){
        fun_1(TFvec, n2)        
    }
    nbFB = 0
    nbFA = 0
    nbT = 0
    solution = -1
    last = F
    for (i in 1:length(TFvec)){
        if(TFvec[i]){           
            nbT = nbT + 1
            if (nbT == n1 & nbFB >= n2){
                solution = i-n1+1
            }
            last = T
        } else {
            if (last){
                nbFB = 0
                nbFA = 0        
            }
            nbFB = nbFB + 1
            nbFA = nbFA + 1
            nbT = 0
            if (nbFA == n2 & solution!=-1){
                return(T)
            }
            last = F
        }
    }
    return(F)
}

有可能不是一个非常有效的功能,但!我没有测试它的100倍,但它看起来像它工作正常!

It is maybe not a very efficient function though! And I haven't tested it 100 times but it looks like it works fine!

测试:

x = c(T,F,T,T,F,F,T,T,T,F,F,T,F,F)
fun_2(x, 3, 2) # TRUE
fun_2(x, 3, 3) # FALSE

现在,不管你信不信,我想一个函数( fun_3 )如果布尔向量有一个(至少)系列返回TRUE至少 N1 TRUEs包裹在中间(至少)两个(每边一个)系列的N2 falses哪里整个事情(三个系列)之间的包装在(至少)两个(每边一个)系列的N3 TRUEs。正如恐怕要进一步把这个问题,我问这里寻求帮助创建一个函数 fun_n 在我们进入两个参数 TFvec list_n ,其中 list_n 列表ñ任意长度的。

Now, believe it or not, I'd like to make a function (fun_3) that returns TRUE if in the boolean vector there is a (at least) series of at least n1 TRUEs wrapped in between (at least) two (one on each side) series of n2 falses where the whole thing (the three series) are wrapped in between (at least) two (one on each side) series of n3 TRUEs. And as I am afraid to have to bring this problem even further, I am asking here for help to create a function fun_n in which we enter two arguments TFvec and list_n where list_n is a list of n of any length.

你能帮我创造功能 fun_n

Can you help me to create the function fun_n?

推荐答案

为了方便起见,记录阈值的数量的长度

For convenience, record the length of the number of thresholds

n = length(list_n)

重新present真假向量作为运行长度编码,记住每次运行的方便长度

Represent the vector of TRUE and FALSE as a run-length encoding, remembering the length of each run for convenience

r = rle(TFvec); l = r$length

查找可能起始位置

Find possible starting locations

idx = which(l >= list_n[1] & r$value)

确认的起始位置嵌入足以满足所有测试

Make sure the starting locations are embedded enough to satisfy all tests

idx = idx[idx > n - 1 & idx + n - 1 <= length(l)]

然后检查远程连续运行的长度与病情相符,只保留那些起点是

Then check that lengths of successively remote runs are consistent with the condition, keeping only those starting points that are

for (i in seq_len(n - 1)) {
    if (length(idx) == 0)
        break     # no solution
    thresh = list_n[i + 1]
    test = (l[idx + i] >= thresh) & (l[idx - i] >= thresh)
    idx = idx[test]
}

如果有在 idx的留下的任何值,则这些索引到满足条件的RLE;起点(S)的初始向量是 cumsum(1)实施IDX - 1] + 1

If there are any values left in idx, then these are the indexes into the rle satisfying the condition; the starting point(s) in the initial vector are cumsum(l)[idx - 1] + 1.

组合:

runfun = function(TFvec, list_n) {
    ## setup
    n = length(list_n)
    r = rle(TFvec); l = r$length

    ## initial condition
    idx = which(l >= list_n[1] & r$value)
    idx = idx[idx > n - 1 & idx + n - 1 <= length(l)]

    ## adjacent conditions
    for (i in seq_len(n - 1)) {
        if (length(idx) == 0)
            break     # no solution
        thresh = list_n[i + 1]
        test = (l[idx + i] >= thresh) & (l[idx - i] >= thresh)
        idx = idx[test]
    }

    ## starts = cumsum(l)[idx - 1] + 1
    ## any luck?
    length(idx) != 0
}

这是速度快,并允许运行> =门槛,规定中的问题;例如:

This is fast and allows for runs >= the threshold, as stipulated in the question; for example

x = sample(c(TRUE, FALSE), 1000000, TRUE)
system.time(runfun(x, rep(2, 5)))

在第二小于1/5完成

completes in less than 1/5th of a second.

一个有趣的泛化允许灵活的条件,例如,刚好运行 list_n ,如rollapply解决方案

A fun generalization allows for flexible condition, e.g., runs of exactly list_n, as in the rollapply solution

runfun = function(TFvec, list_n, cond=`>=`) {
    ## setup
    n = length(list_n)
    r = rle(TFvec); l = r$length

    ## initial condition
    idx = which(cond(l, list_n[1]) & r$value)
    idx = idx[idx > n - 1 & idx + n - 1 <= length(l)]

    ## adjacent conditions
    for (i in seq_len(n - 1)) {
        if (length(idx) == 0)
            break     # no solution
        thresh = list_n[i + 1]
        test = cond(l[idx + i], thresh) & cond(l[idx - i], thresh)
        idx = idx[test]
    }

    ## starts = cumsum(l)[idx - 1] + 1
    ## any luck?
    length(idx) != 0
}

这篇关于寻找`n1` TRUEs裹在两个`n2` FALSEs之间,n3` TRUEs等之间的'包裹在整个事情的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆