Russian Qt Forum

Qt => Общие вопросы => Тема начата: Igors от Мая 16, 2011, 13:09



Название: Простой разбор текста
Отправлено: Igors от Мая 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
Молодые люди любят писать все как можно короче и с применением мощных тулзов. Так что "прошу исполнить"  :)

Спасибо


Название: Re: Простой разбор текста
Отправлено: Пантер от Мая 16, 2011, 13:13
QString::split  в руки и вперед.


Название: Re: Простой разбор текста
Отправлено: Igors от Мая 16, 2011, 13:17
QString::split  в руки и вперед.
Прошу исполнить  :)


Название: Re: Простой разбор текста
Отправлено: Пантер от Мая 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 ());
 }
}
 
Типа так. Код не проверял.


Название: Re: Простой разбор текста
Отправлено: blood_shadow от Мая 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";
 
 

не проверял, но думаю идея ясна :)


Название: Re: Простой разбор текста
Отправлено: Igors от Мая 16, 2011, 13:54
Наверное просто
Код
C++ (Qt)
if (list.size() > 1...  // вместо !list.size()
 

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

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

Спасибо


Название: Re: Простой разбор текста
Отправлено: Пантер от Мая 16, 2011, 13:56
Копипаста. :) Поправил.
Igors, так ты как обычно потроллить зашел? В задании никакой конкретики не было, поэтому никаких проверок и оптимизаций я не делал.


Название: Re: Простой разбор текста
Отправлено: blood_shadow от Мая 16, 2011, 13:58
Нет ли чего-нибудь побыстрее?
Можно обойтись без сплита используя токо QRegExp, но они работают только с QString и к тому
же я не знаю насколько быстро


Название: Re: Простой разбор текста
Отправлено: blood_shadow от Мая 16, 2011, 14:05
я думаю можно файл порезать на количество кусков = количество ядер
и прорегекспить это все поточно
резать на куски по f который находить в близи сектора размер_куска / количество ядер


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


Название: Re: Простой разбор текста
Отправлено: Igors от Мая 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 выходных вектора
)
 
Прошу 



Название: Re: Простой разбор текста
Отправлено: GreatSnake от Мая 16, 2011, 14:26
Цитировать
Та так же и делаю, плюс isblank, isalpha и.т.п.  :)  Но ведь это ж "каменный век".
Чудес на свете не бывает - хочешь скорости пользуйся топором :)

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


Название: Re: Простой разбор текста
Отправлено: Пантер от Мая 16, 2011, 14:27
Что просил, то и получил. Хочешь скорости? Делай так, как сейчас делаешь.


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

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



Название: Re: Простой разбор текста
Отправлено: m_ax от Мая 16, 2011, 17:22

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

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

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

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

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

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

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


Название: Re: Простой разбор текста
Отправлено: Igors от Мая 16, 2011, 18:17
У меня всегда, почему то, после Ваших постов, остаётся стойкое впечатление, что Вы намерено ищете самые сложные решения задач, которые, вероятно, имеют более простые и логичные с точки зрения архитектуры решения.

Но это лично моё ИМХО)) Прошу по голове сильно не бить)
Ладно, сильно не буду  :)
Давайте называть вещи своими именами. Если мы хотим сачкануть - это нормально, во многих (очень многих) случаях разумно отпихнуться тем что предложил Пантер. Ничего плохого в этом нет, но не надо прикрывать ограниченность решения  громкими словами, "изяществом", "простотой", "логичностью" и.т.п. - если мы предлагаем дешевое но ограниченное решение - надо честно сказать об этом пользователю. Короче - врать не надо  :)

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

Стоит ли так "выжимать" если можно пойти на компромисс? Вопрос сложный. По поводу того же файла пользователь написал (вольный перевод мой)

- предыдущий импорт занимался этим файлом более 5 часов. Ваш вариант - 9 минут

Не скрою - приятно такой отзыв получить. С др. стороны низкоуровневой работы более чем хватает и во многих случаях размер куда скромнее. Нормально это обсудить  на форуме? Я считаю - нормально


Название: Re: Простой разбор текста
Отправлено: GreatSnake от Мая 16, 2011, 18:25
Цитировать
Давайте называть вещи своими именами.
Дык ёлы-палы...
Если бы ты сразу пояснил насчёт размера входных данных, я уверен, тебе бы про Qt никто бы и не заикнулся.
Ведь каждому понятно, что любой тулкит - это универсальный комбайн, который абсолютно не предусмотрен для таких задач.

Цитировать
предыдущий импорт занимался этим файлом более 5 часов. Ваш вариант - 9 минут
Мде, слов нет. Писаки, однако...


Название: Re: Простой разбор текста
Отправлено: Igors от Мая 16, 2011, 18:32
Дык ёлы-палы...
Если бы ты сразу пояснил насчёт размера входных данных, я уверен, тебе бы про Qt никто бы и не заикнулся.
Я этого не понимаю. Нормальные файлы - 100-200Мб (в среднем), бывают намного меньше, но бывают и намного больше. Достойно поддержать очень большие файлы - конечно престижно/лестно, но это часть задачи. Почему надо это специально оговаривать?  :)


