【问题标题】:How to find permutations for String arrays excluding own array?如何找到字符串数组的排列,不包括自己的数组?
【发布时间】:2017-12-26 15:57:25
【问题描述】:

我有以下一堆数组:

public class ArrayPermutationExample {
    private static final String PREFIX = "ignore(FAILURE) { build(\"load\", ";
    public static final String ENDING = ")}";
    private static String[] arr_1 = new String[] {
        "111",
        "222",
        "333"};

    private static String[] arr_2 = new String[]{
        "aaa",
        "bbb",
        "ccc"};

    private static String[] arr_3 = new String[] {
        "***",
        "&&&",
        "$$$"};

我需要找到与其他数组的排列,不包括原生数组。
输出应如下所示:

111aaa
111bbb
111ccc
111***
111&&&
111$$$

222aaa
222bbb
222ccc
...

333aaa
333bbb
333ccc
...

最后,对于所有这些排列,应添加prefixending

prefix排列字符串endings

最后我们应该有这样的东西:

忽略(失败){构建(“加载”,111aaa)}

我完全坚持这个任务的解决方案:

private static void processArrays(String[] ... arrays) {
    ArrayList<String> result = new ArrayList<>();
    for (String[] array : arrays) {
        String[] currentArray = array;
        for (String line : currentArray) {
            // exclude all lines from current array & make concatenation with every line from others
        }
    }
}

如何解决这个问题?

更新:

最后我想补充一点,我们需要有一个没有任何重复的独特列表。甚至下面的例子也会互相重复:

111aaa***
***111aaa

我相信这个任务应该有一个Java 8风格的解决方案。

【问题讨论】:

  • 我可以知道投反对票的原因吗?
  • 乍一看你的例子看起来很复杂,你能提供一个更小的例子吗?将更容易阅读并全面了解您的问题。
  • @Zabuza 我更新了问题
  • 现在好多了,谢谢 :) 仅使用现有的 permutation builder (SO 有多种解决方案)并稍微修改一下,问题在哪里?我认为这也有助于理解如何解决这个问题,首先看看你会如何做。
  • @Zabuza 我想知道如何使用 Java 8 风格来解决这个问题。

标签: java arrays algorithm concatenation permutation


【解决方案1】:

我读它的方式:第一个数组 arr_1 被添加到接下来的 3 个数组中。 我认为前缀是 "ignore(FAILURE) { build("load", " 结尾是 "}}"

String prefix = "ignore(FAILURE) { build(\"load\", ";
String ending = "}}";
for (String first: arr_1) {
    for (String second: arr_2) {
       System.out.println( prefix + first + second + ending);
    }
    for (String second: arr_3) {
       System.out.println( prefix + first + second + ending);
    }
    for (String second: arr_4) {
       System.out.println( prefix + first + second + ending);
    }
}

【讨论】:

  • 正确的方向!更重要的是,在第一个数组之后 -> 应该以相同的方式处理第二个数组 -> 在第三个数组之后 -> 最后一个。但是,我想找到如何为这种组合而不是为每个数组创建程序样式的一些智能方法。
【解决方案2】:

我认为这可能是一种组合,因为您实际上并不关心获取所有排序(除了按照数组参数的顺序指定的顺序打印),但无论如何,这是我编写的代码。我使用堆栈来存储未完成的数组。将每个数组的任何给定点的每种可能性推入堆栈,并推入任何已完成数组的结果。

public static List<String> getCombinations(String prefix, String ending, String[]... arrays) {
    List<String> results = new ArrayList<>();
    Stack<String[]> combinations = new Stack<>();
    combinations.add(new String[arrays.length]);

    while (!combinations.isEmpty()) {
        String[] currentArray = combinations.pop();

        if (currentArray[arrays.length - 1] == null) {
            for (int i = 0; i < arrays.length; i++) {
                if (currentArray[i] == null) {
                    for (int j = 0; j < arrays[i].length; j++) {
                        String[] newArray = currentArray.clone();
                        newArray[i] = arrays[i][j];
                        combinations.add(newArray);
                    }

                    break;
                }

            }
        } else {
            StringBuilder stringBuilder = new StringBuilder(prefix);
            for (String string : currentArray) {
                stringBuilder.append(string);
            }
            stringBuilder.append(ending);
            results.add(stringBuilder.toString());
        }
    }

    return results;
}

您只需要遍历返回的列表即可打印出所有字符串。

作为补充说明,此方法可以递归编写,但我通常喜欢使用堆栈而不是尽可能使用递归,因为递归有时会很慢。

【讨论】:

  • 您的return list 包含重复项。一个置换字符串重复 6 次。我们应该有不同的结果。
  • 您可以通过使用 HashSet 而不是 ArrayList Set&lt;String&gt; results = new HashSet&lt;&gt;(); 来摆脱这种情况。最后,您将获得不同的结果,没有任何重复。
  • 我已经修改了我的答案,但我没有使用HashSet。对我来说似乎有点hacky。我宁愿让它从一开始就不会产生重复。
猜你喜欢
  • 2020-09-19
  • 1970-01-01
  • 1970-01-01
  • 2022-05-27
  • 2020-11-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多