【问题标题】:Recursion to get all variants sum in array递归以获取数组中的所有变体总和
【发布时间】:2014-12-28 07:47:24
【问题描述】:

我正在尝试编写一个递归方法,该方法允许我对数组中所有可能的整数变体求和。

例如。对于具有以下值的数组 [1, 2, 3, 4]

结果:[1, 2], [1, 3], [1, 4], [2, 1], [2, 3], [2, 4], [3, 1], [3, 2], [3, 4], [4, 1], [4, 2], [4, 3], [1, 2, 3], [1, 2, 4], [2, 1, 3] , [2, 1, 4] 等等等等。

我对递归完全陌生。我的理解是将问题分解为一个较小的问题。但是对于这种情况,我似乎看不到它。有人可以帮我吗?

编辑:

class Stick {

    public int sum(ArrayList<Integer> array) { 
        int total = 0;
        for(int i = 0; i < array.size(); i++) {
            total += array.get(i);
        }

        return total;
    }

    public void permute(ArrayList<Integer> in, ArrayList<Integer> out) {
        if(out.size() > 0) { print(out); System.out.println(sum(out)); }

        for(int i = 0; i < in.size(); i++) { 
            int item = in.get(i);
            in.remove(i);
            out.add(item);
            permute(in , out);
        }
    }

    public void print(ArrayList<Integer> integer) {
        System.out.print("[");
        for(int i = 0; i < integer.size(); i++) {
            System.out.print(integer.get(i) + ", ");
        }
        System.out.print("]");
    }
    public static void main(String[] args) {
        ArrayList<Integer> in = new ArrayList<Integer>();
        ArrayList<Integer> out = new ArrayList<Integer>();
        in.add(1); in.add(2); in.add(3); in.add(4);

        Stick stick = new Stick();
        stick.permute(in, out);
    }
}

【问题讨论】:

  • 你能在这里更具体一点吗?当您说“所有可能的变体”时,您是什么意思?我很确定您的意思是从 1 到输入数组长度的所有长度排列,但我不是 100%。

标签: java arrays performance algorithm recursion


【解决方案1】:

这是一种有效的递归方法:

  1. 编写一个递归例程permute,它接受两个数组:arrayInarrayOutarrayIn 包含尚未使用的值,arrayOut 包含部分形成的结果。

  2. 将使用包含完整值数组的arrayIn 调用程序,而arrayOut 将以空开始。

  3. 在每一步,您将通过从arrayIn 获取值来构建arrayOut,并将它们附加到数组输出。这是您正在寻找的较小的案例。 arrayIn 在每个步骤中都会变小,直到您到达arrayIn 为空的基本情况

    这是 Ruby 中的解决方案。如果您不熟悉 Ruby 语法,我已尝试使其可读:

    # function to sum up the values of an array
    def sum(array)
        total = 0
        for elem in array
            total += elem
        end
    
        # return the total
        total
    end
    
    def permute(arrayIn, arrayOut)
        if arrayOut.count > 0
            # print out the array
            puts arrayOut.inspect
    
            # print out the total
            puts "total is #{sum(arrayOut)}"
        end
    
        # For each element in turn in arrayIn...
        for elem in arrayIn
            # remove element from arrayIn, add it to arrayOut, and recurse
            permute(arrayIn - [elem], arrayOut + [elem])
        end
    end
    

当我们使用数组 [1,2,3] 运行它时:

    permute([1,2,3], [])

输出是:

[1]
total is 1
[1, 2]
total is 3
[1, 2, 3]
total is 6
[1, 3]
total is 4
[1, 3, 2]
total is 6
[2]
total is 2
[2, 1]
total is 3
[2, 1, 3]
total is 6
[2, 3]
total is 5
[2, 3, 1]
total is 6
[3]
total is 3
[3, 1]
total is 4
[3, 1, 2]
total is 6
[3, 2]
total is 5
[3, 2, 1]
total is 6

【讨论】:

  • 感谢您的解决方案。这似乎是我试图实现的..但是,当我用java编写它时..它似乎停止在迭代的第一级[1],[1,2],[1,2,3],[ 1、2、3、4]。你能帮我看看吗?
  • 在您的置换例程中,您需要在每次从新副本中删除项目并调用 permute 之前制作 inout 的新副本。
【解决方案2】:
static ArrayList<int[]> permutations(int[] a) {
    ArrayList<int[]> ret = new ArrayList<int[]>();
    permutation(a, 0, ret);
    return ret;
}

public static void permutation(int[] arr, int pos, ArrayList<int[]> list) {
    if (arr.length - pos == 1) {
        list.add(arr.clone());
    } else {
        for (int i = pos; i < arr.length; i++) {
            swap(arr, pos, i);
            permutation(arr, pos + 1, list);
            swap(arr, pos, i);
        }
    }
}

public static void swap(int[] arr, int pos1, int pos2) {
    int h = arr[pos1];
    arr[pos1] = arr[pos2];
    arr[pos2] = h;
}

public static void main(String[] args) {
    int[] x = {1, 2, 3, 4};
    for(int i[] : IntRecursion.permutations(x)) {
        System.out.println(Arrays.toString(i));
    }

}

我想这就是你要找的。​​p>

【讨论】:

    猜你喜欢
    • 2019-09-26
    • 1970-01-01
    • 2021-07-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多