Russian Qt Forum

Программирование => Общий => Тема начата: Admin от Сентябрь 28, 2008, 08:04



Название: Ищу: библиотеку для обработки текста
Отправлено: Admin от Сентябрь 28, 2008, 08:04
Не встречал ли кто библиотечку на С++ обладающую функциями:
 - подсчет количества слов в документе
 - количество повторяющихся слов
и так далее.


Название: Re: Ищу: библиотеку для обработки текста
Отправлено: Tonal от Сентябрь 30, 2008, 20:41
Э... что такое "документ"?
Да и вроде всё это делается элементарно: цикл да хеш...


Название: Re: Ищу: библиотеку для обработки текста
Отправлено: Admin от Октябрь 01, 2008, 11:49
документ у меня тут равно текст)

просто иногда полезные функции люди в библиотеки объединяют - может чё есть популярное))


Название: Re: Ищу: библиотеку для обработки текста
Отправлено: Tonal от Октябрь 01, 2008, 12:41
Код:
size_t word_count(const string& doc) {
  string::const_iterator cur = doc.begin();
  string::const_iterator end = doc.end();
  size_t res = 0;
  while (cur != end) {
    cur = find_if(cur, end, isalpha);
    if (cur == end)
      break;
    ++res;
    cur = find_if(cur, end, not1(isalpha));
  }
  return res;
}
Количество повторов - вполне элементарная модификация... :)


Название: Re: Ищу: библиотеку для обработки текста
Отправлено: Admin от Октябрь 01, 2008, 15:38
хитро
спасибо буду дейстовать в этом ключе)


Название: Re: Ищу: библиотеку для обработки текста
Отправлено: ритт от Январь 21, 2009, 08:18
довольно грубый алгоритм с плохим качеством анализа в общем случае. для языков, не использующих пробелы и знаки препинания, работать будет вообще ужасно.


Название: Re: Ищу: библиотеку для обработки текста
Отправлено: Tonal от Январь 21, 2009, 08:50
Цитировать
Шутку понял. Смешно.
(с) Гоблин.
Изменение для таких экзотических языков вполне очевидно:
1. Если по символу мы можем определить принадлежит он слову или нет, то просто передаём в word_count функтор для такого определения и используем его вместо isalpha.
2. Если для определения границ слова требуется знать окрестные символы - то опять же пишем функтор, который находит первое слово в границах переданных итераторов, передаём его как дополнительный параметр и используем вместо find_if(cur, end, isalpha) и find_if(cur, end, not1(isalpha)).
Понятно, что при этом реализация чуток изменится, но алгоритм будет всё тот же. :)


Название: Re: Ищу: библиотеку для обработки текста
Отправлено: ритт от Январь 21, 2009, 09:14
к сожалению, этого недостаточно :(
пара примеров навскидку: don't, $10.99, K.I.S.S. - всего лишь три(!) слова для en_US, у которого одни из самых простых правил анализа. а сколько слов насчитает алгоритм в предыдущем посте?
если взять, к примеру, французский или итальянский (или тайваньский, например, где позволяеся смешивать слова разных языков, а пробелы не используются :) ), гемора уже много больше.

не спорю - для тривиальной задачи, где не требуется качественный анализ текста и высокая точность статистики, вполне подойдёт алгоритм на основе поиска цифро-букв/разделителей. но для более сложных задач, где качество анализа границ может играть приоритетную роль, приходится курить стандарты (unicode.org WB[tr29])


Название: Re: Ищу: библиотеку для обработки текста
Отправлено: Tonal от Январь 21, 2009, 11:27
Таки изменение из п(2) позволят применить любой из алгоритмов выделения слова.
Чтобы не было недопонимания, реализация может быть примерно такой:
Код
C++ (Qt)
template <class String, class FindWord>
size_t word_count(const String& doc, FindWord find_word) {
 typedef String::const_iterator Iter;
 Iter cur = doc.begin();
 Iter end = doc.end();
 size_t res = 0;
 while (cur != end) {
   pair<iter, iter> word = find_word(cur, end);
   if (word.first == end)
     break;
   ++res;
   cur = word.second;
 }
 return res;
}
 
При этом тип String должен иметь тип const_iterator, и функции begin(), end().
А тип FindWord должен иметь оператор () принимающий 2 итератора и возвращающий пару итераторов из начала и конца слова.

Для реализации первого алгоритма (который с isalpha) функтор будет такой:
Код
C++ (Qt)
template <class Iter>
struct IsAlphaWord {
 pair<Iter, Iter> operator() (Iter cur, Iter end) {
   Iter start = find_if(cur, end, isalpha);
   if (start == end)
     return make_pair(end, end);
   return make_pair(start, find_if(start, end, not1(isalpha)));
 }
};
 


Название: Re: Ищу: библиотеку для обработки текста
Отправлено: ритт от Январь 21, 2009, 19:41
у меня используется такой же подход, как первый сниппет выше, но на QStringRef вместо пары итераторов - быстро и удобно. про функтор писал выше - от анализа границ на базе поиска "небукв" (грубо - RegExp("\\b\\w+\\b") ) отказаться мне пришлось почти сразу, т.к. качество ужасное.


Название: Re: Ищу: библиотеку для обработки текста
Отправлено: Tonal от Январь 22, 2009, 08:16
Ну я как-то тоже писал расширенный поиск для специализированных русских текстов, с учётом специальных сокращений и прочия. :)
Кода там было конечно побольше, но идея та же - выделить слово из потока, обработать и перейти к следующему. :)


Название: Re: Ищу: библиотеку для обработки текста
Отправлено: ритт от Январь 22, 2009, 08:58
то-то и оно, что русский текст...для русского языка довольно простые правила нахождения границ слов (не-цифробуквы) и минимум исключений из этих правил - можно и захардкодить.
например, в украинском языке уже появляется апостроф, в общем случае усложняющий анализ текста (т.к. сам уже не является цифробуквой).
а если говорить, например, про итальянский, то кроме апострофа появляются уже и графемы, и пляски с гласными/согласными после апострофа...
и так по нарастающей :(
в /* чёртовом */ таи даже не понятно где предложение заканчивается - не то, что слово...
а для японского вообще без поиска по словарю порой можно с ног на уши наанализировать


Название: Re: Ищу: библиотеку для обработки текста
Отправлено: Tonal от Январь 22, 2009, 13:00
Ну, приведённый алгоритм будет работать для любого "потокового" письма, где можно однозначно выделить начало слова и его окончание. Точнее то место, где не может начинаться следующее слово. :)
Понятно, что если ему подсунуть кроссворд, то он обломается, но таких н-мерных текстов пока встречается не много, и обычно вопрос об их обработки стоит отдельно. :)


Название: Re: Ищу: библиотеку для обработки текста
Отправлено: ритт от Январь 22, 2009, 14:07
мы говорим про алгоритм size_t word_count(const String& doc, FindWord find_word)? или всё же про функтор? а то я уже начинаю терять мысль...
если первое, то я и не спорил (говорю ж - сам подобной использую);
если про второе, то не вижу связи...разве что, по функтору на каждый языковой "скрипт"