在进行递归时无法更改变量

时间:2015-05-11 17:44:40

标签: java variables recursion

public static void main(String[] args) {
    int[] a = { 1, 2, 3, 4, 5 };
    int[] b = new int[5];
    rekursiq(a, b, 0, 0, 1);
}

static void rekursiq(int[] a, int[] b, int index, int start, int check) {
    if (index == b.length){
        System.out.println(java.util.Arrays.toString(b));
    } else {
        for (int i = start; i < a.length; i++) {
            b[index] = a[i];
            rekursiq(a, b, index + 1, i + 1, check + 1);
        }
    }
}

现在我的问题是:我不想在递归底部b.length放置int check,而是让每次去check +1一些东西。 while (check < b.length)去if语句,否则返回;但我似乎无法正确地增加价值,2)正确地做出这一点。我不知道为什么。

我认为我最好的尝试是

static void rekursiq(int[] a, int[] b, int index, int start, int check) {
    if (check > b.length) {
        return;
    } else {
        if (index == check) {
            System.out.println(java.util.Arrays.toString(b));
        } else {
            for (int i = start; i < a.length; i++) {
                b[index] = a[i];
                rekursiq(a, b, index + 1, i + 1, check + 1);
            }
        }
    }
}

但它不起作用,我希望你们中的一些人可以告诉我为什么以及如何解决它。

2 个答案:

答案 0 :(得分:2)

递归调用方法时,check的值确实会增加。但是,您遇到的问题与check无关。

问题

让我首先重复已经简要提到的abhishrp:在这种特殊情况下,你想要使用一个循环迭代数组中的所有元素,或递归,但不要在你的内部使用循环递归方法。原因如下:在递归的每个步骤中,您只查看一个元素:位置index处的元素。

解决方案

那么,你会如何递归复制一个数组呢?我们假设您有一个源数组(在您的代码a中)和一个空的目标数组(在您的代码b中)。现在,我们知道如何复制数组的单个元素,即destination[index] = source[index],我们可以想象将数组复制为复制第一个元素,然后从第二个元素开始复制子数组元件。请注意,知道如何复制数组中的单个元素意味着知道如何复制仅包含一个元素的数组。

这导致我们进行以下递归,我们将在不久之后转向代码:

  • 如果指定的索引取消引用数组中最后一个元素,则复制最后一个元素。
  • 否则,复制当前索引处的元素,并从下一个索引处开始复制子数组。

或用Java表达:

static void copyValuesFromSourceToDestinationStartingAtIndex(int[] source, int[] destination, int index) {
    if (isIndexOfLastElementInArray(index, destination)) {
        destination[index] = source[index];
    } else {
        destination[index] = source[index];
        copyValuesFromSourceToDestinationStartingAtIndex(source, destination, index + 1);
    }
}

static boolean isIndexOfLastElementInArray(int index, int[] array){
    return index == array.length - 1;
}

请注意,您的代码中有太多参数:参数check实际上只是index,因为您要检查是否索引仍然在数组的边界内。我真的不知道你打算用变量start做什么 - 看起来好像你因为循环而在那里感到困惑。

旁注

此外,上述代码中true - 语句的if - 分支为什么会复制最后一个元素而不是在索引超出范围时不返回任何内容的小理由码。像你一样这样做是完全合理的。 “我们很容易知道如何复制空数组”的论点似乎并不像“知道如何复制单个元素意味着知道如何复制由单个元素组成的数组”一样自然。但我鼓励你将代码调整为“复制一个空数组”作为基本情况,因为它删除了重复,更重要的是,允许你复制空数组(上面的实现会失败)。

代码

我还尝试在迭代和递归方法之间进行比较:

public static void main(String[] args) {
    int[] a = {1, 2, 3, 4, 5};
    int[] copyOfAUsingIteration = copyArrayUsingIteration(a);
    int[] copyOfAUsingRecursion = copyArrayUsingRecursion(a);
    assert(Arrays.equals(copyOfAUsingIteration, copyOfAUsingRecursion));
    assert(copyOfAUsingIteration != a);
    assert(copyOfAUsingRecursion != a); 
    System.out.println(java.util.Arrays.toString(copyOfAUsingIteration));
    System.out.println(java.util.Arrays.toString(copyOfAUsingRecursion));
}

static int[] copyArrayUsingIteration(int[] arrayToCopy) {
    int[] result = new int[arrayToCopy.length];
    for(int index = 0; index < result.length; index++){
        result[index] = arrayToCopy[index];
    }
    return result;
}

static int[] copyArrayUsingRecursion(int[] arrayToCopy){
    if (arrayToCopy.length == 0){
        return new int[0];
    } else {
        int[] result = new int[arrayToCopy.length];
        copyValuesFromSourceToDestinationStartingAtIndex(arrayToCopy, result, 0);
        return result;
    }
}

static void copyValuesFromSourceToDestinationStartingAtIndex(int[] source, int[] destination, int index) {
    if (isIndexOfLastElementInArray(index, destination)) {
        destination[index] = source[index];
    } else {
        destination[index] = source[index];
        copyValuesFromSourceToDestinationStartingAtIndex(source, destination, index + 1);
    }
}

static boolean isIndexOfLastElementInArray(int index, int[] array){
    return index == array.length - 1;
}

答案 1 :(得分:0)

要将一个数组复制到另一个数组,可以使用迭代或递归。没有必要同时做到这两点。我的意思是rekursiq方法中不需要for循环。