Можете ли вы придумать канонизирующую функцию для циклических строк, основанную на следующем:
- Найдите наибольший ряд нулей.
- Поверните строку так, чтобы этот ряд нулейнаходится впереди.
- Для каждого прогона нулей одинакового размера, посмотрите, если вращение на фронт приводит к лексикографически меньшей строке, и если это так, используйте это.
Это канонизируетвсе в классе эквивалентности (1011, 1101, 1110, 0111) до лексикографически наименьшего значения: 0111.
0101010101
- сложный случай, для которого этот алгоритм не будет работать хорошо, но если ваши биты примернослучайным образом распределенный, он должен хорошо работать на практике для длинных строк.
Затем вы можете хешировать на основе канонической формы или использовать три, которая будет включать только пустую строку и строки, начинающиеся с 0, и один прогон трия.ответит на ваш вопрос.
РЕДАКТИРОВАТЬ:
, если у меня есть строка длины | s |Чтобы найти наименьшее лексикографическое значение, может потребоваться много времени. Сколько времени на самом деле это займет?
Вот почему я сказал, что 010101....
- это значение, для которого оно плохо работает.Скажем, строка имеет длину n, а самая длинная последовательность из 1 имеет длину r.Если биты распределены случайным образом, длина самого длинного прогона равна O (log n) согласно «Распределение самого длинного прогона» .
Время поиска самого длинного прогона равно O (п).Вы можете реализовать сдвиг, используя смещение вместо буферной копии, которая должна быть O (1).Количество прогонов - наихудший случай O (n / m).
Тогда время выполнения шага 3 должно быть
- Найти другие длинные прогоны: один O (n) проходс O (log n) среднего значения хранения, O (n) наихудшим случаем
- Для каждого прогона: O (log n) среднего случая, O (n) наихудшим случаем
- Сдвиг и сравнение лексикографически: O (log n) средний случай, так как большинство сравнений случайно выбранных строк терпят неудачу рано, O (n) худший случай.
Это приводит к худшему случаю O (n²), но средний случайO (n + log² n) ≅ O (n).