【问题标题】:Creating multiple nested loops to generate two numbers that move through the length of a Array创建多个嵌套循环以生成两个穿过数组长度的数字
【发布时间】:2015-01-01 19:56:28
【问题描述】:

正如标题所述,我一直在考虑创建多个旨在实现一个目的的嵌套循环。将两个生成的随机数在 0-9 之间移动到数组的每个可能位置。

例如,App 生成第一个数字 (fNum) 1 和第二个数字 (sNum) 6。然后它将这些数字移动到包含 ABC 的数组中。但是 firstNum 和 secondNum 还需要尝试所有可能的组合,因此每个循环都需要不同。

-1ABC6
-A1BC6
-AB1C6
-ABC16
-ABC61
-AB6C1
-A6BC1
-6ABC1
-A6B1C
-A61BC
-A16BC
-A1B6C
-A1BC6

等等……

我相信最好的方法是创建一个生成计数器的方法,它会增加我可以调用的数字。

    private int getNextNumber(int num) {

    if (num == 0) {
        return num;
    } else {
        num++;
    }

    if (num < 10) {
        return num;
    } else {
        return -1;
    }

}

然后我将需要多个嵌套循环...我决定进行多个循环,这些循环将无限循环。

            while (j < maxlen) {
            //J = 0 and maxlen = length of text so in this case 3 as it is ABC
            //Add two numbers and check against answer

            while (fNum != -1 || sNum != -1) {

                //incrememnt numbers
                fNum = getNextNumber(fNum);
                System.out.println(fNum);

                sNum = getNextNumber(sNum);
                System.out.println(fNum);

            }

            String textIni = "ABC";
            int lenOfText = textIni.length();
            char[] split = textIni.toCharArray();

            for (int i = 0; i < lenOfText; i++) {
                //here it will look at the length of the Text and
                //try the possible positions it could be at....
                //maybe wiser to do a longer loop but I am not too sure
            }
        }

【问题讨论】:

  • 您应该研究递归广告,这看起来可以使用递归解决!
  • 你必须存储这些排列吗?如果是这种情况,递归解决方案将是更好的选择。如果您需要对每个排列进行处理而不存储它,请坚持迭代解决方案
  • 问题是什么?
  • 递归,我已经掌握了这个术语,但是在 Java 方面我仍然是一个菜鸟,好的,谢谢!我会尝试通过使用解决这个问题并反馈。
  • @Tom 嗨,对不起,我刚刚注意到我没有把它放进去的问题,是我如何才能真正通过数组并检查所有可能性,我现在正在尝试学习递归所以我可能会想出一个解决方案。

标签: java arrays loops while-loop nested


【解决方案1】:

由于您不需要存储所有可能的组合,我们将通过迭代解决方案仅使用 O(n) 存储来节省一些内存。我建议你一个基本的实现,但不要期望在大型数组上使用它,因为它具有O(n³) 复杂性。

public static void generateCombinationsIterative(List<Integer> original, int fnum, int snum) {
    int size = original.size();
    for (int i=0 ; i<=size ; i++) {
        List<Integer> tmp = new ArrayList<>(original);
        tmp.add(i,fnum);
        for (int j=0 ; j<=size + 1 ; j++) {
            tmp.add(j,snum);
            System.out.print(tmp + (i == size && j == size + 1 ? "" : ", "));
            tmp.remove(j);
        }
    }
}

对于您的文化,这里有一个递归解决方案的示例,它会占用大量内存,因此如果您不需要生成结果列表,请不要使用它。不过,这是一种更通用的解决方案,可以处理要插入的任意数量的元素。

public static List<List<Integer>> generateCombinations(List<Integer> original, Deque<Integer> toAdd) {
    if (toAdd.isEmpty()) {
        List<List<Integer>> res = new ArrayList<>();
        res.add(original);
        return res;
    }

    int element = toAdd.pop();
    List<List<Integer>> res = new LinkedList<>();
    for (int i=0 ; i<=original.size() ; i++) 
        // you must make a copy of toAdd, otherwise each recursive call will perform
        // a pop() on it and the result will be wrong
        res.addAll(generateCombinations(insertAt(original,element,i),new LinkedList<>(toAdd)));
    return res;
}

// a helper function for a clear code
public static List<Integer> insertAt(List<Integer> input, int element, int index) {
    List<Integer> result = new ArrayList<>(input);
    result.add(index,element);
    return result;
}

请注意,我没有使用任何数组来从动态数据结构中受益,但是您可以像这样调用方法:

int[] arr  = { 1,2,3 };
int   fnum = 4, snum = 5;
generateCombinationsIterative(Arrays.asList(arr),fnum,snum);
generateCombinations(Arrays.asList(arr),new LinkedList<>(Arrays.asList(fnum,snum));

请注意,这两种方法都以相同的顺序生成组合。

【讨论】:

  • System.out.print(tmp + (i == size && j == size + 1 ? "" : ", "); is missing a ) 某处但无法弄清楚!我也可以使用以下伪代码 - int[] arr = (a string to array)?
  • @zhiar 修复了缺少的括号,谢谢。我给了你一个使用整数的代码,但你可以用字符替换它(int 变成 char 和 Integer 变成 Character)。
  • 再次感谢,但是我怀疑当我用 char 替换 int 时,它给了我一个错误,因为 fNum 和 sNum 都是 int,当您将它们添加到数组时,它们无法转换为字符。这个问题有什么解决办法吗?我是否还需要将这两个数字转换为字符以便以后能够将它们添加到数组中?
  • 这不是很优雅,但你可以使用String.valueOf(myInt).charAt(0)将一个int(0到9之间)转换为char
  • 我保证最后一个问题 :) 你建议我使用 generateCombinationsIterative(Arrays.asList(arr),fnum,snum);调用该方法但是我实际上不能调用它,因为由于将列表更改为字符,它不再是类型而是字符。错误:不兼容的类型:推理变量 T 具有不兼容的边界等式约束:字符下限:char[] 其中 T 是类型变量:T 扩展方法中声明的对象 asList(T...)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-11-05
  • 1970-01-01
  • 1970-01-01
  • 2022-10-01
  • 2018-04-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多