Нужное решить такую задачу:
Разбить множество уникальных строк на непересекающиеся группы по
следующему критерию:
Если две строчки имеют совпадения непустых значений в одной или более
колонках, они принадлежат одной группе.
Например, строчки
111;123;222
200;123;100
300;;100
все принадлежат одной группе, так как первые две строчки имеют
одинаковое значение 123 во второй колонке, а две последние одинаковое
значение 100 в третьей колонке
Также есть ограничение на время работы программы (30 секунд). Также могу добавить количество строк - около миллиона.
Вот мой код:
private static Set
Iterator
return 0;
});
Map
for (int lineNum = 0; lineNum < lines.size(); lineNum++) {
String line = lines.get(lineNum);
String[] lineElements = line.replaceAll("\"", "").replaceAll(" ", "").split(";");
Set
Integer groupNum = null;
TreeSet
if (groupNum == null) {
TreeSet
resultSet.addAll(lineNumGroups);
return resultSet;
}
И все мои решения работают слишком долго (а пробовал по-разному решать эту задачу). Правда, если строк меньше тысячи, то работает быстро (укладываюсь в указанное ограничение), и практически с любым моим алгоритмом.
Прошу подсказать, как можно решить эту задачку (или что изменить в моём решении, чтобы работало быстро).
Ответ
К какому решению "почти в лоб" я пришел:
храним результат в виде списка списков: [номер_группы -> [строки_группы]]
используем вспомогательный список хэш-таблиц: [позиция_слова -> { слово -> номер_группы }]
и вспомогательную хэш-таблицу для хранения какая группа в какую была влита
каждую строку разбиваем на слова
каждое слово строки ищем в соответствующей (позиции слова в строке) хэш-таблице
если слово есть, запоминаем номер группы (значение из хэш-таблицы), в которой оно найдено
если слова нет, то добавляем его в список новых слов
если строка (а точнее её слова) найдена в группах, то берём первую из "живых" (объяснение этого позже) групп, иначе создаём новую группу
добавляем новые слова в соответствующие хэш-таблицы с номером найденной/созданной группы
объединяем найденные группы в одну, выбранную ранее. Так как группы хранятся в виде списка строк, то просто объединяем списки строк в один у выбранной группы, а более ненужные группы отмечаем как "мёртвые" (присваиваем null, дабы не перемещать элементы внутри списка)
добавляем строку в список строк группы
Кода выходит ещё больше, чем слов:
//вспомогательный класс для добавления новых слов
private static class NewWord
{
public String value;
public int position;
public NewWord(String value, int position)
{
this.value = value;
this.position = position;
}
}
private static List> findGroups(List
Комментариев нет:
Отправить комментарий