【问题标题】:Choice of algorithm for .indexOf method in JavaJava中.indexOf方法的算法选择
【发布时间】:2011-06-27 04:46:15
【问题描述】:

我只是在查看 Java String 类的 .indexOf() 方法的实现,代码作者似乎使用蛮力算法在给定字符串中查找子字符串。也就是说,该方法在 O(mn) 中运行,其中 m 和 n 分别是源字符串和目标字符串的长度。

为什么作者不使用像 Rabin-Karp 这样更高效的算法,如果提供了一个好的哈希函数,它的运行时间复杂度是 O(m + n) ?

我可能错过了执行此实施原因背后的完整知识,因此想了解。

【问题讨论】:

  • 你说的是String.indexOf(String)吗? substring() 创建一个新字符串。

标签: java string algorithm


【解决方案1】:

我假设您的意思是 indexOf 或 contains 而不是子字符串。子串为 O(1)

简单的代码通常运行得更快。例如,创建对象的代码通常运行得慢得多。

您为什么不尝试自己实现它,看看它是否更快。如果是,您可以建议他们改进方法。

【讨论】:

  • 请注意,如果您考虑 >= Java 7,从 6 开始更新,子字符串不再是 O(1)。
【解决方案2】:

我猜他们认为人们不会将它用于非常大的字符串。字符串长度小于 100 不会有太大不同。

【讨论】:

    【解决方案3】:

    我不确定为什么会做出这个决定,但如果我猜想这可能是因为对于小模式字符串(一个非常常见的用例),天真的蛮力算法可能与某些算法一样快,甚至更快渐近更快的算法,如 Rabin-Karp、Boyer-Moore 或 Knuth-Morris-Pratt。这似乎是一个合理的默认算法,因为在许多情况下,您将在小字符串中搜索小模式,并且强大的匹配设置的开销可能与天真的方法的运行时间相当。

    也就是说,Java 规范中没有任何地方要求使用这种算法。他们可以很容易地选择 Rabin-Karp 作为默认算法。

    他们可能选择这种方法的另一个原因是,如果您想进行快速文本搜索,正则表达式库提供更快的字符串匹配和更强大的搜索功能。默认情况下为用户提供简单的蛮力算法,并在需要时切换到更强大的工具集,这似乎是平衡渐近效率和实际效率的好方法。

    【讨论】:

    • 公平地说,正则表达式库是最近才添加的,所以它不可能是 indexOf() 的幼稚实现的原因。
    【解决方案4】:

    只是一个猜测,但请记住,Java 字符串存储为 UTF-16 是出于 i18n 的原因,而不是纯 8 位 ASCII。可能是在 UTF-16(以及更难的 UTF-8)上支持一些算法可能会出现问题。不过,只是猜测。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-06-01
      • 1970-01-01
      • 2012-01-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多