Какова лучшая структура данных и алгоритм для сравнения списка строк? - PullRequest
4 голосов
/ 25 декабря 2010

Я хочу найти максимально длинную последовательность слов, которая соответствует следующим правилам:

  • Каждое слово можно использовать не более одного раза
  • Все слова являются строками
  • Две строки sa и sb могут быть объединены, если последние два символа sa соответствуют первым двум символам sb.

В случае конкатенации это выполняется путем наложения этих символов. Например:

  • sa = "torino"
  • sb = "новара"
  • sa concat sb = "ториновара"

Например, у меня есть следующий входной файл "input.txt":

Новара

Torino

Верчелли

Равенна

Napoli

liverno

messania

1044 * Нови-Лигуре *

1046 * Roma *

И, вывод вышеуказанного файла в соответствии с вышеуказанными правилами должен быть:

Torino

Новара

Равенна

Napoli

Ливорно

1064 * Нови-Лигуре *

, поскольку самая длинная возможная конкатенация:

torinovaravennapolivornovilligure

Может кто-нибудь помочь мне с этим? Какова будет лучшая структура данных для этого?

Ответы [ 2 ]

5 голосов
/ 25 декабря 2010

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

(Ну, на самом деле, вы хотите немного расширить график, чтобы обработать начало и конец слова. Присоедините «начальный узел» с ребром к каждому слову слова весовой длины /2. Между словами: -overlap + длина начала + длина конца / 2, и между каждым словом и "конечным узлом" "длина слова / 2". Может быть проще удвоить его.)

https://cstheory.stackexchange.com/questions/3684/max-non-overlapping-path-in-weighted-graph

1 голос
/ 26 декабря 2010

Я бы начал очень просто. Создайте 2 вектора строк, один из которых отсортирован как обычно, а другой - по двум последним буквам. Создайте индекс (вектор целых) для второго вектора, который указывает его положение в первом.

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

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

Некоторые пункты для рассмотрения: Если у вас 3+ уникальных конца, вы гарантированно отбросите 1+ слов. Это может быть использовано для сокращения ваших попыток во время поиска ответа. часто пересчитывать уникальные цели. Нечетные числа данного конца гарантируют, что один должен быть отброшен (вы получаете 2 халявы на концах). Отделяйте слова, которые могут соответствовать самому себе, вы всегда можете бросить их последними, и иначе они испортят математику. Возможно, вам удастся создать маленькие самосогласованные кольца, вы можете относиться к ним как к самоподобным словам, если вы не осиротите их при создании. Это может сделать производительность фантастической, но не гарантирует идеального решения.

Пространство поиска - это порядок (N!), Список миллионов элементов может быть трудно доказать точный ответ. Конечно, я мог что-то упустить из виду.

...