Проблема в написании кода для отфильтровки файла от одинаковых строк.
Нужно брать первую строку Мемо и сравнивать ее со следующей и т.д., а потом брать вторую строку и ...
Короче я пытаюсь сделать прогу, которая бы чистила спам-лист от одинаковых mail'ов. Вот...
Пока я пишу код, я настолько запутываюсь сам, что не помню где, что делается...
Помогите кусочком кода или размышлениями... А то я себе голову сломаю... Заранее спасибо!
Я не хочу пользоваться прогами сторонних разработчиков, я хочу сделать "под себя"!
Здравствуйте, Apri, Вы писали:
A> Проблема в написании кода для отфильтровки файла от одинаковых строк. A>Нужно брать первую строку Мемо и сравнивать ее со следующей и т.д., а потом брать вторую строку и ... A>Короче я пытаюсь сделать прогу, которая бы чистила спам-лист от одинаковых mail'ов. Вот... A>Пока я пишу код, я настолько запутываюсь сам, что не помню где, что делается...
A>Помогите кусочком кода или размышлениями... А то я себе голову сломаю... Заранее спасибо!
A>Я не хочу пользоваться прогами сторонних разработчиков, я хочу сделать "под себя"!
Если по несчастливой случайности средство разработки Delphi или ВСВ — то TStringList + Sorted = true и Duplicates = dupIgnore — поможет.
Здравствуйте, Apri, Вы писали:
A>Помогите кусочком кода или размышлениями... А то я себе голову сломаю... Заранее спасибо!
A>Я не хочу пользоваться прогами сторонних разработчиков, я хочу сделать "под себя"!
Общий подход: отсортировать и поубивать те, которые оказались по нескольку раз.
А реализации могут быть разными
Например, так:
// map string -> duplicatestypedef std::map<std::string, bool> map_sb; // таблицаtypedef std::pair<map_sb::iterator, bool> map_sb_pib; // для оптимизации операций с таблицей
map_sb table;
// первый проход: заполняем таблицу.for(each str)
{
map_si_pib pib = table.insert(str);
if(pib.second) // новенькое
pib.first->second = false; // инициализируем признакelse// уже было
pib.first->second = true; // существуют дубликаты!
}
// второй проход: проверяемfor(each str)
{
if(table[str]) // ага, есть дубликаты
kill_the_message();
}
Для ускорения работы (если это критично) можно считать хэш-функции (напр., CRC).
Иногда спамеры специально против таких умных, как ты, пихают в строки всякое случайное фуфло:
"Ворованные телефоны в ассортименте — FYWA1234asdf!@"
Поэтому (вероятно) тебе пригодится функция, делающая сигнатуру строки. (Например, выкусывать мусор).
Кстати, сам факт наличия мусора может служить критерием спама.
Наконец, можно использовать нестрогое равенство (если строки длиннее 20 символов, то достаточно совпадения 70% знакомест).
Здравствуйте, Apri, Вы писали:
A> Проблема в написании кода для отфильтровки файла от одинаковых строк. A>Нужно брать первую строку Мемо и сравнивать ее со следующей и т.д., а потом брать вторую строку и ... A>Короче я пытаюсь сделать прогу, которая бы чистила спам-лист от одинаковых mail'ов. Вот... A>Пока я пишу код, я настолько запутываюсь сам, что не помню где, что делается...
A>Помогите кусочком кода или размышлениями... А то я себе голову сломаю... Заранее спасибо!
A>Я не хочу пользоваться прогами сторонних разработчиков, я хочу сделать "под себя"!
Самое простое, что приходит на ум:
1) Открываем исходный файл
2) Читаем строку
3) Сохраняем ее в какой нибудь map (т.е. массив с доступом не по индексу, а по самой строке)
4) Записываем строку в другой файл
5) Читаем следующую строку
6) Если такой строки еще нет в нашем map, то переходим к пункту 3, если есть, то к пункту 4
Здравствуйте, Кодт, Вы писали:
К>Здравствуйте, Всеволод, Вы писали:
В>>На выходе имеем файл без повторяющихся строк.
К>Я так понял, что если строка повторяется — то ее вообще исключают (а не так, что оставляют один экземпляр). К>Потому что дубликаты — это признак спама.
Если детально разобраться в ранее описанном алгоритме, то:
1. Ошибка в самом описании алгоритма:
6) Если такой строки еще нет в нашем map, то переходим к пункту 3, если есть, то к пункту 4 (не 4, а 5)
2. В выходном файле все равно одна компия "спама" будет присутствовать
Также позволю себе немного апгрейдить алгоритм Всеволода:
1) Открываем исходный файл
2) Читаем строку
3) Сохраняем ее в какой нибудь map1 (т.е. массив с доступом не по индексу, а по самой строке), переходим к пункту 5
4) Переносим из map1 в какой-нить map2, переход к пункту 5
5) Читаем очередную строку
6) Если такая строка есть в map 2 -> пункт 5, иначе, если есть в mаp1 -> пункт 5, иначе -> пункт 3
Итого:
map1 — список абсолютно без спама
map2 — спам
Что с ними делать — воля разарботчика
Здравствуйте, Кодт, Вы писали:
К>Здравствуйте, Всеволод, Вы писали:
В>>На выходе имеем файл без повторяющихся строк.
К>Я так понял, что если строка повторяется — то ее вообще исключают (а не так, что оставляют один экземпляр). К>Потому что дубликаты — это признак спама.
Согласен !
Не четко понял изначальную постановку задачи — очистку списка, а не исключение повторов.
A> Проблема в написании кода для отфильтровки файла от одинаковых строк.
Во временном списке нужно сохранять копии спама, чтобы уметь его распознать, если он ещё попадётся.
И каждую следующую строчку в файле сравниваешь со всеми "хорошими" строчками, и со всем спамом. Если совпадения не нашлось, считай текущую строчку "хорошей".
Если совпало с каким-то спамом, то просто выкидывай текущую.
Если совпало с "хорошей" строчкой, то выкидывай и "хорошую" строчку, и текущую, но не забудь добавить копию в список спама.
Здравствуйте, Apri, Вы писали:
A> Благодаря Евгению (mrhru) я нашел правильный (простой) способ для фильтровки, плиз:
A>
A>procedure Tbody.OpenClick(Sender: TObject);
A>begin
A> OpenDialog.Filter:='Текстовые файлы (*.txt)|*.TXT|Все файлы (*.*)|*.*|Лист файлы (*.lst)|*.lst';
A> OpenDialog.Execute;
A>end;
A>procedure Tbody.StartClick(Sender: TObject);
A>var mass: TStringList;
A>begin
A> mass:=TStringList.Create;
A> mass.Sorted:=true;
A> mass.Duplicates:=DupIgnore;
A> try
A> mass.LoadFromFile(OpenDialog.FileName);
A> SaveDialog.Execute;
A> mass.SaveToFile(SaveDialog.FileName);
A> finally
A> mass.Free;
A> end;
A>end;
A>end.
A>
как-то странно ты не_проверяешь возврат метода Execute у диалога... неправильно это.
A>Потом зажал всё это дело ASPack'ом и в рез. получилось 160 кило.
Это можно понимать, как рекламу ASPack'а?
Ну, можно было бы из Uses просто повыбрасывать лишнее(например Graphics), итого получилось бы еще меньше...
А можно и вообще без *.dfm обойтись. Прописать создание формы ручками(из визуальщины тут всего две кнопки на форме), и размер бинарника будет еще на порядок меньше...