Много людей говорит о том, как сложный мерзавец должен использовать, но это не стоит ничего, что, если Вы придерживаетесь очень простого мерзавца шаблона использования, не является больше сложным, чем говорят RCS.
Используя мерзавца для Вашего собственного управления версиями локали (для того же вида вещей Вы использовали бы RCS), я спорил бы легче, чем использование RCS.
, Конечно, при использовании его для больших проектов с загрузками людей и большим ветвлением и т.д. затем, это может стать более сложным, чем традиционные системы управления версиями.
Лично я использовал его главным образом для персональных проектов и для того, чтобы иметь локальное управление версиями на работе. Мы используем по необходимости на работе, и они довольно строги о количестве ответвлений, которые мы можем сделать, в каком мы можем зарегистрироваться. Мы добрались для регистрации в законченных, способных компиляцией, тестируемых блоках кода.
Часто я работал над большими заданиями рефакторинга, и меньшее выполнение закрепляет на стороне одновременно. Я нашел это очень трудным манипулировать по необходимости. Но с мерзавцем я смог иметь загрузки маленьких ответвлений локали для различных экспериментов, рефакторинга и устранения ошибки, которое я делал.
Так для меня привлекательные для покупателя качества мерзавца:
причина последней точки состоит в том, что мерзавец сохраняет все ответвления в том же каталоге, таким образом, Вы подкачиваете между ними с командами мерзавца и остаетесь такими же место. Мне нравится этот, потому что это означает, что я не должен настраивать конфигурационные файлы для своего IDE для нового каталога каждый раз, когда я перехожу, и я не трачу впустую загрузки пространства от наличия безумных чисел ответвлений.
Я не уверен, что это правильный ответ, но в любом случае:
При построении значения хеш-функции мы можем проверить соответствие в наборе хеш-значений строк. Также известно, что текущее хеш-значение. Хэш-функция / код обычно реализуются как цикл, и внутри этого цикла мы можем вставить наш быстрый поиск.
Конечно, мы должны выбрать m
, чтобы получить максимальную длину строки из набора строк .
Обновление: Из Википедии,
[...]
for i from 1 to n-m+1
if hs ∈ hsubs
if s[i..i+m-1] = a substring with hash hs
return i
hs := hash(s[i+1..i+m]) // <---- calculating current hash
[...]
Мы вычисляем текущий хэш за m
шагов. На каждом шаге есть временное хеш-значение , которое мы можем найти (сложность O (1)) в наборе хешей. Все хэши будут иметь одинаковый размер, т.е. 32 бита.
Обновление 2: амортизированная (средняя) временная сложность O (n)?
Выше я сказал, что m
должен иметь максимальную длину строки. Оказывается, мы можем использовать обратное.
С хешированием для сдвига поиска подстроки и фиксированным размером м
мы можем достичь сложности O (n).
Если у нас есть строки переменной длины, мы можем установить м
] до минимальной длины строки. Кроме того, в наборе хешей мы связываем хеш не со всей строкой, а с ее первыми m-символами.
Теперь при поиске текста мы проверяем, находится ли текущий хэш в наборе хешей, и проверяем связанные строки на соответствие.
Этот метод увеличивает количество ложных срабатываний, но в среднем он имеет временную сложность O (n).
Это потому, что хеш-значения подстрок связаны математически. Вычисление хэша H (S, j) (хеш символов, начиная с j-й позиции строки S ) занимает O (m) времени на струна длиной м . Но как только у вас есть это, вычисление H (S, j + 1) может выполняться за постоянное время, потому что H (S, j + 1) может быть выражено как функция от H (S, j) .
O (m) + O (1) => O (m) , т.е. линейное время.
Вот ссылка , где это описано более подробно (см., Например, раздел «Что делает Пост Рабина-Карпа? »)