Если цель состоит в том, чтобы найти «максимально возможный разрыв для входных данных», как вы ответили, то алгоритм может быть довольно простым, если вы используете некоторую теорию графов. Вы берете составное слово и строите граф с вершинами до и после каждой буквы. У вас будет вершина для каждого индекса в строке и одна за концом. Затем вы найдете в своем словаре все допустимые слова, которые являются подстроками сложного слова. Затем для каждой допустимой подстроки добавьте к графу ребро с весом 1, соединяющее вершину перед первой буквой в подстроке с вершиной после последней буквы в подстроке. Наконец, используйте алгоритм кратчайшего пути, чтобы найти путь с наименьшим количеством ребер между первой и последней вершиной.
Псевдокод примерно такой:
parseWords(compoundWord)
# Make the graph
graph = makeGraph()
N = compoundWord.length
for index = 0 to N
graph.addVertex(i)
# Add the edges for each word
for index = 0 to N - 1
for length = 1 to min(N - index, MAX_WORD_LENGTH)
potentialWord = compoundWord.substr(index, length)
if dictionary.isElement(potentialWord)
graph.addEdge(index, index + length, 1)
# Now find a list of edges which define the shortest path
edges = graph.shortestPath(0, N)
# Change these edges back into words.
result = makeList()
for e in edges
result.add(compoundWord.substr(e.start, e.stop - e.start + 1))
return result
Я, конечно, не тестировал этот псевдокод, и могут быть какие-то ошибки индексации, и нет никакой проверки ошибок, но основная идея есть. Я делал что-то подобное в школе, и это работало очень хорошо. Циклы создания ребер — это O(M * N), где N — длина составного слова, а M — максимальная длина слова в вашем словаре или N (в зависимости от того, что меньше). Время выполнения алгоритма кратчайшего пути будет зависеть от того, какой алгоритм вы выберете. На ум сразу приходит Дейкстры. Я думаю, что его время выполнения составляет O (N ^ 2 * log (N)), поскольку максимально возможное количество ребер составляет N ^ 2.
Вы можете использовать любой алгоритм кратчайшего пути. Существует несколько алгоритмов поиска кратчайшего пути, которые имеют свои сильные и слабые стороны, но я догадываясь, что для вашего случая разница будет не слишком существенной. Если вместо того, чтобы пытаться найти наименьшее количество слов для разбиения составного слова, вы хотите найти максимально возможное, тогда вы присваиваете ребрам отрицательные веса и пытаетесь найти кратчайший путь с помощью алгоритм, допускающий отрицательные веса.
person
A. Levy
schedule
18.08.2009