Russian Qt Forum
Май 05, 2024, 23:56 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: Ищу: библиотеку для обработки текста  (Прочитано 8660 раз)
Admin
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 1988



Просмотр профиля
« : Сентябрь 28, 2008, 08:04 »

Не встречал ли кто библиотечку на С++ обладающую функциями:
 - подсчет количества слов в документе
 - количество повторяющихся слов
и так далее.
Записан
Tonal
Гость
« Ответ #1 : Сентябрь 30, 2008, 20:41 »

Э... что такое "документ"?
Да и вроде всё это делается элементарно: цикл да хеш...
Записан
Admin
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 1988



Просмотр профиля
« Ответ #2 : Октябрь 01, 2008, 11:49 »

документ у меня тут равно текст)

просто иногда полезные функции люди в библиотеки объединяют - может чё есть популярное))
Записан
Tonal
Гость
« Ответ #3 : Октябрь 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;
}
Количество повторов - вполне элементарная модификация... Улыбающийся
Записан
Admin
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 1988



Просмотр профиля
« Ответ #4 : Октябрь 01, 2008, 15:38 »

хитро
спасибо буду дейстовать в этом ключе)
Записан
ритт
Гость
« Ответ #5 : Январь 21, 2009, 08:18 »

довольно грубый алгоритм с плохим качеством анализа в общем случае. для языков, не использующих пробелы и знаки препинания, работать будет вообще ужасно.
Записан
Tonal
Гость
« Ответ #6 : Январь 21, 2009, 08:50 »

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

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

не спорю - для тривиальной задачи, где не требуется качественный анализ текста и высокая точность статистики, вполне подойдёт алгоритм на основе поиска цифро-букв/разделителей. но для более сложных задач, где качество анализа границ может играть приоритетную роль, приходится курить стандарты (unicode.org WB[tr29])
Записан
Tonal
Гость
« Ответ #8 : Январь 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)));
 }
};
 
« Последнее редактирование: Январь 22, 2009, 08:13 от Tonal » Записан
ритт
Гость
« Ответ #9 : Январь 21, 2009, 19:41 »

у меня используется такой же подход, как первый сниппет выше, но на QStringRef вместо пары итераторов - быстро и удобно. про функтор писал выше - от анализа границ на базе поиска "небукв" (грубо - RegExp("\\b\\w+\\b") ) отказаться мне пришлось почти сразу, т.к. качество ужасное.
Записан
Tonal
Гость
« Ответ #10 : Январь 22, 2009, 08:16 »

Ну я как-то тоже писал расширенный поиск для специализированных русских текстов, с учётом специальных сокращений и прочия. Улыбающийся
Кода там было конечно побольше, но идея та же - выделить слово из потока, обработать и перейти к следующему. Улыбающийся
Записан
ритт
Гость
« Ответ #11 : Январь 22, 2009, 08:58 »

то-то и оно, что русский текст...для русского языка довольно простые правила нахождения границ слов (не-цифробуквы) и минимум исключений из этих правил - можно и захардкодить.
например, в украинском языке уже появляется апостроф, в общем случае усложняющий анализ текста (т.к. сам уже не является цифробуквой).
а если говорить, например, про итальянский, то кроме апострофа появляются уже и графемы, и пляски с гласными/согласными после апострофа...
и так по нарастающей Грустный
в /* чёртовом */ таи даже не понятно где предложение заканчивается - не то, что слово...
а для японского вообще без поиска по словарю порой можно с ног на уши наанализировать
« Последнее редактирование: Январь 22, 2009, 09:01 от Константин » Записан
Tonal
Гость
« Ответ #12 : Январь 22, 2009, 13:00 »

Ну, приведённый алгоритм будет работать для любого "потокового" письма, где можно однозначно выделить начало слова и его окончание. Точнее то место, где не может начинаться следующее слово. Улыбающийся
Понятно, что если ему подсунуть кроссворд, то он обломается, но таких н-мерных текстов пока встречается не много, и обычно вопрос об их обработки стоит отдельно. Улыбающийся
Записан
ритт
Гость
« Ответ #13 : Январь 22, 2009, 14:07 »

мы говорим про алгоритм size_t word_count(const String& doc, FindWord find_word)? или всё же про функтор? а то я уже начинаю терять мысль...
если первое, то я и не спорил (говорю ж - сам подобной использую);
если про второе, то не вижу связи...разве что, по функтору на каждый языковой "скрипт"
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.089 секунд. Запросов: 22.