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

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

Страниц: 1 ... 5 6 [7] 8 9 ... 18   Вниз
  Печать  
Автор Тема: Регулярное выражение с QString  (Прочитано 161154 раз)
Spark
Гость
« Ответ #90 : Июль 27, 2013, 21:17 »

И все таки несмотря ни на, что я знаю над чем именно сейчас мне думать. Лучше ближе к делу, к конкретно поставленному вопросу. Сейчас я работаю над вполне стандартным функционалом для программ данной категории.

Поточнее засек время. почти 6 миллионов слов обработала за 10 минут.
« Последнее редактирование: Июль 27, 2013, 21:20 от Spark » Записан
m_ax
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2095



Просмотр профиля
« Ответ #91 : Июль 27, 2013, 22:04 »

И все таки несмотря ни на, что я знаю над чем именно сейчас мне думать. Лучше ближе к делу, к конкретно поставленному вопросу. Сейчас я работаю над вполне стандартным функционалом для программ данной категории.

Поточнее засек время. почти 6 миллионов слов обработала за 10 минут.

Вот в том то и оно..
К вашему сведению, в файле test.txt, что прилагался к тестам (см. посты выше) более шести миллионов слов  и обработка там занимала (с учётом 100 кратного повторения) - секунды, т.е., фактически, по времени у вас на три порядка (в 1000 раз!) медленнее..      
Делайте выводы..
« Последнее редактирование: Июль 27, 2013, 22:33 от m_ax » Записан

Над водой луна двурога. Сяду выпью за Ван Гога. Хорошо, что кот не пьет, Он и так меня поймет..

Arch Linux Plasma 5
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #92 : Июль 27, 2013, 22:26 »

Какие же новые сущности я наплодил? Улыбающийся Не лучше ли вместо копий слов держать ссылки на них? Вот Вам и оптимизация: по памяти вдвое, по скорости тоже будет прилично. Это "не мелочь по карманам тырить". А главное - мы всегда знаем место слова в исходном тексте, ценная возможность. Кстати в дусте идея та же - их итератор очень похож на QStringRef (ну или наоборот).

Поясните пожалуйста, на какие строки будут держаться ссылки в хеше?
Код
C++ (Qt)
struct CData {
...
QHash <QStringRef, int> mFrequency;  // возможно строить по запросу
};
 

Вот есть текст:
aaa bbb ccc aaa ddd aaa

На какую из этих строк "aaa" будет ссылка в хеше?
Записан
kambala
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4747



Просмотр профиля WWW
« Ответ #93 : Июль 27, 2013, 22:46 »

И все так по существу вопроса. Фактически надо решить последнюю задачу.
Как сделать, что бы отрабатывался такой регесп:
Код
C++ (Qt)
   originalText.replace(QRegExp("[а-я]"), "");
С английским, естественно, нет проблем и это работает:
Код
C++ (Qt)
   originalText.replace(QRegExp("[a-z]"), "");
проблема в несоответствии кодировки исходников и обрабатываемого текста. чтобы этого избежать, задавай в коде русские буквы (да и вообще все не-ASCII символы) их unicode-кодом.
Записан

Изучением C++ вымощена дорога в Qt.

UTF-8 has been around since 1993 and Unicode 2.0 since 1996; if you have created any 8-bit character content since 1996 in anything other than UTF-8, then I hate you. © Matt Gallagher
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #94 : Июль 28, 2013, 03:59 »

На какую из этих строк "aaa" будет ссылка в хеше?
Ну "не мудрствуя лукаво" - на первую. Хотя тут есть гораздо более интересные ходы. Напр вообще без ассоциативного контейнера
Код
C++ (Qt)
struct CTextAnalyzer {  // имя посочнее
...
private:
 QString mSource;
 QVector <QStringRef> mWord;   // слова по порядку
 QVector <QStringRef> mFreqWord; // слова по частоте
 QVector <int> mFreqEntry;  // индекс слова в mFreqWord
};
И наверное QStringRef избыточен, лучше просто typedef QPair <int, int> ...
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #95 : Июль 28, 2013, 04:04 »

И все таки несмотря ни на, что я знаю над чем именно сейчас мне думать.
Пока Вы будете лепить все в MainWindow - это "мартышкин труд", ну никак не более того.
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #96 : Июль 28, 2013, 06:41 »

Хотя тут есть гораздо более интересные ходы.
Вначале нужно разобраться, какая крутая обработка текста вообще планируется, хотя бы основные направления.
Записан
Spark
Гость
« Ответ #97 : Июль 28, 2013, 15:08 »

