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

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

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

Сообщений: 11445


Просмотр профиля
« : Май 16, 2011, 13:09 »

Добрый день

Никогда не пользовался regexp ни др. средствами для разбора текстовиков. Пишу по старинке (char * и пользую string/cstring). Хочу узнать как сделать "по-современному", вот пример (разбор obj файла)
Есть 3 массива целых чисел которые должны заполняться из строки начинающейся с "f". Возможны варианты:

Цитировать
// 1) есть данные для всех 3 массивов
f 148/154/146 340/155/327 342/156/336 150/157/148 

// 2) есть данные для первого и второго массивов
f 148/154 340/155 342/156 150/157     

// 3) есть данные для первого и последнего массивов
f 148//146 340//327 342//336 150//148 

// 4) есть данные только для первого массива
f 148 340 342 150       
Число элементов в строке любое, но в пределах строки они должны быть однообразны, напр так ошибка
Цитировать
f 148 340/155
Молодые люди любят писать все как можно короче и с применением мощных тулзов. Так что "прошу исполнить"  Улыбающийся

Спасибо
Записан
Пантер
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 5876


Жаждущий знаний


Просмотр профиля WWW
« Ответ #1 : Май 16, 2011, 13:13 »

QString::split  в руки и вперед.
Записан

1. Qt - Qt Development Frameworks; QT - QuickTime
2. Не используйте в исходниках символы кириллицы!!!
3. Пользуйтесь тегом code при оформлении сообщений.
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #2 : Май 16, 2011, 13:17 »

QString::split  в руки и вперед.
Прошу исполнить  Улыбающийся
Записан
Пантер
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 5876


Жаждущий знаний


Просмотр профиля WWW
« Ответ #3 : Май 16, 2011, 13:24 »

Код
C++ (Qt)
QString str;
 
QVector <int> a;
QVector <int> b;
QVector <int> c;
 
foreach (const QString& s, str.split (" ")) {
 const QStringList list = s.split ("/", QString::KeepEmptyParts);
 
 if (!list.isEmpty ()) {
   a.push_back (list [0].toInt ());
 }
 if (list.size () > 1 && !list [1].isEmpty ()) {
   b.push_back (list [1].toInt ());
 }
 if (list.size () > 2 && !list [2].isEmpty ()) {
   c.push_back (list [2].toInt ());
 }
}
 
Типа так. Код не проверял.
« Последнее редактирование: Май 16, 2011, 13:55 от Пантер » Записан

1. Qt - Qt Development Frameworks; QT - QuickTime
2. Не используйте в исходниках символы кириллицы!!!
3. Пользуйтесь тегом code при оформлении сообщений.
blood_shadow
Гость
« Ответ #4 : Май 16, 2011, 13:50 »

мой вариант:

Код
C++ (Qt)
QString codeStr;
QStringList capturedList;
if (codeStr.contains('/')
{
   QRegExp sep1Reg("(\\d*/\\d*)*");
   int pos = 0;
   while ((pos = sep1Reg.indexIn(codeStr, pos)) != -1)
   {
        capturedList.append(sep1Reg.cap(pos));
        pos += sep1Reg.matchedLength();
   }
}
else if (codeStr.contains('//')
{
   QRegExp sep2Reg("(\\d*//\\d*)*");
   int pos = 0;
   while ((pos = sep2Reg.indexIn(codeStr, pos)) != -1)
   {
        capturedList.append(sep1Reg.cap(pos));
        pos += sep2Reg.matchedLength();
   }
}
else
   capturedList = codeStr.split(' ', QString::SkipEmptyParts).removeFirst();
 
if (capturedList.count() != codeStr.split(' ', QString::SkipEmptyParts).count() - 1)
   qDebug() << "Error";
 
 

не проверял, но думаю идея ясна Улыбающийся
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #5 : Май 16, 2011, 13:54 »

Наверное просто
Код
C++ (Qt)
if (list.size() > 1...  // вместо !list.size()
 

Также никто не обещал что toInt успешно сконвертит в целое, ни того что элементы однообразны (программирование приятно только без контроля ошибок).

А главное - файлы могут быть очень велики. Вот напр вчера получил 1.7Gb, разбор длился уже неск. минут. При использовании "шикарного" split возможно будет десятки минут. Да и QString - хотя и терпимо но по-хорошему не нужно, разрешена только латиница. Нет ли чего-нибудь побыстрее?

Спасибо
Записан
Пантер
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 5876


Жаждущий знаний


Просмотр профиля WWW
« Ответ #6 : Май 16, 2011, 13:56 »

Копипаста. Улыбающийся Поправил.
Igors, так ты как обычно потроллить зашел? В задании никакой конкретики не было, поэтому никаких проверок и оптимизаций я не делал.
Записан

1. Qt - Qt Development Frameworks; QT - QuickTime
2. Не используйте в исходниках символы кириллицы!!!
3. Пользуйтесь тегом code при оформлении сообщений.
blood_shadow
Гость
« Ответ #7 : Май 16, 2011, 13:58 »

Нет ли чего-нибудь побыстрее?
Можно обойтись без сплита используя токо QRegExp, но они работают только с QString и к тому
же я не знаю насколько быстро
Записан
blood_shadow
Гость
« Ответ #8 : Май 16, 2011, 14:05 »

я думаю можно файл порезать на количество кусков = количество ядер
и прорегекспить это все поточно
резать на куски по f который находить в близи сектора размер_куска / количество ядер
Записан
GreatSnake
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2921



Просмотр профиля
« Ответ #9 : Май 16, 2011, 14:05 »

Цитировать
Молодые люди любят писать все как можно короче и с применением мощных тулзов.
имхо, "мощные тулзы" и 1.7Gb - вещи несовместимые.
Поэтому сам и ручками - mmap(), isdigit(), isspace() и т.д. и т.п. Улыбающийся
« Последнее редактирование: Май 16, 2011, 14:13 от GreatSnake » Записан

Qt 5.11/4.8.7 (X11/Win)
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #10 : Май 16, 2011, 14:21 »

имхо, "мощные тулзы" и 1.7Gb - вещи несовместимые.
Поэтому сам и ручками - isdigit(), isspace() и т.д. и т.п. Улыбающийся
Та так же и делаю, плюс isblank, isalpha и.т.п. Улыбающийся  Но ведь это ж "каменный век". Вот хотел посоветоваться с молодыми/продвинутыми - обозвали троллем  Плачущий

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

Код
C++ (Qt)
bool ParseFacet(            // возвращает false если ошибка
 const char * iStr,         // исходная строка, начинается с "f", варианты см. выше
 std::vector <int> oVec[3]   // 3 выходных вектора
)
 
Прошу 

Записан
GreatSnake
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2921



Просмотр профиля
« Ответ #11 : Май 16, 2011, 14:26 »

Цитировать
Та так же и делаю, плюс isblank, isalpha и.т.п.  Улыбающийся  Но ведь это ж "каменный век".
Чудес на свете не бывает - хочешь скорости пользуйся топором Улыбающийся

Цитировать
std::vector <int> oVec[3]   // 3 выходных вектора
Референс не забыл?
Записан

Qt 5.11/4.8.7 (X11/Win)
Пантер
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 5876


Жаждущий знаний


Просмотр профиля WWW
« Ответ #12 : Май 16, 2011, 14:27 »

Что просил, то и получил. Хочешь скорости? Делай так, как сейчас делаешь.
Записан

1. Qt - Qt Development Frameworks; QT - QuickTime
2. Не используйте в исходниках символы кириллицы!!!
3. Пользуйтесь тегом code при оформлении сообщений.
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #13 : Май 16, 2011, 15:10 »

Цитировать
std::vector <int> oVec[3]   // 3 выходных вектора
Референс не забыл?
Не забыл, эта запись тождественна
Код
C++ (Qt)
std::vector <int> * oVec;

Что просил, то и получил. Хочешь скорости? Делай так, как сейчас делаешь.
Значит так и запишем - тулзы с приемлемой производительностью Пантеру неизвестны  Улыбающийся

Записан
m_ax
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2094



Просмотр профиля
« Ответ #14 : Май 16, 2011, 17:22 »


Также никто не обещал что toInt успешно сконвертит в целое, ни того что элементы однообразны (программирование приятно только без контроля ошибок).

А главное - файлы могут быть очень велики. Вот напр вчера получил 1.7Gb, разбор длился уже неск. минут. При использовании "шикарного" split возможно будет десятки минут. Да и QString - хотя и терпимо но по-хорошему не нужно, разрешена только латиница. Нет ли чего-нибудь побыстрее?

Спасибо
Ну, ну))
Цитировать
Пантер, Ваш вариант, ну как бы это сказать.. ну "студенческий" что ли. Конечно преподаватель бы Вам поставил пятерку - и совершенно заслуженно, т.к. инструметарием Вы в совершенстве владеете (и я так никогда не сумею). Но меня интересует не "игра с классами в песочнице", а производительность и полный контроль ошибок. Уточним постановку

1.7 Gb данных на три вектора.. Если прикинуть: int =4 байт, 1Gb = 10^9 байт, три вектора, то по порядку величины размер одново вектора сколько выходит? 10^9 ?

Конечно, такие не детские решения держать в памяти не маленькие объемы залитые в стандартные вектора - это не игра в песочнице))

У меня всегда, почему то, после Ваших постов, остаётся стойкое впечатление, что Вы намерено ищете самые сложные решения задач, которые, вероятно, имеют более простые и логичные с точки зрения архитектуры решения.

Но это лично моё ИМХО)) Прошу по голове сильно не бить)
Записан

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

Arch Linux Plasma 5
Страниц: [1] 2   Вверх
  Печать  
 
Перейти в:  


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