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

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

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

К слову сказать, та часть функции которую вы замеряете у меня выполняется за 20 секунд. Однако вряд ли условия тестов одинаковы. От самого текста полагаю многое зависит и кроме того мой регесп удаляет весь мусор.
« Последнее редактирование: Июль 28, 2013, 21:27 от Spark » Записан
Spark
Гость
« Ответ #106 : Июль 28, 2013, 21:45 »

Полагаю здесь грубовато сделал:
Код
C++ (Qt)
       wordCount.remove(5,100);
       wordCount.remove(QRegExp("^[0]"));
       wordCount.remove(QRegExp("^[0]"));
       wordCount.remove(QRegExp("^[0]"));
       wordCount.remove(QRegExp("^[0]"));
Текст специфически и на выходе много слов. Потери в этом месте до 1,5 минут на моем тесте. В реальных текстах, вряд ли такое будет. Но все таки лучше сделать правильно.  Как оптимально удалить начальные нули в строковой переменной? Думаю можно было обойтись вообще без регеспа.
« Последнее редактирование: Июль 28, 2013, 21:48 от Spark » Записан
m_ax
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2095



Просмотр профиля
« Ответ #107 : Июль 29, 2013, 00:23 »

Полагаю здесь грубовато сделал:
Код
C++ (Qt)
       wordCount.remove(5,100);
       wordCount.remove(QRegExp("^[0]"));
       wordCount.remove(QRegExp("^[0]"));
       wordCount.remove(QRegExp("^[0]"));
       wordCount.remove(QRegExp("^[0]"));
Текст специфически и на выходе много слов. Потери в этом месте до 1,5 минут на моем тесте. В реальных текстах, вряд ли такое будет. Но все таки лучше сделать правильно.  Как оптимально удалить начальные нули в строковой переменной? Думаю можно было обойтись вообще без регеспа.

Возвёл очи к небу..
Записан

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

Arch Linux Plasma 5
Majestio
Гость
« Ответ #108 : Июль 29, 2013, 09:38 »

Spark, попробую еще раз на пальцах обсудить вашу задачу и ваше стремление научится программированию...

Общие вопросы

1) Заходя на форум с вопросами, научитесь слушать и заставьте себя слышать. Это не просто, но, в конечном счете, сэкономит вам кучу времени. Участники не пытаются вас "выставить дураком", напротив тратят свое время вам на помощь. Все когда-то начинали. Учится на своих ошибках - хорошо, но еще лучше - на ошибках других. А каждый совет участников - результат некогда экспериментов и в конечном счете потраченного времени. У вас его больше чем у других?
2) Поймите, что умение кодировать и умение программировать - это разные понятия. Вы их до сих пор путаете. Кодирование - это умение представить алгоритм на выбранном языке программирования (или без, крайне редкий случай) с учетом его синтаксиса. Программирование - это умение кодировать предварительно разработанные и оптимизированные алгоритмы с учетом постановки задачи. Пишу от себя, стараясь выхватить суть. Конечно еще есть нюансы (проектирование архитектуры, выбор средств и пр... опускаю).
3) Вам настоятельно советуют: четкое определение постановки задачи, отделение кода обработки от средств UI. Вы этому не предаете значение, это печально. Попробую написать аналогию, чтобы вы посмотрели на свои действия "нашими" глазами:

Парни, я не строитель, но у меня есть две доски, шурупы, отвертка и молоток. Надо соединить две доски. Я не умею, поэтому пока просто пытаюсь научится забивать шурупы. Беру шуруп, ставлю под угдом 45 градусов и забиваю его. Покритикуйте! Вам отвечают - нужно использовать другие методы соединения. То что вы делаете - не правильно, хотя и возможно. Вы закрываете уши и пытаетесь вбить шуруп под углом 90 градусов. Шуруп входит легче - у вас поднимается настроение ...

Но есть более правильный способ - шуруп ввинчивать отверткой! См п.1.

Частные вопросы

4) Постановка задачи? Ее так и нет ... Вы говорите  - один текст считается быстро, другой непонятно как.  Это должно быть в постановке задачи, к примеру важно определиться с кодировкой. Если кодировка с фиксированной длиной символа (к примеру win-1251) - ему свой алгоритм, если с переменной (к примеру, UTF-8) - ему свой. Конечно второй алгоритм сможет обрабатывать и первый вариант, но накладных расходов будет ну очень много. В случае вашей озвученной задачи, для текста с кодировкой с фиксированной длиной символа - регэкспы возможно вовсе выкинуть. Регэкспы - это средство поиска языковых конструкций, символы-разделители - ими являются, но их можно обрабатывать и быстрее (подход Old хорош, а для 8-битного текста можно еще на порядок ускорить, почти уверен). В нашем случае (захотели обрабатывать UTF-8) - это понятный и простой способ выделения слов в тексе с кодировкой с переменной  длиной символа.

