【问题标题】:Java Multiple Array Recursion regardless of array size无论数组大小如何,Java 多数组递归
【发布时间】:2012-03-04 10:36:25
【问题描述】:

我有三个数组:

{}    
{a, b, c}
{d, e} 

我正在尝试将它们组合以获得以下数组:

{a, d}
{a, e}
{b, d}
{b, e}
{c, d} 
{c, e}

我遇到的问题是第一个空数组导致嵌套的 for 循环根本不运行 - 从逻辑上讲是有道理的。即:

 for (int i = 0; i < bL.size(); i++) {
        for (int j = 0; j < dL.size(); j++) {
            for (int k = 0; k < oL.size(); k++) {

我试图找到的是组合三个数组的最有效方法,无论它们的大小如何。大多数时候这三个都有元素,但在某些情况下可能会生成一个空集。

任何帮助表示赞赏。

编辑:为所有三个数组添加输出

输入 - {a,b} {光盘} {e,f}

输出 - {高手} {a,c,f} {a,d,e} {a,d,f} {b,c,e} {b,c,f}

编辑:只有第一个或第三个数组可能导致空集

【问题讨论】:

  • 为什么不递归地调用一个组合两个数组的方法,并在该方法中处理空数组的特殊情况?您甚至不必递归调用它,只需为前两个数组调用它,然后为当前组合结果和下一个数组调用它。
  • 假设第一个数组有元素 {f,g}。在这种情况下,答案应该是什么?
  • @GregS 我假设他想要一个笛卡尔积,尽管它的不同之处在于空数组/集合被有效地忽略了。
  • @Thomas 我可以看到该方法是如何工作的。这会被认为是实现笛卡尔积的常见做法吗?
  • @Josh 显式地生成潜在无限集合的笛卡尔积并不太常见,因为存在消耗大量内存的危险。通常,您还希望根据某些条件过滤您的结果,并且这两个操作合而为一。但是,如果内存消耗不是问题,并且您不能立即减小结果的大小,那就继续吧。

标签: java arrays recursion


【解决方案1】:

这是一个简单的递归方法,它以 2D ArrayList 的形式返回结果,而不是打印出来。

import java.util.ArrayList;

public class Program
{
    public static void main(String[] args)
    {
        String[][] x = { {}, {"a", "b", "c"}, {"d", "e"} };
        System.out.println(cartProd(x));
    }

    public static ArrayList< ArrayList<String> > cartProd(String[][] x)
    {
        return cartProd(x, new ArrayList<String>(), 0);
    }

    public static ArrayList< ArrayList<String> > cartProd(String[][] x, ArrayList<String> current, int index)
    {
        ArrayList< ArrayList<String> > result = new ArrayList< ArrayList<String> >();

        while (index < x.length && x[index].length == 0)
        {
            index++;
        }

        if (index == x.length)
        {
            result.add(new ArrayList<String>(current));
        }
        else
        {
            for (int i = 0; i < x[index].length; i++)
            {
                current.add(x[index][i]);
                result.addAll(cartProd(x, current, index + 1));
                current.remove(current.size() - 1);
            }
        }

        return result;
    }
}

【讨论】:

    【解决方案2】:

    假设您正在处理 int 值的数组,您可以执行以下操作:

    void printCombination(int[][] data, List<int> partial) {
        if (partial.size() == data.Length) {
            for (int i : partial) {
                if (i != -1) {
                    System.out.writeln(" " + i);
                }
            }
            return;
        }
        if (data[partial.size()].length == 0) {
            partial.add(-1);
            printCombination(data, partial);
            partial.remove(partial.size()-1);
            return;
        }
        for (int i = 0 ; i != data[partial.size()].length; i++) {
            partial.add(data[partial.size()][i]);
            printCombination(data, partial);
            partial.remove(partial.size()-1);
        }
    }
    

    初始调用如下所示:

    List<int> partial = new ArrayList();
    int[][] data = new int[][] {new int[] {}, new int[] {1,2}, new int[] {3, 4, 5}};
    printCombination(data, partial);
    

    【讨论】:

    • “p”和“str”从何而来?试图遵循逻辑。我实际上正在使用 Character[]。
    • 您的代码中似乎有一些错误: 1. 为什么要检查列表的长度与二维数组的长度?我假设您希望该条件为partial.size() == data[p].Length,不是吗? 2. 我假设你错过了data 的外循环。你使用了变量p,但没有声明它。
    • @Josh 哎呀,我从今天早些时候给出的另一个答案中提取了代码,忘记重命名变量。我编辑了代码来修复这些问题。
    • @Thomas 我编辑了代码。第一个检查实际上是正确的:我正在检查partial 的长度与列表的外部尺寸。当它们相等时,partial 实际上是“完整的”。 data 的外层循环是递归调用本身,因此不需要。
    • 在尝试访问空数组时,partial.add(data[partial.size()][i]); 行不会产生 ArrayIndexOutOfBounds 异常吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-28
    • 2017-11-28
    • 1970-01-01
    相关资源
    最近更新 更多