Основные вопросы решены (сортировка по частоте, оставить английский). Настало время оптимизации и выбора более лучшего алгоритма. Критикуйте:
Код
C++ (Qt)
void MainWindow::bufferButtonSave()
{
   QClipboard *clipboard = QApplication::clipboard();
   QString originalText = clipboard->text();
   QString countItemFullString;
   QString countItemString;
   QStringList itemList;
   int countItem(0);
   int countItemFull(0);
 
   originalText = originalText.toLower();
   originalText.replace(QRegExp("\\W"), " ");
   originalText.replace(QRegExp("\\d"), " ");
   originalText.replace(QRegExp("_"), " ");
   // УБИРАЕМ РУССКИЙ
   originalText.replace(QRegExp(QString::fromUtf8("[а-яё]")), "");
 
   textory.clear();
 
   itemList = originalText.split(QRegExp("\\s+"),QString::SkipEmptyParts);
   QMap <QString, int> frequencyMap;
   foreach (QString Item, itemList) ++frequencyMap[Item];
 
   QList<QString> frequencyList;
   QMapIterator<QString,int> Iter(frequencyMap);
   while(Iter.hasNext())
   {
       Iter.next();
       countItem = Iter.value();
       countItemString.setNum(countItem);
       // ОРГАНИЗОВЫВАЕМ СОРТИРОВКУ
       if(countItem <10 )countItemString = "0000" + countItemString;
       if(countItem >9 && countItem <100 )countItemString = "000" + countItemString;
       if(countItem >99 && countItem <1000 )countItemString = "00" + countItemString;
       if(countItem >999 && countItem <10000 )countItemString = "0" + countItemString;
       countItemFull = countItemFull + countItem;
       frequencyList.append(countItemString + "_" + Iter.key() );
   }
 
   qSort(frequencyList);
 
   textory.enableAdd( true );
 
   QString wordItem, wordCount;
 
   foreach (QString itm, frequencyList)
   {
       wordItem = itm;
       wordCount = itm;
       wordItem.remove(0,6);
       wordCount.remove(5,100);
       wordCount.remove(QRegExp("^[0]"));
       wordCount.remove(QRegExp("^[0]"));
       wordCount.remove(QRegExp("^[0]"));
       wordCount.remove(QRegExp("^[0]"));
       textory.addItem( Textory::Item( 1, wordItem + "\t" + wordCount ) );
   }
 
   countItemFullString.setNum(countItemFull);
 
   ui.textoryPaneWidget->getTextoryLabel().setText( "Frequency list (" + countItemFullString + ")" );
}
Есть небольшой косячок. Если взять смешанный текст из текстового редактора то все Ok! Но например, если из самого QT взять смешанный текст и отправить на обработку, то то-же все Ok! Но если для сравнения сначала отправляю в подобную эталонную программку, а затем этот же текст на свою обработку, то уже русские не удаляются и притом в крягозябрах. Может это и не страшно, но хотелось бы исключить такой подвох.



И все таки несмотря ни на, что я знаю над чем именно сейчас мне думать. Лучше ближе к делу, к конкретно поставленному вопросу. Сейчас я работаю над вполне стандартным функционалом для программ данной категории.

Поточнее засек время. почти 6 миллионов слов обработала за 10 минут.

Вот в том то и оно..
К вашему сведению, в файле test.txt, что прилагался к тестам (см. посты выше) более шести миллионов слов  и обработка там занимала (с учётом 100 кратного повторения) - секунды, т.е., фактически, по времени у вас на три порядка (в 1000 раз!) медленнее..      
Делайте выводы..
Я не писал, что мой код оптимален. Ткните пальцем какой из предложенных алгоритмов выбрать и почему, попробую воспроизвести в реальных условиях (не в тестовых), со всей последующей обработкой, вот тогда смогу оценить по достоинству.
А пока же могу сказать, что моя функция работает лучше, чем та которую брал за эталон. Правда там тоже видно начинающий делал, но в своем роде аналогов то больше и нет особо.
« Последнее редактирование: Июль 28, 2013, 17:06 от Spark » Записан
Spark
Гость
« Ответ #98 : Июль 28, 2013, 17:31 »

Второй способ убрать Русский.
Код
C++ (Qt)
   // УБИРАЕМ ВСЕ КРОМЕ АНГЛИЙСКОГО
   originalText.replace(QRegExp(QString::fromUtf8("[a-z]")), " ");
Вроде как полностью решает проблему с кодировкой. И вообще получается в один проход можно сразу разделить весь текст.
Записан
Spark
Гость
« Ответ #99 : Июль 28, 2013, 19:27 »

Не поленился проверил свою реализацию и реализацию эталон (чужую программку), которую юзал раньше:
Всего слов:
4352212 - всего слов насчитала моя реализация
4352217 - всего слов насчитал эталон
15 минут - вычисляла моя реализация
70 минут - вычислял эталон

Однако, эталон без сортировки ставит слова в порядке поступления, что есть хорошо. То же делал мой первый вариант (скорость не проверял, но видимо алгоритм схож).
Моя программа сортирует (мапа сортирует сразу) и это плохо. Если не удастся нормально реализовать этот режим, то придется как то совмещать два подхода.
« Последнее редактирование: Июль 28, 2013, 19:33 от Spark » Записан
kambala
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4747



