Почему реализованная в C ++ функция string :: substr () не использует алгоритм KMP (и не работает в O (N + M)) и работает в O (N * M)?
Я предполагаю, что вы имеете в виду find()
, а не substr()
, который не нуждается в поиске и должен выполняться за линейное время (и только потому, что он должен скопировать результат в новую строку).
Стандарт C ++ не определяет детали реализации, а только определяет требования к сложности в некоторых случаях.Единственные требования к сложности операций std::string
состоят в том, что size()
, max_size()
, operator[]
, swap()
, c_str()
и data()
имеют постоянное время.Сложность чего-либо еще зависит от выбора, сделанного тем, кто внедрил используемую вами библиотеку.
Наиболее вероятная причина выбора простого поиска по сравнению с чем-то вроде KMP - избегать необходимости дополнительного хранилища.Если строка, которую нужно найти, не очень длинная, а строка для поиска содержит много частичных совпадений, то время, затрачиваемое на ее выделение и освобождение, вероятно, будет намного больше стоимости дополнительной сложности.
Исправлено ли это в c ++ 0x?
Нет, C ++ 11 не добавляет никаких требований к сложности к std::string
и, конечно, не добавляет никаких обязательных подробностей реализации.
Если сложность текущего substr не O (N * M), что это?
Это сложность наихудшего случая, когда искомая строка содержитмного длинных частичных совпадений.Если символы имеют достаточно равномерное распределение, то средняя сложность будет ближе к O(N)
.Поэтому, выбирая алгоритм с лучшей сложностью в худшем случае, вы можете сделать более типичные случаи намного медленнее.