【问题标题】:String comparison in constant time恒定时间内的字符串比较
【发布时间】:2020-04-18 11:01:01
【问题描述】:

我正在考虑比较两个字符串的更快方法。 检查 Python 集合(哈希表)中是否存在值具有恒定的时间。 是不是意味着在set中查找字符串也有恒定的时间?

print('tya' == 'tya') #O(n)
mySet = set()
mySet.add('tya')
if 'tya' in mySet: #O(1) <-- ???
    print('True')

在更一般的情况下,这是否意味着我可以在线性时间内找到字符串中的子字符串???

def NaiveFind(largeString, subString):
    mySet = set()
    mySet.add(subString)
    index = -1
    start = 0
    end = len(subString)

    while(end < len(largeString)): #O(n-m)
        windowFromLarge = largeString[start:end]
        if(windowFromLarge in mySet): #O(1) <------- LINEAR ???
        #if(windowFromLarge == subString): #O(m)
            return start
        start += 1
        end += 1

    return index

【问题讨论】:

  • 这不会比仅比较两个字符串更快,因为您必须创建集合等
  • 相对于集合的大小大约是 O(1)。字符串的散列时间似乎是 O(len(string)),请参阅 stackoverflow.com/questions/2070276/…
  • 当然,但我正在创建与实际子字符串匹配算法并行的集合

标签: python python-3.x string-comparison


【解决方案1】:

你说

检查 Python 集合(哈希表)中是否存在值具有恒定的时间。

但这是一种常见的过度简化,因为人们没有意识到他们正在这样做,或者因为每次说出实际行为需要更长的时间。

检查一个值是否存在于 Python 集中需要 平均大小写常量 数量的散列操作和相等比较,假设散列冲突不会失控.它不会自动使散列操作和相等比较的时间恒定。

您的NaiveFind 算法不是线性时间,因为您忽略了哈希计算的成本(也因为字符串切片需要在 CPython 中进行复制)。 Rabin-Karp algorithm 使用您的想法的改进版本,其中哈希是 rolling hash 以避免此问题。 Rabin-Karp 算法是平均情况线性时间,只要哈希冲突不会失控。还有像Knuth-Morris-Pratt 这样的算法可以保证线性时间,而像Boyer-Moore 这样的算法在通常情况下可以比线性时间做得更好

【讨论】:

  • 我明白了,但是如果我像上面的算法那样在子字符串匹配中使用它,它会提高天真的方法复杂度吗?
  • @KocT9H:不。请参阅扩展答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-24
  • 2013-09-19
  • 2014-10-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多