Как узнать, может ли строка быть сегментирована на две строки

Меня задали в интервью следующий вопрос. Я не мог понять, как подойти к этому вопросу. Пожалуйста, направляйте меня.

Вопрос: Как узнать, может ли цепочка быть сегментирована на две строки - например, хлеббана является сегментируемым в хлеб и банан, а хлеббанан - нет. Вам будет предоставлен словарь, содержащий все допустимые слова.

Ответ 1

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

EDIT: извините, пропустил тот факт, что должно быть только два слова. В этом случае ограничьте глубину рекурсии до 2.

Псевдокод для двух слов будет:

T = trie of words in the dictionary
for every word in T, which can be found going down the tree by choosing the next letter of the input string each time we move to the child:
    p <- length(word)
    if T contains input_string[p:length(intput_string)]:
        return true
return false

Предполагая, что вы можете перейти к дочернему node в trie in O(1) (ascii-индексы для детей), вы можете найти все префиксы входной строки в O(n+p), где p - это число префиксы и n длину ввода. Верхняя граница на этом O(n+m), где m - количество слов в словаре. При проверке для сложения будет O(w), где w - длина слова, для которой верхняя граница будет m, поэтому временная сложность алгоритма O(nm), так как O(n) распределяется в первом фазы между всеми найденными словами.

Но поскольку мы не можем найти больше, чем n слов на первом этапе, сложность также ограничена O(n^2). Таким образом, сложность поиска будет O(n*min(n, m)) До этого вам нужно построить trie, который примет O(s), где s - сумма длин слов в словаре. Верхняя граница на этом равна O(n*m), так как максимальная длина каждого слова n.

Ответ 2

вы просматриваете свой словарь и сравниваете каждый термин как подстроку с исходным термином, например. "Breadbanana". Если первый член совпадает с первой подстрокой, вырежьте первый член из исходного условия поиска и сравните следующие словарные статьи с остальной частью исходного термина...

Позвольте мне попытаться объяснить, что в java: например.

    String dictTerm = "bread";
    String original = "breadbanana";

    // first part matches
    if (dictTerm.equals(original.substring(0, dictTerm.length()))) {
        // first part matches, get the rest
        String lastPart = original.substring(dictTerm.length());

        String nextDictTerm = "banana";

        if (nextDictTerm.equals(lastPart)) {
            System.out.println("String " + original +
                " contains the dictionary terms " +
                dictTerm + " and " + lastPart);
        }
    }

Ответ 3

Простейшее решение:

Разделите строку между каждой парой последовательных символов и посмотрите, находятся ли в словаре словарные подстроки (слева от точки разделения и справа от нее).

Ответ 4

Один подход может быть:

Put all elements of dictionary in some set or list теперь вы можете использовать функции contains и substring для удаления слов, соответствующих словарю. если в конце строки есть null → строка может быть сегментирована иначе. Вы также можете позаботиться о счете.

Ответ 5

public boolean canBeSegmented(String s) {
    for (String word : dictionary.getWords()) {
        if (s.contains(word) {
            String sub = s.subString(0, s.indexOf(word)); 
            s = sub + s.subString(s.indexOf(word)+word.length(), s.length()-1);
        }

        return s.equals("");
    }
}

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

Просто два слова облегчают:

public boolean canBeSegmented(String s) {
    boolean wordDetected = false;

    for (String word : dictionary.getWords()) {
        if (s.contains(word) {
            String sub = s.subString(0, s.indexOf(word)); 
            s = sub + s.subString(s.indexOf(word)+word.length(), s.length()-1);

            if(!wordDetected) 
                wordDetected = true;
            else 
                return s.equals("");
        }

        return false;
     }
}

Этот код проверяет одно слово и если в строке есть другое слово, и только эти два слова он возвращает true, иначе false.

Ответ 6

Это простая идея, вы можете реализовать ее лучше, если хотите

package farzi;

import java.util.ArrayList;

public class StringPossibility {
    public static void main(String[] args) {
        String str = "breadbanana";
        ArrayList<String> dict = new ArrayList<String>();
        dict.add("bread");
        dict.add("banana");
        for(int i=0;i<str.length();i++)
        {
            String word1 = str.substring(0,i);
            String word2 = str.substring(i,str.length());
            System.out.println(word1+"===>>>"+word2);
            if(dict.contains(word1))
            {
                System.out.println("word 1 found : "+word1+" at index "+i);
            }
            if(dict.contains(word2))
            {
                System.out.println("word 2 found : "+ word2+" at index "+i);
            }
        }

    }

}