Просмотр профиля WWW
« Ответ #100 : Июль 28, 2013, 19:56 »

QHash не сортирует
Записан

Изучением C++ вымощена дорога в Qt.

UTF-8 has been around since 1993 and Unicode 2.0 since 1996; if you have created any 8-bit character content since 1996 in anything other than UTF-8, then I hate you. © Matt Gallagher
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #101 : Июль 28, 2013, 20:17 »

Не поленился проверил свою реализацию и реализацию эталон (чужую программку), которую юзал раньше:
Всего слов:
4352212 - всего слов насчитала моя реализация
4352217 - всего слов насчитал эталон
15 минут - вычисляла моя реализация
70 минут - вычислял эталон
Вот об этом m_ax и говорит, это ужасный результат.
В наших тестах 6107300 слов обрабатываются за чуть более 5 секунд (на моей машине).
Записан
Spark
Гость
« Ответ #102 : Июль 28, 2013, 20:20 »

Не поленился проверил свою реализацию и реализацию эталон (чужую программку), которую юзал раньше:
Всего слов:
4352212 - всего слов насчитала моя реализация
4352217 - всего слов насчитал эталон
15 минут - вычисляла моя реализация
70 минут - вычислял эталон
Вот об этом m_ax и говорит, это ужасный результат.
В наших тестах 6107300 слов обрабатываются за чуть более 5 секунд (на моей машине).

Я полагаю наши тексты отличаются. Но сейчас буду экспериментировать и смотреть различия между вашими реализациями и моей.
Записан
Spark
Гость
« Ответ #103 : Июль 28, 2013, 20:23 »

QHash не сортирует
Спасибо. Это хорошая новость.

Расставил таймеры. Проверил где наибольшие тормоза:
Код
C++ (Qt)
   originalText = originalText.toLower();
 
   qDebug() << tm.elapsed();
 
   tm.start();
 
   // УБИРАЕМ РУССКИЙ
   originalText.replace(QRegExp("[^a-z]"), " ");
   originalText.replace(QRegExp("_"), " ");
 
   qDebug() << tm.elapsed();
 
   tm.start();
 
   textory.clear();
 
   itemList = originalText.split(QRegExp("\\s+"),QString::SkipEmptyParts);
   QMap <QString, int> frequencyMap;
   foreach (QString Item, itemList) ++frequencyMap[Item];
 
   qDebug() << tm.elapsed();
 
   tm.start();
 
   QList<QString> frequencyList;
   QMapIterator<QString,int> Iter(frequencyMap);
   while(Iter.hasNext())
   {
       Iter.next();
       countItem = Iter.value();
       countItemString.setNum(countItem);
       // ОРГАНИЗОВЫВАЕМ СОРТИРОВКУ
       if(countItem <10 )countItemString = "0000" + countItemString;
       if(countItem >9 && countItem <100 )countItemString = "000" + countItemString;
       if(countItem >99 && countItem <1000 )countItemString = "00" + countItemString;
       if(countItem >999 && countItem <10000 )countItemString = "0" + countItemString;
       countItemFull = countItemFull + countItem;
       frequencyList.append(countItemString + "_" + Iter.key() );
   }
 
   qDebug() << tm.elapsed();
 
   tm.start();
 
   qSort(frequencyList);
 
   textory.enableAdd( true );
 
   QString wordItem, wordCount;
 
   qDebug() << tm.elapsed();
 
   tm.start();
 
   foreach (QString itm, frequencyList)
   {
       wordItem = itm;
       wordCount = itm;
       wordItem.remove(0,6);
       wordCount.remove(5,100);
       wordCount.remove(QRegExp("^[0]"));
       wordCount.remove(QRegExp("^[0]"));
       wordCount.remove(QRegExp("^[0]"));
       wordCount.remove(QRegExp("^[0]"));
       textory.addItem( Textory::Item( 1, wordItem + "\t" + wordCount ) );
   }
 
   qDebug() << tm.elapsed();
Результаты:
316
919942
12435
542
110
103253
Картина ясная. Будем думать.
Записан
Spark
Гость
« Ответ #104 : Июль 28, 2013, 20:55 »

Как то не так все просто получается.
Сократил время работы самой функции до 2х минут. Убрал все регеспы, оставил только сплит:
Код
C++ (Qt)
   itemList = originalText.split(QRegExp("[^a-z]"),QString::SkipEmptyParts);
При этом вывод результатов на экран все все таки задерживается еще на 5 минут.
Итого 7 минут. Это лучше, и эти 5 минут уже не от меня зависят. Попробую пошаманить еще над своим кодом.
Записан
Страниц: 1 ... 5 6 [7] 8 9 ... 18   Вверх
  Печать  
 
Перейти в:  


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