2014-02-17 4 views
3

Я анализирую поток данных пар двойных значений в std :: vector>. Я использую boost, поскольку я думаю, что он более эффективен. Мой код выглядит следующим образом.Эффективный разбор данных std :: stringstream в std :: vector <std :: vector <double>>

   std::stringstream tmp_stream;     
       typedef double data_type;    
       typedef ::std::vector <data_type> V_d; 
       // type below describes type of the container of all data 
       typedef ::std::vector <V_d> V_v_d; 
       // list container 
       //typedef ::std::list <V_d> V_v_d; 

       V_v_d data; 

       ::data_parser::Data_parser <V_v_d> data_parser; 
       data_parser (tmp_stream, data); 

Мой входной текстовый файл в формате {(132.181,0.683431), (136.886,0.988517), (137.316,0.504297), (133.653,0.602269), (150.86,0.236839) } Пара не обрабатывается правильно, и я получил пустую пару. В чем может быть проблема? Благодаря

+1

Вы собираетесь иметь чтобы показать нам ваш код data_parser. –

+0

Почему бы не использовать std :: pair ? – UldisK

+1

Не уверен, что это связано с вопросом, но если вы всегда будете работать с парами парных чисел, вероятно, было бы гораздо более эффективно использовать 'std :: vector >' для хранения , – icabod

ответ

5

Используя немного Boost Духа, вы можете использовать одну строку:

if (tmp_stream >> std::noskipws >> 
     qi::phrase_match((+qi::double_) % qi::eol, qi::blank, data)) 
{ 

и еще одну строку, чтобы отобразить результаты в виде бонуса:

std::cout << karma::format((karma::double_ % ", ") % karma::eol, data) << "\n"; 
} 

Примечание It руды inf, -inf, nan :)

S и ее это Live on Coliru:

#include <boost/spirit/include/qi.hpp> 
#include <boost/spirit/include/karma.hpp> 
#include <boost/spirit/include/qi_match.hpp> 

namespace qi = boost::spirit::qi; 
namespace karma = boost::spirit::karma; 

int main() 
{ 
    std::vector<std::vector<double>> data; 

    std::stringstream tmp_stream(
      "123 45 inf -inf nan .7e-99\n" 
      "42\n" 
      "-1"); 

    if (tmp_stream >> std::noskipws >> qi::phrase_match((+qi::double_) % qi::eol, qi::blank, data)) 
    { 
     std::cout << karma::format((karma::double_ % ", ") % karma::eol, data) << "\n"; 
    } 
} 

UPDATE Слегка адаптированного к вашей входной грамматике, я предлагаю разбор в вектор пара вместо:

#include <boost/fusion/adapted/std_pair.hpp> // handle std::pair 
#include <boost/spirit/include/qi.hpp> 
#include <boost/spirit/include/karma.hpp> 
#include <boost/spirit/include/qi_match.hpp> 

namespace qi = boost::spirit::qi; 
namespace karma = boost::spirit::karma; 

int main() 
{ 
    std::vector<std::pair<double, double>> data; 

    std::stringstream tmp_stream("{ (132.181,0.683431), (136.886,0.988517), (137.316,0.504297), (133.653,0.602269), (150.86,0.236839) }"); 

    if (tmp_stream >> std::noskipws >> qi::phrase_match(
        '{' 
       >> 
        ('(' >> qi::double_ >> "," >> qi::double_ >> ')') 
        % ',' 
       >> '}', 
       qi::space, data)) 
    { 
     std::cout << karma::format(karma::delimit(" ") [karma::auto_] % karma::eol, data) << "\n"; 
    } 
} 

который печатает: (см Live On Coliru

132.181 0.683 
136.886 0.989 
137.316 0.504 
133.653 0.602 
150.86 0.237 

Примечания Чтобы сделать вещи быстрее, рассмотреть не разбор образует поток, но с использованием

  • streambuf_iterator
  • основополагающих данные байт, если у вас в памяти в любом случае
+0

О выполнении вышеизложенного: [Как синтаксически разделить поплавки с пространственным разделением на C++?] (Http://stackoverflow.com/questions/17465061/how-to-parse-space-separated-floats-in-c- быстро/17479702 # 17479702) содержит контрольные показатели – sehe

Смежные вопросы