Название: Re: Простой разбор текста
Отправлено: GreatSnake от Мая 16, 2011, 18:35
Цитировать
Я этого не понимаю. Нормальные файлы - 100-200Мб (в среднем), бывают намного меньше, но бывают и намного больше. Достойно поддержать очень большие файлы - конечно престижно/лестно, но это часть задачи. Почему надо это специально оговаривать?
Имхо, для текстовых файлов такой размер скорее исключение, чем правило.


Название: Re: Простой разбор текста
Отправлено: m_ax от Мая 16, 2011, 18:42
Igors, не обижайтесь, но мне просто интересно: Неужели есть такая жёсткая необходимость держать в памяти такие громадные объёмы?
Просто не представляю ситуации, где это действительно так необходимо.
Моё бы железо, при виде такого.. даже не знаю что и сказало бы))


Название: Re: Простой разбор текста
Отправлено: Igors от Мая 16, 2011, 19:08
Igors, не обижайтесь, но мне просто интересно: Неужели есть такая жёсткая необходимость держать в памяти такие громадные объёмы?
Просто не представляю ситуации, где это действительно так необходимо.
Моё бы железо, при виде такого.. даже не знаю что и сказало бы))
Ну пользователь - он понимает по-своему. Было ему обещано 150 Tb адресного  пр-ва? Было. Купил он памяти 8/16 Gb - честно купил (это кстати не так уж недорого). Ну вот мне и приходится отвечать почему небольшой (по его понятиям) объем (та всего-то 2-3 Gb) вызывает такие проблемы  :)
Господи, та всего-то неск. десятков (рельефных) лестниц и этажей (архитектурная сцена) - да о чем тут говорить?  :)

В конце-концов чем отличается профессиональный софт от "философии GNU" и "нашей малышь" - да очень немногим - тем что он честно "держит нагрузку" а если не может - сообщает


Название: Re: Простой разбор текста
Отправлено: Пантер от Мая 16, 2011, 21:46
Igors, ты слишком толстый тролль. Был конкретный вопрос, был конкретный ответ. Ты в первом посте ничего не говорил о производительности. Еще очень давно было сказано "Преждевременная оптимизация есть корень всех зол". Если тебе нужно "современное решение", то чем тебя не устраивает мой ответ? Если ты хочешь производительности, то какого ты вообще поднял этот вопрос??? Хочешь, чтобы все было супер-пупер - пиши на асме.


Название: Re: Простой разбор текста
Отправлено: Igors от Мая 17, 2011, 10:20
Igors, ты слишком толстый тролль. Был конкретный вопрос, был конкретный ответ. Ты в первом посте ничего не говорил о производительности. Еще очень давно было сказано "Преждевременная оптимизация есть корень всех зол". Если тебе нужно "современное решение", то чем тебя не устраивает мой ответ? Если ты хочешь производительности, то какого ты вообще поднял этот вопрос??? Хочешь, чтобы все было супер-пупер - пиши на асме.
- мой вес 100кг, я не считаю себя ни толстым, ни троллем  :)

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

- я не хочу "супер", хочу просто "нормально". Вот Вы лихо применили split - раз, 3 новых элемента QString распределились, потом удалились. Всего для 1 скромной строки десятки malloc/delete. Это что, по уму? Нет. это издевательство над машиной. Почему такая халтура считается нормой (мол, мне о скорости ничего не говорили)? Разбор текстовика - задача очень популярная, всем так или иначе ей заниматься приходилось, почему не может быть нормальных тулзов?

Хмм.. недавно boost пришлось поставить (впечатление очень хорошее), пошукаю там


Название: Re: Простой разбор текста
Отправлено: brankovic от Мая 17, 2011, 11:02
Хмм.. недавно boost пришлось поставить (впечатление очень хорошее), пошукаю там

спирит это мелко. И всё равно тормозить будет, уверен почти. Вам надо бизон. Годами люди писали оптимальные парсеры на бизоне, в том числе в VLSI, где файлы исчислялись гигабайтами уже лет 8 назад. Прямо в гугле набирайте bison tutorial.


Название: Re: Простой разбор текста
Отправлено: GreatSnake от Мая 17, 2011, 11:07
GNU bison = yacc


Название: Re: Простой разбор текста
Отправлено: lit-uriy от Мая 17, 2011, 11:07
>>Можно обойтись без сплита используя токо QRegExp, но они работают только с QString
>>и к тому же я не знаю насколько быстро

Ну да, с какой стати "регвыры" стали быстро работать? они скорость обработки в 10-ки раз снижают.


Название: Re: Простой разбор текста
Отправлено: Igors от Мая 17, 2011, 13:29
Прямо в гугле набирайте bison tutorial.
Намек понял, спасибо