如何管理递归函数?

时间:2017-02-18 20:31:27

标签: java recursion

我需要编写一个获取4个参数的递归函数。

第一个是阵列。第二个 - 左指数,第三个是右指数," K"指数。 " K" index是数组中的单元格,lrft索引指向开头,右指数指向结尾。

数组可能包含零和1等数字。该方法返回包含单元格k的序列的最大长度。

这里是我需要获得的结果示例:

public static void main(String[] args) {
   int[] A = {1,1,1,0,1,1,0,1,1,1,1,1,0,1,1};
   System.out.println(floodOnes(A,0, A.length-1, 9)); // 5 output
   System.out.println(floodOnes(A,0, A.length-1, 3)); // 0 output
   System.out.println(floodOnes(A,0, A.length-1, 0)); // 3 output
   System.out.println(floodOnes(A,0, A.length-1, 14)); // 2 output
}

public static int floodOnes(int [] A,int left, int right, int k){
    //some logic
}

这是我的实施:

public class Program {
    public static void main(String[] args) {
        int[] A = {1,1,1,0,1,1,0,1,1,1,1,1,0,1,1};
        System.out.println(floodOnes(A,0,A.length-1, 9));
    }

    public static int floodOnes(int [] A,int left, int right, int k){           
        if (left != k) left+=1;
        if (right != k) right-=1;   

        if (left == k  && right == k) return A[k]; //condition when the recursive call stops 

        int res = floodOnes(A, left,  right,  k);

        if (A[left] == 1 && A[right] == 1) 
            return res = A[left] + A[right];  //count ones      

        else  return res;   
    }   
}

但我的解决方案无法正常工作。

在这行中:

if (A[left] == 1 && A[right] == 1) 
      return res = A[left] + A[right];  //count ones  

如果其中一个条件没有执行一次,则以下返回不应该为结果变量添加一个条件。

而且我不知道该怎么做。

3 个答案:

答案 0 :(得分:1)

您可以将此问题分解为2个功能。 第一个将计算左侧的元素,后者位于右侧。两者都使用递归。

public static int floodOnes(int[] A, int left, int right, int k) {
    return checkLeft(A, left, k-1, A[k]) + 1 + checkRight(A, right, k+1, A[k]);
}

public static int checkLeft(int[] A, int leftBoundary, int k, int number) {
    if (k < 0 || A[k] != number || k < leftBoundary)
        return 0;
    return 1 + checkLeft(A, leftBoundary, k-1, number);
}

public static int checkRight(int[] A, int rightBoundary, int k, int number) {
    if(k >= A.length || A[k] != number || k > rightBoundary)
        return 0;
    return 1 + checkRight(A, rightBoundary, k+1, number);
}

我假设:
0 <= left <= k <= right < A.length;
与你的例子不同,单独的数字应该被计为1(长度为1的序列)。如果您希望将其计为0,请在if(A[k] != 1) return 0;方法中添加floodOnes或类似条件。

因此:

System.out.println(floodOnes(A, 0, A.length - 1, 9));  // prints 5 
System.out.println(floodOnes(A, 0, A.length - 1, 3));  // prints 1 
System.out.println(floodOnes(A, 0, A.length - 1, 0));  // prints 3 
System.out.println(floodOnes(A, 0, A.length - 1, 14)); // prints 2 

除了leftright参数可用于某些输入异常 (例如k > A.length)。

答案 1 :(得分:1)

我证明我的评论错了。这是一个递归方法,问题中提到的4个参数确实解决了这个问题。

public static int floodOnes(int[] a, int left, int right, int k) {
    if (0 <= left && left <= k && k <= right && right < a.length) {
        // is there a 0 between left (inclusive) and k (exclusive)?
        int i = left;
        while (i < k && a[i] == 1) {
            i++;
        }
        if (i < k) {
            assert a[i] == 0;
            return floodOnes(a, i + 1, right, k);
        }
        // is there a 0 between k (exclusive) and right (inclusive)?
        i = right;
        while (i > k && a[i] == 1) {
            i--;
        }
        if (i > k) {
            assert a[i] == 0;
            return floodOnes(a, left, i - 1, k);
        }
        // no zero found, a[k] not checked, though
        if (a[k] == 0) {
            return 0;
        } else {
            return right - left + 1;
        }
    } else {
        throw new IllegalArgumentException("Expected " + left + " <= " + k + " <= " + right + " < " + a.length);
    }
}

使用此方法,问题中的第一个main方法打印出预期的:

5
0
3
2

我真的没有看到以这种方式解决问题的重点,所以我很难确定这是有意的。我更喜欢非递归解决方案,或者只是需要以某种方式递归,然后是Grzegorz Górkiewicz’ answer中的解决方案。

答案 2 :(得分:0)

因为您正在寻找 - the maximum length of a sequence of ones that contain the cell k。实现这一目标的简单而简洁的代码如下:

public static void main(String[] args) {
    int[] A = {1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1};
    System.out.println(floodOnes(A, 0, A.length - 1, 9));  // prints 5 
    System.out.println(floodOnes(A, 0, A.length - 1, 3));  // prints 0 
    System.out.println(floodOnes(A, 0, A.length - 1, 0));  // prints 3 
    System.out.println(floodOnes(A, 0, A.length - 1, 14)); // prints 2 
}

public static int checkLeft(int[] A, int k) {
    return (k < 0 || A[k] != 1) ? 0 : 1 + checkLeft(A, k - 1);
}

public static int checkRight(int[] A, int k) {
    return (k > (A.length - 1) || A[k] != 1) ? 0 : 1 + checkRight(A, k + 1);
}

public static int floodOnes(int[] A, int left, int right, int k) {
    return (A[k] != 1) ? 0 : checkLeft(A, k - 1) + 1 + checkRight(A, k + 1);
}

它输出所需的结果。

5
0
3
2