【问题标题】:what is the time complexity of .equals in java for 2 strings?java中.equals对于2个字符串的时间复杂度是多少?
【发布时间】:2013-01-27 21:04:32
【问题描述】:

我想知道 Java 中 .equals 运算符对于两个字符串的时间复杂度(大 O)是多少。

基本上,如果我执行 stringOne.equals(stringTwo),它的性能如何?

谢谢。

【问题讨论】:

  • 你会怎么想?您认为平等检查是如何实施的?
  • 如果两个Strings都被interned,可以在恒定时间内完成。

标签: java string big-o


【解决方案1】:

这里的其他答案过于简单了。

一般来说,证明两个不同的字符串相等是O(n),因为您可能必须比较每个字符。

但这只是最坏的情况:有许多捷径意味着equals() 方法在平均/典型情况下的表现要好得多:

  • 如果字符串相同,则为 O(1):它们是同一个对象,因此根据定义相等,因此结果为真
  • O(1) 如果您能够检查预先计算的哈希码,这可以证明两个字符串不相等(显然,它不能帮助证明两个字符串相等,因为很多字符串哈希到相同的哈希码)。
  • 如果字符串的长度不同,则为O(1)(它们不可能相等,因此结果为假)
  • 您只需要检测一个不同的字符即可证明字符串不相等。所以对于随机分布的字符串,比较两个字符串实际上是平均O(1) 时间。如果您的字符串不是完全随机的,则结果可能介于 O(1)O(n) 之间,具体取决于数据分布。

如您所见,确切的性能取决于数据的分布

除此之外:这是依赖于实现,因此确切的性能特征将取决于所使用的 Java 版本。但是,据我所知,当前所有主要的 Java 实现都进行了上面列出的优化,因此您可以期望 equals() 在字符串上的性能非常快。

最后一个技巧:如果您使用 String interning,那么所有相等的 String 都将映射到同一个对象实例。然后,您可以使用极快的== 检查对象身份来代替equals(),保证为O(1)。这种方法有缺点(您可能需要实习很多字符串,这会导致内存问题,并且您需要严格记住要实习您计划与此方案一起使用的任何字符串),但在某些情况下它非常有用。

【讨论】:

  • 实习的另一个缺点是您必须记住来实习每个要比较的字符串。如果使用== 比较一个非内部字符串,那么您的代码可能会中断。这会使您的应用程序变得脆弱。
  • 您还可以提及依赖于 String 对象(特定于实现的)哈希码缓存的(假设的)优化。
  • 哈希冲突调用。 > 如果您能够检查预先计算的哈希码,则为 O(1),这可以证明两个字符串不相等(显然,它无法帮助证明两个字符串相等,因为许多字符串哈希到相同的哈希码)。
  • 见鬼,如果应用程序的唯一目标是比较明确定义的字符串池,那么实习可能是一笔大买卖。也许我应该习惯在使用通用算法之前检查我的目标两次。
  • 我不认为这是正确的。与 sgupta 相同的原因。
【解决方案2】:

最坏的情况是 O(n),除非两个字符串是同一个对象,在这种情况下是 O(1)。

(虽然这里的n指的是从第一个字符开始的两个字符串中匹配的字符数,而不是字符串的总长度)。

【讨论】:

  • 没错,我忘记了对象身份。
  • OpenJDK 在比较字符之前至少会检查Strings 的长度是否相同。
  • 这个答案是误导。缩放问题中的常规 N 是数据结构的长度/大小 ...
【解决方案3】:

为了增加出色的答案,我们可以查看代码:

public boolean equals(Object anObject) {
    if (this == anObject) { // O(1)
        return true;
    }
    if (anObject instanceof String) //O(1)  {
        String anotherString = (String)anObject;
        int n = value.length;
        if (n == anotherString.value.length) { // O(1)
            char v1[] = value;
            char v2[] = anotherString.value;
            int i = 0;
            while (n-- != 0) {  // O(n)
                if (v1[i] != v2[i]) //O(1)
                    return false;
                i++;
            }
            return true;
        }
    }
    return false;
}

最佳情况:O(1)

最坏情况:O(n)

【讨论】:

    猜你喜欢
    • 2023-04-07
    • 1970-01-01
    • 2012-02-13
    • 2013-05-21
    • 2011-02-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多