【问题标题】:String comparison time complexity字符串比较时间复杂度
【发布时间】:2016-05-24 16:51:44
【问题描述】:

哪个比较需要更长的时间?

a = helloworldhelloworldhelloworld
b = https://www.somerandomurls.com/directory/anotherdirectory/helloworld.html
if a != b: doThis()

对比

a=one, b=two
if a != b: doThis()

我经常需要对照拥有数千行的数据库检查这一点。我不是在寻找任何特定的编程语言。我只想知道哪个比较更快。如您所见,b 的值在第一个示例中较长,而在第二个示例中较短。所以我想知道这是否会对比较产生任何影响。

【问题讨论】:

    标签: string comparison time-complexity


    【解决方案1】:

    字符串比较的时间是O(n),n是字符串的长度。

    但是根据测试数据,您可以手动优化匹配算法。我已经提到了一些。

    优化一:

    检查两个字符串的大小,如果不相等,返回false。因为这将停止进一步的 O(n) 比较,并节省时间。通常字符串数据结构将大小存储在内存中,而不是每次都计算它。这允许 O(1) 时间访问字符串大小。

    实际上这是一个巨大的优化。我将通过计算摊销时间复杂度来解释如何。

    如果您的字符串数据结构可以有一个最大大小为 x 的字符串,那么总共可以有 (x + 1) 个可能的字符串大小 (0, 1, 2, ... , x)。

    (x + 1)选择2种方式选择两个字符串 = x * (x + 1) / 2

    如果您使用优化 1,那么只有当两个字符串长度相等时,您才需要比较整个长度。只有 x + 1 个这样的情况。完成的操作数将是 0 + 1 + 2 + .... + x = x * (x + 1) / 2

    剩余的 (x + 1) * (x - 2) / 2 个案例将在 O(1) 时间内计算。

    因此总计算 = x * (x + 1) / 2 + (x + 1) * (x - 2) / 2 = (x + 1) * (x - 1)是 O(n^2)。由于我们正在进行 x * (x + 1) / 2 字符串比较,因此 每次比较的摊销时间复杂度为 O(1)

    如果没有任何优化,就会有

    0 + 1 * (x) * 1 + 2 * (x - 1) * 2 + 3 * (x - 3) * 3 + .... + x/2 * x/2 * x /2 计算。毫无疑问,这将超过 O(n^3)。并且摊销时间复杂度将超过 O(n)

    优化 2:

    由于您的数据库包含网络链接,它们可能属于同一个网站,因此它们的前几个字符将始终相同。这将导致多余的 CPU 时间使用。因此,最好从结尾检查这种情况,因为相对链接只会与结尾不同。

    注意 从理论上讲,我们并不是在开发一种可以改变最坏情况时间复杂度的算法,它仍然是 O(n)。我们只是在优化算法。

    【讨论】:

      【解决方案2】:

      字符串比较通常对字符进行线性扫描,在字符不匹配的第一个索引处返回 false。

      时间复杂度为 O(N),实际花费的时间取决于在统计差异出现之前需要扫描多少个字符。如果您的每个字符串都以 http:// 开头,则扫描前 7 个字符的开销将持续存在(无需针对您的专业数据定制比较算法)。

      如果您有长字符串,许多字符串的开头倾向于具有相同的起始字符,以及极端的性能要求,您可以考虑对字符串进行哈希处理,首先比较哈希值,并且仅在以下情况下才对字符串进行线性比较哈希匹配(以排除哈希冲突的可能性)。如果您使用比假定的长字符串短的哈希值进行初始比较,则可以通过仔细设计查询策略来减少系统的 IO 和 RAM 需求。

      【讨论】:

      • 既然字符串长度可以在恒定时间内进行比较,难道这不应该只适用于长度相等的字符串吗?我希望比较两个任意字符串以摊销到 O(1) 的时间复杂度,因为在平均情况下长度会有所不同。
      • 有时,虽然当它是真的时,成本已经转移到算法的不同部分。 C 语言将字符串存储为以空字符结尾的字符序列,因此您描述的算法将不起作用。许多语言(例如 C#)将有关字符串长度的信息存储为元数据。但是,在该程序执行的某个时刻,对字符串的字符进行计数以获得长度。当在程序运行期间多次比较给定字符串时,您的观点变得非常有效。存储长度成为一种有用的优化。
      猜你喜欢
      • 1970-01-01
      • 2015-10-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-04-01
      • 1970-01-01
      • 2015-08-24
      • 2018-01-06
      相关资源
      最近更新 更多