Определить, является ли одна строка префиксом другой

Я записал простую функцию, которая определяет, является ли строка str1 префиксом строки str2. Это очень простая функция, которая выглядит так (в JS):

function isPrefix(str1, str2) // determine if str1 is a prefix of a candidate string
{
    if(str2.length < str1.length) // candidate string can't be smaller than prefix string 
        return false;

    var i = 0;
    while(str1.charAt(i) == str2.charAt(i) && i <= str1.length)
        i++;
   if(i < str1.length) // i terminated => str 1 is smaller than str 2
        return false;
    return true;
}

Как видите, он перебирает всю длину строки префикса, чтобы определить, является ли она префиксом строки-кандидата. Это означает, что его сложность равна O(N), что неплохо, но это становится проблемой, когда у меня есть огромный набор данных, чтобы рассмотреть цикл, чтобы определить, какие строки имеют строку префикса как часть префикса. Это делает сложность кратной, как O (M * N), где M — общее количество строк в данном наборе данных. Фигово.

Я немного изучил Интернет, чтобы определить, что лучшим ответом будет тройка Patricia/Radix. Где строки хранятся как префиксы. Даже тогда, когда я пытаюсь вставить/поиск строки, будут значительные накладные расходы на сопоставление строк, если я использую вышеупомянутую функцию проверки префикса.

Скажем, у меня была строка префикса «rom» и набор слов-кандидатов.

var dataset =["случайный","быстрый","романтика","румыния","рим","роза"];

что хотело бы это в radix trie :

         r
       /    \
     a       o
    / \     / \
ndom pid  se  m
             / \
           an   e
          /  \
        ia   ce

Это означает, что для каждого узла я буду использовать функцию сопоставления префикса, чтобы определить, какой узел имеет значение, соответствующее строке префикса в индексе. Почему-то это решение все еще кажется трудным и не слишком мне подходит. Есть ли что-то лучше или в любом случае я могу улучшить функцию сопоставления основных префиксов?


person Parijat Kalia    schedule 03.09.2013    source источник


Ответы (2)


Похоже, у вас две разные проблемы.

Один из них — определить, содержится ли строка в качестве префикса в другой строке. Для этого я бы предложил использовать функцию, уже реализованную в строковой библиотеке языка. В JavaScript вы можете сделать это

if (str2.indexOf(str1) === 0) {
    // string str1 is a prefix of str2
}

См. документацию для String.indexOf здесь: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/indexOf

Что касается другой проблемы, в наборе строк узнайте, какие из них имеют заданную строку в качестве префикса, создание структуры данных, такой как Trie или та, которую вы упомянули, кажется подходящим способом, если вы хотите быстрый поиск.

person Ram    schedule 04.09.2013
comment
пометка как правильная, потому что это намного лучше, чем мое решение для сопоставления префиксов, и это был основной вопрос, а не структура данных, а также потому, что вам нужны некоторые очки, отчаянно @Ram :) - person Parijat Kalia; 05.09.2013
comment
О, да!? Вам срочно нужен Hadoop! :П - person Ram; 05.09.2013
comment
Разве это решение неэффективно? Если одна строка является префиксом другой, вы должны остановиться на первом несоответствии. Однако indexOf попытается выполнить ту же проверку, но по одному разу для каждого символа str2. - person Peregring-lk; 12.07.2020

Посмотрите этот поток в stackoverflow — Как проверить, начинается ли строка с другой строки?. Решение Mark Byers кажется очень эффективным. Также для Java встроены функции String "endsWith" и "startsWith" - http://docs.oracle.com/javase/tutorial/java/data/comparestrings.html

person jaykhopale    schedule 04.09.2013