【问题标题】:Performance: JAVA permutation性能:JAVA排列
【发布时间】:2017-06-24 10:06:25
【问题描述】:

所以,我有这段代码来生成单词的排列,并将其存储到 HashSet 中,以便以后与字典进行比较。 但是当输入的单词有 10 个或更多字母时,排列过程变得异常缓慢。除了使用置换算法,还有什么方法可以提高这个过程的性能吗?

/**
 * Returns a HashSet of the string permutation.
 *
 * @param prefix an empty string.
 * @param str the string to create perm.
 * @return permutations a HashSet of the permutation.
 */
private static HashSet<String> permutation(String prefix, String str) {
    HashSet<String> permutations = new HashSet<String>();
    int n = str.length();
    if (n == 0) {
        permutations.add(prefix);
    } else {
        for (int i = 0; i < n; i++) {
            permutations.addAll(permutation(prefix + str.charAt(i), str.substring(0, i) + str.substring(i + 1, n)));
        }
    }
    return permutations;
}

【问题讨论】:

  • 指定一个与HashSet 中预期条目数相匹配的初始容量,这样它就不必一直扩展。
  • 算法的复杂度是 O(n!)。这可能是最糟糕的复杂性。 10 步需要 3628800 步
  • @Henrik 好吧,问题是我不知道预期的数字,它可能是 1000000 或 100000000,具体取决于输入字符串的长度。我不确定是否使用 HashSet 是最好的选择。
  • @TianchengXu:嗯,当然可以根据字符串的长度来计算。无论如何,只是一个近似值可能会减少运行时间。如果地图包含大量条目,则调整地图大小以容纳比预期更多的条目可能会非常昂贵。
  • @VladBochenin,它的意思是生成输入字符串的每一个组合,然后检查哪个是英文单词。所以...我想最好的方法是使用某种算法来消除无用的组合。

标签: java string performance permutation hashset


【解决方案1】:

简短的回答: 没有比 O(n!) 更好的排列复杂度了

O(n!) 是我能想象到的最糟糕的时间复杂度。您找不到更有效的方法来处理排列。如需更多信息,请参阅:

Stackoverflow-Wiki

Big-O


长答案:

您可以通过使用 Javas StringBuffer-Class 来改进您的代码(而不是您的算法)以获得更快的结果。

public static HashSet<StringBuffer> permutationNew(StringBuffer sb_prefix, StringBuffer sb_str) {
    HashSet<StringBuffer> permutations = new HashSet<>();
    int n = sb_str.length();
    if (n == 0) {
        permutations.add(sb_prefix);
    } else {
        for (int i = 0; i < n; i++) {
            permutations.addAll(permutationNew(sb_prefix.append(sb_str.charAt(i)), new StringBuffer(sb_str.substring(0, i)).append(sb_str.substring(i + 1, n))));
        }
    }
    return permutations;
}

我测试了这段代码并将其与您的旧方法进行了比较。这是我的结果。

 ____________________________________
| inputlength | oldmethod | newmethod|
 ------------------------------------
| 1           | 0 ms      | 0 ms     |
| 2           | 0 ms      | 0 ms     |
| 3           | 1 ms      | 0 ms     |
| 4           | 1 ms      | 0 ms     |
| 5           | 2 ms      | 0 ms     |
| 6           | 9 ms      | 3 ms     |
| 7           | 71 ms     | 38 ms    |
| 8           | 400 ms    | 66 ms    |
| 9           | 1404 ms   | 377 ms   |
| 10          | 9696 ms   | 2095 ms  |
L_[...]__________[...]______[...]____J

如果有很多方法引用您的排列方法,请围绕优化方法创建一个包装器:

private static HashSet<String> permutation(String prefix, String str) {
    HashSet<StringBuffer> permutations = permutationNew(new StringBuffer(prefix), new StringBuffer(str);
    //create new HashSet<String> using permutations-HashSet and return it...

【讨论】:

    猜你喜欢
    • 2022-01-05
    • 2022-10-24
    • 1970-01-01
    • 1970-01-01
    • 2023-03-22
    • 2012-03-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多