Защо внедреният низ::substr() на c++ не използва алгоритъма 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)
. Така че, като изберете алгоритъм с по-добра сложност в най-лошия случай, можете да направите по-типичните случаи много по-бавни.
person
Mike Seymour
schedule
15.01.2012
string::find
, вижте публикацията ми: stackoverflow.com/questions/19506571/ - person Peter Lee   schedule 25.10.2013(std::string(n-1,'a')+"b"+std::string(n,'a')).find(std::string(n,'a'))
е O(n^2) или по-лошо. напр. за n = 1 милион отнема 21 секунди на моя компютър, но би трябвало да е мигновено (може би няколко милисекунди). - person Don Hatch   schedule 12.04.2020