5) Отделите "мухи от котлет". Рассово-правильно Улыбающийся выносить обработчики из основного кода UI - либо в виде классов (подход ООП), либо в виде библиотеки процедур (классический процедурно-ориентированный подход).

6) В плане обработки текста есть три основных подхода:

а) поиск целевого содержимого
б) чистка "мусора"
в) комбинация первых двух

Вы должны для себя определиться - чем занимаетесь вы в своем коде. Что в вашем случае предпочтительнее. Посмотрите на подход Igors - он поскромничал или решил не выдавать военную тайну)) Он предлагает класс-индексатор. Хотя не совсем правильно, имхо, с точки зрения реализации. Нужно выделять индексы слов в тексте без учета их содержимого (ибо повторяются), а если бы не повторялись - 2-ая трата памяти все равно. Индексация решает вопрос экономии памяти и скорости доступа. В качестве индекса должна использоваться пара (смещение начала слова в тексте,его длина). Если вам не дай боже придется анализировать 10-20 Гигабайтные тексты - то предлагаемые тут способы не прокатят ни разу. Нужно будет кусками читать текст в память (строить индекс, если потребуется дальнейшее обращение к словам), и обрабатывать по ходу сканирования (см. алгоритм Old, его принцип).

Если хотите более плотного обсуждения, с учетом, что будете прислушиваться - разместите свой проект на sourceforge или на git, будем "присматривать" ... если все же речь идет о выборе угла забивания шурупа - лично я дальше пасс.
« Последнее редактирование: Июль 29, 2013, 09:47 от Majestio » Записан
Spark
Гость
« Ответ #109 : Июль 29, 2013, 09:47 »

Ok! Переделал сортировку по частотности (заодно обнаружил, что нулей не хватало Улыбающийся). Критикуйте:
Код
C++ (Qt)
void MainWindow::bufferButtonSave()
{
   QTime tm;
 
   tm.start();
 
   QClipboard *clipboard = QApplication::clipboard();
   QString originalText = clipboard->text();
   QString countItemFullString;
   QString countItemString, countItemStringZero;
   QStringList itemList;
   int countItem(0);
   int countItemFull(0);
 
   qDebug() << "Reade Data: " << tm.elapsed();
 
   tm.start();
 
   originalText = originalText.toLower();
 
   qDebug() << "Data toLower: " << tm.elapsed();
 
   textory.clear();
 
   tm.start();
 
   itemList = originalText.split(QRegExp("[^a-z]"),QString::SkipEmptyParts);
   QHash<QString, int> frequencyMap;
   foreach (QString Item, itemList) ++frequencyMap[Item];
 
   qDebug() << "Data split [^a-z]: " << tm.elapsed();
 
   tm.start();
 
   QList<QString> frequencyList;
   QHashIterator<QString,int> Iter(frequencyMap);
   while(Iter.hasNext())
   {
       Iter.next();
       countItem = Iter.value();
       countItemString.setNum(countItem);
       countItemStringZero = countItemString;
       // ОРГАНИЗОВЫВАЕМ СОРТИРОВКУ
       if(countItem <10 )countItemStringZero = "00000" + countItemStringZero;
       if(countItem >9 && countItem <100 )countItemStringZero = "0000" + countItemStringZero;
       if(countItem >99 && countItem <1000 )countItemStringZero = "000" + countItemStringZero;
       if(countItem >999 && countItem <10000 )countItemStringZero = "00" + countItemStringZero;
       if(countItem >9999 && countItem <100000 )countItemStringZero = "0" + countItemStringZero;
       countItemFull = countItemFull + countItem;
       frequencyList.append(countItemStringZero + "_" + Iter.key() + "\t" + countItemString );
   }
 
   qDebug() << "Add zero: " << tm.elapsed();
 
   tm.start();
 
   qSort(frequencyList);
 
   textory.enableAdd( true );
 
   QString wordItem, wordCount;
 
   qDebug() << "Data sort: " << tm.elapsed();
 
   tm.start();
 
   foreach (QString itm, frequencyList)
   {
       itm.remove(0,7);
       textory.addItem( Textory::Item( 1, itm ) );
   }
 
   qDebug() << "Clear zero: " << tm.elapsed();
 
   tm.start();
 
   countItemFullString.setNum(countItemFull);
 
   ui.textoryPaneWidget->getTextoryLabel().setText( "Frequency list (" + countItemFullString + ")" );
 
   qDebug() << "Write name: " << tm.elapsed();
}
Текст на входе  не из простых. Вот вывод результата:

В скобках всего слов. Дальше оригинальных слов

Результат теста:
Reade Data:  8745
Data toLower:  310
Data split [^a-z]:  15249
Add zero:  757
Data sort:  93
Clear zero:  413837
Write name:  1

Против старого:
Reade Data:  8837
Data toLower:  308
Data split [^a-z]:  16566
Add zero:  544
Data sort:  89
Clear zero:  406562
Write name:  0

Как видим в общем то ничего не изменилось.
Закоментировал вывод:
Код
C++ (Qt)
       textory.addItem( Textory::Item( 1, itm ) );
Результат теста новой реализации:
Reloading all the tabs...
Reade Data:  9584
Data toLower:  323
Data split [^a-z]:  16117
Add zero:  772
Data sort:  91
Clear zero:  94

Результат старой реализации:
Reloading all the tabs...
Reade Data:  8949
Data toLower:  310
Data split [^a-z]:  16196
Add zero:  541
Data sort:  93
Clear zero:  759
Write name:  0


Да на порядок хуже Улыбающийся. Но абсолютно не важно. И тот и другой вариант меньше секунды.
Записан
Majestio
Гость
« Ответ #110 : Июль 29, 2013, 09:52 »

Ok! Переделал сортировку по частотности (заодно обнаружил, что нулей не хватало Улыбающийся). Критикуйте:
В Qt есть средства форматирования.
if(countItem <10 )countItemStringZero = "00000" + countItemStringZero;
if(countItem >9 && countItem <100 )countItemStringZero = "0000" + countItemStringZero;
if(countItem >99 && countItem <1000 )countItemStringZero = "000" + countItemStringZero;
if(countItem >999 && countItem <10000 )countItemStringZero = "00" + countItemStringZero;
if(countItem >9999 && countItem <100000 )countItemStringZero = "0" + countItemStringZero;
Решается одним оператором: QString QString::arg

Прочтите мой пост выше, пожалуйста Улыбающийся
Записан
Spark
Гость
« Ответ #111 : Июль 29, 2013, 09:56 »

По поводу очередных нравоучений. Я все понимаю и внемлю. Это раз!
Не без вашей помощи. Но помощь процентов на 80 заключается в постановке ответа - гомнокод, быдлокод (честно говоря у меня еле язык поворачивается, ну раз так принято...). Во всяком случае для меня это означает одно - можно лучше и я переделываю. Это двас!
Моя программа уже лучше работает чем аналоги профи, за плечами которых лет по пять (напомню у меня за плечами 2 месяца). Это трис!
Еще непонятки есть по этому вопросу?
Вы из меня хотите профи сделать за пару месяцев? В кокой то мере удается Улыбающийся. И я за это благодарен.
Записан
Spark
Гость
« Ответ #112 : Июль 29, 2013, 09:58 »

Решается одним оператором: QString QString::arg
Такой ответ мне больше по душе. Пользы от него намного больше, чем от нравоучений.
Спасибо!

P.S. Вы же видите, что двигаюсь я попорядку. Бессмысленно в моем положении охватывать все сразу, кода я плохо знаю инструментарий. Сделал плохо, но сделал. Подсказали, что можно лучше, делаем лучше. И .т.д.
« Последнее редактирование: Июль 29, 2013, 10:05 от Spark » Записан
Majestio
Гость
« Ответ #113 : Июль 29, 2013, 10:13 »

Вы из меня хотите профи сделать за пару месяцев?
Не в коей мере - это зависит только от вас.
Просто есть, и я уже описал, базовые принципы - игнорирование которых есть моветон (можно написать и быдлокод). Зачем вам начинать неправильно, если вам дают ГОТОВЫЕ РЕКОМЕНДАЦИИ?

Это даст:

понятность реализации
скорость выполнения
экономию накладных расходов
возможно удобное повторное использование кода

В чем суть вашего "игнора"? Если скажите что нравиться "ходить по граблям" - я пойму.
А так просто в непонятках.
Записан
Majestio
Гость
« Ответ #114 : Июль 29, 2013, 10:18 »

P.S. Вы же видите, что двигаюсь я попорядку.

В том то и дело - вы двигаетесь и это видно.
Но важные вещи игнорируете и копаетесь в мелочах.

