Java 中 String.contains() 的大 O 是啥?
Posted
技术标签:
【中文标题】Java 中 String.contains() 的大 O 是啥?【英文标题】:What is the Big-O of String.contains() in Java?Java 中 String.contains() 的大 O 是什么? 【发布时间】:2011-05-04 14:59:14 【问题描述】:我正在做一个项目,需要优化运行时间。 String.contains()
runtime 是不是和TreeSet.contains()
一样,都是O(logN)?
我问的原因是我正在构建一个TreeMap<String, TreeSet<Song>>
,其中 Songs 包含一串歌词。根据效率,我正在考虑在歌曲中包含一组歌词,并在其上而不是字符串上运行搜索。
【问题讨论】:
不想成为一个混蛋或其他什么,但:为什么不分析它? 如果我有时间做测试,也许吧。我想在项目中运行另一个测试:treeset 和 hashset 之间的运行时变化。如果一天有 30 小时,那么时间还不够! 【参考方案1】:最著名的算法之一是 Boyer-Moore 字符串搜索算法,虽然它可以在最好的情况下提供次线性性能,但它是 O(n)。
在 Java 中使用哪种算法取决于您下载的实现。例如,OpenJDK 似乎使用了一种在 O(nm) 中运行的简单算法,并且在最佳情况下具有线性性能。请参阅第 1770-1806 行 here。
【讨论】:
您链接到的文章说它是 O(n),因为它最多进行 3n 次比较。 “最坏情况 O(n)”是重言式 - 根据定义 O(n) 是最坏情况 :) 根据programmers.stackexchange.com/questions/65558/…,jdk1.6.0_23 具有与当代 OpenJDK 相同的String.indexOf()
实现。有人可以告诉你String.contains()
是否属实
@NicholasWhite O(n) 是一个上限。它可能是最坏情况、平均情况或最佳情况性能的上限。上限和下限与最佳/平均/最差情况正交。另一个正交维度是loose vs. tight。 O(n) 是一个宽松的上限。 Θ(n) 是一个严格的上限和下限。【参考方案2】:
.contains()
绝对使用幼稚的方法,相当于O(nm)
的时间复杂度。
O(nm)
时间。
KMP 在最坏的情况下需要 O(n)
时间。
在与模式匹配相关的问题之一中,我使用了.contains()
,它花费了70 ms
,而用patternSearch() //KMP search
替换该行将时间减少到14 ms
。
Java source code | KMP search vs .contains()
【讨论】:
KMP 最坏情况是 O(n + m),因为您需要事先创建 lsp 表。 是的,但即使在最坏的情况下n==m
-> O(n+m) -> O(2n) -> O(n)【参考方案3】:
您也可以尝试使用 Trie 代替 TreeMap(尽管 Java 没有内置的 Trie 实现)
【讨论】:
Trie reference 似乎 Trie 只支持“starts with”,不支持“contains”?以上是关于Java 中 String.contains() 的大 O 是啥?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Java 中的 String.contains() 方法中使用正则表达式
在 .Net Standard 2.0 中替换 string.Contains(string, StringComparison)