![]() |
Расчленяем почту
Привет! Помоги решить задачу (нужен подход):
Есть электронное письмо. Нужно:
Теоретически письмо может быть составлено любым почтовым клиентом. С визиткой ещё как-то можно придумать, например искать по списку "Best regards" не дальше N слов от e-mail отправителя. С остальным как-то затрудняюсь |
первый эксперимент. В принципе нормально себя показывает когда искомая строка гарантировано есть в тексте. Когда нет или содержит небольшие ошибки, то находит не всегда то, что хотелось бы. Хотя придраться сложно, текст действительно похож. И появилась мысль, как выдирать репосты (по сути репост - это плагиат)
Код:
#include <iostream> ответ получается понятней, когда spread_size = 1 исходный файл - text.txt что искать - sample.txt понимает английские и русские буквы в 1251 |
В общем, придумал способ находить цитаты (и подписи, если считать их цитатами), второе приближение.
Задача №1: найти все репосты. Решение: ищем общую последовательность максимальной длины, помечаем, вырезаем, разделяем найденной частью один из списков на два. Для каждой получившихся частей повторяем задачу заново. Задача №2: в 2-х списках строк найти общую последовательность максимальной длины. Решаем как задачу динамического программирования. Пусть список sample - тот, из которого ищем цитаты, text - тот в котором ищем. Управление: позиция в sample, с которой начинается цитата. Состояние: лучшая длина + начало цитаты, текущая длина. Т.о. возможен однопроходной алгоритм, количество сравнений - N*M, где N и M - длины списков. Если считать цитаты достаточно редкими, то можно уменьшить расходуемую память и ускорить обработку за счёт использования хеш-мапов строк на состояния. Если требуется нечёткое сравнение, то строки предварительно обрабатываются канонанизатором (т.е. перекодируются, выкидываются части, не имеющие значения) Вероятно можно переформулировать задачу так, чтобы на выходе сразу получался разбитый цитатами список. Какие ещё могут быть варианты решения задачи? |
Цитата:
|
Честно говоря, я думал что значки ">>" проставляет почтовый клиент. В письмах, которые я взял для анализа, я обнаружил кроме html-ных частей ещё текстовые копии (для старых почтовых клиентов), там такие значки проставляются. Но не со всеми письмами прокатывает.
В общем, я провёл эксперименты со вторым приближением. За образец взял два "очень длинных письма" - два рассказа братьев Стругацких, с разделением по словам, а не по строкам, у слов отрезаются окончания (такой канонизатор). Время измеряно для отладочной сборки. Код:
longest match (10): библиотек ладошек http palm com ладошк солнц карманны компьютеры аркад Делаем улучшение(1): составляем map<string,unsigned> из слов. В качестве слов используем указатели на слова, сравнение указатеелй как чисел (в итоге полностью исключаем сравнение слов, имеем идеальный хеш), но можем потерять на загрузке (составление словаря). Код:
loaded at 0 secs Другое улучшение(2): Теперь считаем цитаты редкими и составляем map слова на список его вхождений. Убираем хеш, т.е. снова сравниваем строки. Код:
loaded at 0 secs Теперь решаем задачу "найти все цитаты". Для этого заметим, что мы их фактически все и находим, находя максимальную. Отличие только в том, как производится выбор лучшего решения из последнего состояния. Вместо вывода на экран самой длинной цепочки, мы выводим все цепочки в порядке убывания длины. Причём после вывода цепочки удаляем её состояния, избегая тем самым пересечения. Любопытно выглядят цепочки из 3-5 слов. По сути это любимые выражения автора, стиль его разговора. Можно использовать для анализа личности (сравнив несколько писем). Мне понравилась фраза (если правильно помню) "вот уже пять лет как". т.о. полная задача решена за лучшее время меньше 1 сек. Если считать подписи цитатами подписей, проверять цитирование письмом не только прошлого письма, но и подписи отправителя, то вроде как задача решается. Внимание, вопрос для разработчиков архиваторов: что будет, если найти все цитаты письма самим себя (по сути все повторения)?.... Правильно! письмо полностью себя цитирует! Ещё одно возможное применение - diff, который находит не только отличия, но и копипасты. В принципе задачу можно считать решённой; остаются вопросы с ложными срабатываниями, когда за цитирование будет принят плохой стиль письма. |
Примеры схожих в двух произведениях фраз:
Код:
longest match (5): разобра можн был тольк отдельны |
Время: 20:18. |
Время: 20:18.
© OSzone.net 2001-