временная сложность python str.index

Для нахождения позиции подстроки внутри строки наивный алгоритм займет O(n^2) времени. Однако при использовании некоторых эффективных алгоритмов (например, алгоритм KMP), это может быть достигнуто за время O(n):

s = 'saurabh'
w = 'au'

def get_table():
    i = 0; j = 2 
    t = []
    t.append(-1); t.append(0)
    while i < len(w):
        if w[i] == w[j-1]:
            t.append(j+1)
            j += 1
        else:
            t.append(0)
            j = 0 
        i += 1
    return t

def get_word():
    t = get_table()
    i = j = 0 
    while i+j < len(s):
        if w[j] == s[i+j]:
            if j == len(w) - 1:
                return i
            j += 1
        else:
            if t[j] > -1: 
                i = i + j - t[j]
                j = t[j]
            else:
                i += 1
    return -1

if __name__ == '__main__':
    print get_word()

Однако, если мы делаем: 'saurabh'.index('ra'), использует ли он внутри себя какой-то эффективный алгоритм для вычисления этого в O(n) или использует наивный алгоритм сложности O(n^2)?


person Saurabh Verma    schedule 26.04.2016    source источник
comment
Вы можете профилировать его и посмотреть, растет ли время экспоненциально или линейно;)   -  person Joel Cornett    schedule 26.04.2016


Ответы (3)


В этой статье [1] автор проходит алгоритм и объясняет его. Из статьи:

The function “fastsearch” is called. It is a mix between 
Boyer-Moore and Horspool algorithms plus couple of neat tricks.

И со страницы вики алгоритма Бойера-Мура-Хорспула [2]:

The algorithm trades space for time in order to obtain an 
average-case complexity of O(N) on random text, although 
it has O(MN) in the worst case, where the length of the 
pattern is M and the length of the search string is N.

Надеюсь, это поможет!

[1] http://www.laurentluce.com/posts/python-string-objects-implementation

[2] https://en.wikipedia.org/wiki/Boyer%E2%80%93Moore%E2%80%93Horspool_algorithm

person alpert    schedule 26.04.2016
comment
Но время наихудшего случая KMP по-прежнему линейно. Означает ли это, что мы должны реализовать наш код с использованием алгоритма KMP вместо встроенного в Python index() для критичных по времени процессов? - person Saurabh Verma; 26.04.2016
comment
Я думаю, что в этой ветке есть хороший ответ на эту тему: programmers.stackexchange.com/questions/183725/ - person alpert; 26.04.2016

это комбинация нескольких алгоритмов - посмотрите на это

Python string 'in' алгоритм реализации оператора и временная сложность

или это

http://effbot.org/zone/stringlib.htm

person Jonathan    schedule 26.04.2016

Иногда вы можете получить быстрый ответ, просто попробовав

>>> timeit.timeit('x.index("ra")', setup='x="a"*100+"ra"')
0.4658635418727499
>>> timeit.timeit('x.index("ra")', setup='x="a"*200+"ra"')
0.7199222409243475
>>> timeit.timeit('x.index("ra")', setup='x="a"*300+"ra"')
0.9555441829046458
>>> timeit.timeit('x.index("ra")', setup='x="a"*400+"ra"')
1.1994099491303132
>>> timeit.timeit('x.index("ra")', setup='x="a"*500+"ra"')
1.4850994427915793
person Francesco    schedule 26.04.2016