Фильтруй...
От: Apri  
Дата: 14.03.03 07:55
Оценка:
Проблема в написании кода для отфильтровки файла от одинаковых строк.
Нужно брать первую строку Мемо и сравнивать ее со следующей и т.д., а потом брать вторую строку и ...
Короче я пытаюсь сделать прогу, которая бы чистила спам-лист от одинаковых mail'ов. Вот...
Пока я пишу код, я настолько запутываюсь сам, что не помню где, что делается...

Помогите кусочком кода или размышлениями... А то я себе голову сломаю... Заранее спасибо!

Я не хочу пользоваться прогами сторонних разработчиков, я хочу сделать "под себя"!
Re: Фильтруй...
От: mrhru Россия  
Дата: 14.03.03 08:04
Оценка: 22 (1)
Здравствуйте, Apri, Вы писали:

A> Проблема в написании кода для отфильтровки файла от одинаковых строк.

A>Нужно брать первую строку Мемо и сравнивать ее со следующей и т.д., а потом брать вторую строку и ...
A>Короче я пытаюсь сделать прогу, которая бы чистила спам-лист от одинаковых mail'ов. Вот...
A>Пока я пишу код, я настолько запутываюсь сам, что не помню где, что делается...

A>Помогите кусочком кода или размышлениями... А то я себе голову сломаю... Заранее спасибо!


A>Я не хочу пользоваться прогами сторонних разработчиков, я хочу сделать "под себя"!


Если по несчастливой случайности средство разработки Delphi или ВСВ — то TStringList + Sorted = true и Duplicates = dupIgnore — поможет.
Евгений
Re: Фильтруй...
От: Кодт Россия  
Дата: 14.03.03 10:41
Оценка: 22 (1)
Здравствуйте, Apri, Вы писали:

A>Помогите кусочком кода или размышлениями... А то я себе голову сломаю... Заранее спасибо!


A>Я не хочу пользоваться прогами сторонних разработчиков, я хочу сделать "под себя"!


Общий подход: отсортировать и поубивать те, которые оказались по нескольку раз.

А реализации могут быть разными
Например, так:
// map string -> duplicates

typedef 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% знакомест).
Перекуём баги на фичи!
Re: Фильтруй...
От: Всеволод Россия  
Дата: 14.03.03 12:06
Оценка:
Здравствуйте, Apri, Вы писали:

A> Проблема в написании кода для отфильтровки файла от одинаковых строк.

A>Нужно брать первую строку Мемо и сравнивать ее со следующей и т.д., а потом брать вторую строку и ...
A>Короче я пытаюсь сделать прогу, которая бы чистила спам-лист от одинаковых mail'ов. Вот...
A>Пока я пишу код, я настолько запутываюсь сам, что не помню где, что делается...

A>Помогите кусочком кода или размышлениями... А то я себе голову сломаю... Заранее спасибо!


A>Я не хочу пользоваться прогами сторонних разработчиков, я хочу сделать "под себя"!


Самое простое, что приходит на ум:

1) Открываем исходный файл
2) Читаем строку
3) Сохраняем ее в какой нибудь map (т.е. массив с доступом не по индексу, а по самой строке)
4) Записываем строку в другой файл
5) Читаем следующую строку
6) Если такой строки еще нет в нашем map, то переходим к пункту 3, если есть, то к пункту 4

На выходе имеем файл без повторяющихся строк.
Re[2]: Фильтруй...
От: Кодт Россия  
Дата: 14.03.03 12:11
Оценка:
Здравствуйте, Всеволод, Вы писали:

В>На выходе имеем файл без повторяющихся строк.


Я так понял, что если строка повторяется — то ее вообще исключают (а не так, что оставляют один экземпляр).
Потому что дубликаты — это признак спама.
Перекуём баги на фичи!
Re[3]: Фильтруй...
От: uzzy Россия  
Дата: 14.03.03 12:31
Оценка:
Здравствуйте, Кодт, Вы писали:

К>Здравствуйте, Всеволод, Вы писали:


В>>На выходе имеем файл без повторяющихся строк.


К>Я так понял, что если строка повторяется — то ее вообще исключают (а не так, что оставляют один экземпляр).

К>Потому что дубликаты — это признак спама.

Если детально разобраться в ранее описанном алгоритме, то:
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 — спам
Что с ними делать — воля разарботчика

Удачи
Re[3]: Фильтруй...
От: Всеволод Россия  
Дата: 14.03.03 13:04
Оценка:
Здравствуйте, Кодт, Вы писали:

К>Здравствуйте, Всеволод, Вы писали:


В>>На выходе имеем файл без повторяющихся строк.


К>Я так понял, что если строка повторяется — то ее вообще исключают (а не так, что оставляют один экземпляр).

К>Потому что дубликаты — это признак спама.

Согласен !
Не четко понял изначальную постановку задачи — очистку списка, а не исключение повторов.
Re: Фильтруй...
От: mihailik Украина  
Дата: 14.03.03 15:51
Оценка:
A> Проблема в написании кода для отфильтровки файла от одинаковых строк.

Во временном списке нужно сохранять копии спама, чтобы уметь его распознать, если он ещё попадётся.

И каждую следующую строчку в файле сравниваешь со всеми "хорошими" строчками, и со всем спамом. Если совпадения не нашлось, считай текущую строчку "хорошей".

Если совпало с каким-то спамом, то просто выкидывай текущую.

Если совпало с "хорошей" строчкой, то выкидывай и "хорошую" строчку, и текущую, но не забудь добавить копию в список спама.
... << RSDN@Home 1.0 beta 6a >>
Re: Фильтруй...
От: DSD Россия http://911.ru/cv
Дата: 15.03.03 02:00
Оценка:
http://rsdn.ru/Forum/Message.aspx?mid=214783&amp;only=1
Автор: DSD
Дата: 15.03.03
--
DSD
Re: Фильтруй...
От: Apri  
Дата: 15.03.03 10:27
Оценка:
Спасибо всем. Особенно за идею с map'ом. Сам бы не додумался.
Re: Фильтруй...
От: Apri  
Дата: 15.03.03 14:04
Оценка:
Благодаря Евгению (mrhru) я нашел правильный (простой) способ для фильтровки, плиз:

unit main;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, Buttons, ComCtrls;

type
  Tbody = class(TForm)
    Open: TSpeedButton;
    Start: TSpeedButton;
    OpenDialog: TOpenDialog;
    SaveDialog: TSaveDialog;
    procedure OpenClick(Sender: TObject);
    procedure StartClick(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  body: Tbody;

implementation

{$R *.dfm}

procedure Tbody.OpenClick(Sender: TObject);
begin
 OpenDialog.Filter:='Текстовые файлы (*.txt)|*.TXT|Все файлы (*.*)|*.*|Лист файлы (*.lst)|*.lst';
 OpenDialog.Execute;
end;

procedure Tbody.StartClick(Sender: TObject);
var mass: TStringList;
begin
 mass:=TStringList.Create;
 mass.Sorted:=true;
 mass.Duplicates:=DupIgnore;
 try
    mass.LoadFromFile(OpenDialog.FileName);
    SaveDialog.Execute;
    mass.SaveToFile(SaveDialog.FileName);
 finally
    mass.Free;
 end;
end;

end.


Потом зажал всё это дело ASPack'ом и в рез. получилось 160 кило.
Re[2]: Фильтруй...
От: DSD Россия http://911.ru/cv
Дата: 17.03.03 02:21
Оценка:
Здравствуйте, 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 обойтись. Прописать создание формы ручками(из визуальщины тут всего две кнопки на форме), и размер бинарника будет еще на порядок меньше...
--
DSD
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.