检测二进制序列的第n项

时间:2015-10-30 18:56:25

标签: java algorithm

我有一个遵循特定逻辑的二进制序列 它以0

开头

第n项=第(n-1)项的序列+ 0 +逆(第(n-1)项)

例如:

0
0 + 0 + 1
001 + 0 + 011
0010011 + 0 + 0011011

在这里,我需要找出第k个序列的第n个项。

我的看法:

我已经编写了一个递归函数来计算第k个序列中的术语数

  public static long noOfElements(long elements){
     long answer;
     if(elements == 1)
        return 1;
     else
     answer = 1 + 2*noOfElements(elements-1);
     return answer;
}

经过分析,我发现序列遵循一定的模式,第k个序列可以分解为一半并且切换0和1的值我可以跟踪结果。

所以,我的函数在下面将给定的序列分解为[0,0,1]递归

public static long letsBegin(long reqd, long length){
    long mid = (length + 1)/2;
    if(length <= 3){
        return reqd;
    }else{
        if(reqd > mid){
            reqd = reqd - 2*(reqd-mid);
            switcher();                 //Switcher stores if the value is switched
            return letsBegin(reqd, mid);
        }else{
            return letsBegin(reqd, mid);
        }
    }
}

最后我在[0,0,1]中有索引1,2或3,我相应地输出了值。 这里的问题是

  1. 它因某些未知案例而失败(可能是我的逻辑错误)。
  2. 序列的数量可以达到50,使得元素的数量= 1125899906842623,因此输出值太长(> 2秒) 可能出了什么问题?我的逻辑是不正确的

2 个答案:

答案 0 :(得分:1)

Easily done with recursion, the number of elements in k-th sequence is 2^(k+1)-1:

static int foo(long n, int k) { //n-th element (indexed from 0) in k-th sequence
    long length = (2L << k) - 1; // computes 2^(k+1)-1
    if(n >= length) return -1; // prevent invalid inputs
    if(n == length/2) return 0; // middle point
    if(n < length/2) return foo(n, k-1); //left half
    return 1 - foo(length - n - 1, k-1); //right half
}

In the last recursive call, you both flip the array and the return value.

EDIT:

Be sure to use (2L << k) and not (2 << k) otherwise this will cause overflow and may lead to endless recursion.

答案 1 :(得分:0)

你错过了一个案例(当reqd == mid)并且调用递归函数时长度不正确(mid而不是mid-1)。完成这些修复后,函数如下所示:

public static long letsBegin(long reqd, long length){
    long mid = (length + 1)/2;
    if(length <= 3){
        return reqd;
    } else{
        if(reqd > mid){
            reqd = reqd - 2*(reqd-mid);
            switcher();     //Switcher stores if the value is switched
            return letsBegin(reqd, mid-1);
        } else if(reqd < mid) {
            return letsBegin(reqd, mid-1);
        } else {
            return 0;
        }
    }
}

此外,代码比必要的更复杂。请尝试使用以下重复关系:

T(n, k) = T(n, k-1)            if n < 2^{k-1}
        = 0                    if n = 2^{k-1}
        = 1 - T(2^k-n, k-1)    otherwise