Нахождение общих для всех списков значений

Marcelo

Client
Регистрация
16.12.2014
Сообщения
109
Благодарностей
17
Баллы
18
Всем привет!:-)
Логика шаблона: В папке находится неизвестное заранее количество (может быть 2, 3, ..., 15 и т.д.) текстовых файлов user_***.txt, каждый из которых содержит список id пользователей. Мне необходимо сверить все списки и найти те значения, которые встречаются в каждом из этих списков (текстовых файлов user_***.txt).

Шаблон сделал, выкладываю. В примере, после запуска "на выходе" вы получите текстовый файл target.txt, который будет содержать значения "1" и "18". Эти значения есть в каждом из текстовых файлов.

Проблема (зачем я создал тему на форуме): Если списки содержат большой массив данных, например, 2 текстовых файла в каждом из которых по 100 000 id, то работа шаблона при такой логике затягивается на двое суток, что катастрофически долго o_O

Буду благодарен всем, кто потратит своё время и подскажет, как можно улучшить логику шаблона, чтобы сделать процесс сравнения списков гораздо более быстрым. Возможно есть решение на c#, так же буду признателен, если скажите, как сделать эту версию годной для использования на многопотоке (у меня light версия ZP и, к сожалению, не понимаю как должен выглядеть шаблон, который можно запускать в много потоков)
 

Вложения

Nick

Client
Регистрация
22.07.2014
Сообщения
1 982
Благодарностей
817
Баллы
113
Проект не смотрел, но скорее всего проблема в том, что ты в цикле по сто раз открываешь/закрываешь файлы.
Нужно один раз в начале открыть все файлы, считать содержимое в память (в переменную или список) и потом работать с этими переменными уже в памяти. Там всё на пару порядков быстрее отработает.
 
  • Спасибо
Реакции: Marcelo

VladZen

Administrator
Команда форума
Регистрация
05.11.2014
Сообщения
22 453
Благодарностей
5 911
Баллы
113
С какой целью нужно нахождение общих значений? Если с целью избежать повторений, то лучше объединить списки и просто удалить дубли.
 
  • Спасибо
Реакции: Marcelo

Marcelo

Client
Регистрация
16.12.2014
Сообщения
109
Благодарностей
17
Баллы
18
Нужно один раз в начале открыть все файлы, считать содержимое в память (в переменную или список) и потом работать с этими переменными уже в памяти.
именно так всё сейчас и реализовано. Данные из списков склеиваются и кладутся в 1 переменную с разделителем. Таким образом удалось сократить время сравнения списков по 100К с двух суток до полутора часа, но вдруг можно ещё быстрее ? :-)
С какой целью нужно нахождение общих значений? Если с целью избежать повторений, то лучше объединить списки и просто удалить дубли.
с целью получения этих самых значений.
 

Nick

Client
Регистрация
22.07.2014
Сообщения
1 982
Благодарностей
817
Баллы
113
А, ну то есть проблема уже другая. За полтора часа оно на кубиках так отрабатывает?
Если да, то на C# можно сначала эти списки отсортировать по возрастанию и хранить в оптимизированной для поиска структуре данных, тогда поиск будет почти мгновенным и вся эта катавасия может заработать ещё во много раз быстрее.
 
  • Спасибо
Реакции: Marcelo

Marcelo

Client
Регистрация
16.12.2014
Сообщения
109
Благодарностей
17
Баллы
18
За полтора часа оно на кубиках так отрабатывает?
да, на кубиках.
на C# можно сначала эти списки отсортировать по возрастанию и хранить в оптимизированной для поиска структуре данных, тогда поиск будет почти мгновенным и вся эта катавасия может заработать ещё во много раз быстрее.
в C# не соображаю, поэтому буду благодарен за помощь в написании. Или если это сложная работа, требующая времени, то напиши пожалуйста в лс, сколько это будет стоить и я взвешу скорость с ценой для себя :-)
 

Lexicon

Client
Регистрация
27.12.2012
Сообщения
1 775
Благодарностей
901
Баллы
113
во первых можно запилить на питоне - там даже есть подходящая структура - множества
во вторых можно запилить и на шарпе но мне лениво
в третьих вероятно у вас что то с логикой проекта для того, чтобы найти user_id которые есть во всех файлах лучше следовать следующему алгоритму

Открываем первый файл и забираем из него все элементы и кладем в список
открываем второй файл и забираем так же все из него
Находим пересечения между этими двумя файлами пусть оно будет зваться Х
Дальше при открытии первого файла мы ищем не все подряд строки а проверяем какие элементы из Х есть в третьем файле, и если какие то отсутствуют удаляем их из Х
В итоге вместо того чтобы перебирать каждый раз по 100500 строк вы будете сравнивать уменьшающийся массив Х который по завершении работ и будет представлять из себя пересечения всех файлов
 
  • Спасибо
Реакции: Marcelo

Marcelo

Client
Регистрация
16.12.2014
Сообщения
109
Благодарностей
17
Баллы
18
во первых можно запилить на питоне - там даже есть подходящая структура - множества
стыдно признаться, но не понимаю даже о чем речь :(
Находим пересечения между этими двумя файлами пусть оно будет зваться Х
Дальше при открытии первого файла мы ищем не все подряд строки а проверяем какие элементы из Х есть в третьем файле, и если какие то отсутствуют удаляем их из Х
объясни, пожалуйста, "на пальцах", так как моих навыков не хватает, чтобы понять как это реализовать через кубики
 

Lexicon

Client
Регистрация
27.12.2012
Сообщения
1 775
Благодарностей
901
Баллы
113
гм... берете строку 1 из списка А в цикле 1
внутри цикла 1 берете строку 1 из списка Б в цикле 2 и сравниваете... если совпало - кладете в список 3

Первый проход будет самый долгий остальные покороче
 
  • Спасибо
Реакции: Marcelo

Кто просматривает тему: (Всего: 1, Пользователи: 0, Гости: 1)