Это расточительно по времени - да и несколько неправильно с точки зрения форумного общения. Тут принято предлагать "как", а не анализировать в каком именно операторе или блоке кода вы накосячили.

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

Сообщений: 11445


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

Ok! Переделал сортировку по частотности (заодно обнаружил, что нулей не хватало Улыбающийся). Критикуйте:
Уже критиковали. Как сделать сортировку нормально - код приводили. Хотите делать какую-то свою сортировку (через склейку строк) - на здоровье, но это никому не интересно, потому что просто хуже, длиннее и  медленнее. Зачем Вы уже третий раз навязываете это бесполезное обсуждение?

Сформулируйте задачу, выделите класс - тогда может поговорим. А будете упираться и приводить очередной MainWindow - на том же месте и останетесь.
Записан
Spark
Гость
« Ответ #116 : Июль 29, 2013, 11:13 »

Как сделать сортировку нормально - код приводили.
В общем то мой код работает быстро. Но хотелось бы увидеть тот код который предлагали.  Ну а замеров тут столько наделано, что не удивительно, что я что то пропустил, тем более без пояснений, что это именно ответ на мой вопрос.
Записан
Spark
Гость
« Ответ #117 : Июль 29, 2013, 11:14 »

P.S. Вы же видите, что двигаюсь я попорядку.

В том то и дело - вы двигаетесь и это видно.
Но важные вещи игнорируете и копаетесь в мелочах.

Это расточительно по времени - да и несколько неправильно с точки зрения форумного общения. Тут принято предлагать "как", а не анализировать в каком именно операторе или блоке кода вы накосячили.

Ладно, дело ваше. Только вы же должны понимать - если форумчанин вам ответит, вы решите что это не важно, начнете "доделывать" свое ... Второй раз отвечать желание пропадет, ибо впустую.
Однако, за основу я взял ваш вариант.
На остальные вопросы я не получил ответа и свои варианты предложил. Опять же не получил критических замечаний, ни иные способы решения поставленной задачи.
Все, что мимо поставленной задачи, я записываю.
Я пояснял, что взял исходники и добавляю свой функционал. Следовательно зажат рамками тех кто делал программу до меня. Приходится разбираться как она устроена изнутри.
И могу сказать, что на сегодня уже могу поправить то, что накосячили до меня программисты со стажем лет пять, а так же снять ограничения в связи с бывшей малой скоростью обработки. Мой код работает быстрее на порядок.

И все таки ближе к делу. Глядя на последний предложенный код, видно, что расчленение на слова происходит относительно долго. Можно ли ускорить процесс? Хочу двигаться в этом направлении. Как только код будет наиболее быстр, так сразу попробую отделить мух от борща. Но прежде хотелось бы узнать, а прирост в скорости это даст?
Записан
Majestio
Гость
« Ответ #118 : Июль 29, 2013, 11:16 »

И результаты у меня такие (release)

Код
Bash
Old: 15629 15211
Majestio: 17590 15211
m_ax: [b]9028[/b]  15211
 
Хе, хе Подмигивающий

Ланна, простите за оффтопик  Показает язык ...

Код
Perl
#!/usr/bin/perl
 
use Time::HiRes qw(gettimeofday);
 
open(FD,"test.txt") || die "Shit happiness!";
$T = join("",<FD>);
close(FD);
 
$Start = gettimeofday();
 
for($I=0; $I<100; $I++) {
 map { $F{$_}++ } split(/[\s\.,:;\-()]+/,$T);
}
 
$Elapsed = gettimeofday() - $Start;
 
print "<br>Elapsed: $Elapsed";
 

Результат: 3484 Смеющийся (в ТЗ речи об UI не было ... к разговору об регэкспах ....)
Записан
Majestio
Гость
« Ответ #119 : Июль 29, 2013, 11:24 »

И все таки ближе к делу. Глядя на последний предложенный код, видно, что расчленение на слова происходит относительно долго. Можно ли ускорить процесс?

1) Откажитесь от кодировок и сделайте для одной 8-битной с фиксированной длинной символа (к примеру, win-1251)
2) Откажитесь от регэкспов, работайте с символами (например через switсh)
3) Откажитесь от манипуляции с QString в качестве хранителя текста - используйте *char
4) Частоты заносите в QHash

По поводу п.3 - просто подозрение,  все равно будут преобразования для добавления в QHash, проверить бы ...
Записан
Страниц: 1 ... 6 7 [8] 9 10 ... 18   Вверх
  Печать  
 
Перейти в:  


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