2016-09-09 5 views
1

У меня была аналогичная проблема при кодировании на Java, и в этом случае я использовал str1.split (","), чтобы изменить целую цепочку в массив из них.Каков наиболее эффективный способ превратить цепочку целых чисел, например. (1,5,73,2) в массив целых чисел?

Есть ли способ на C++, который имеет аналогичную функцию для метода разделения Java, или лучший способ использовать цикл for для достижения тех же целей?

+2

Посмотрите на 'станд :: istringstream 'и его различные' >> 'операторы для синтаксического анализа. Вы можете даже упростить это, используя 'std :: copy()'/'std :: copy_n()' с помощью 'std :: istream_iterator' и' std :: back_inserter' для синтаксического анализа и вставки целых чисел в 'std: : vector' или другой контейнер, который вы выберете, не указав вручную код фактической логики цикла. –

+1

Ну, способ, которым вы упоминали в Java, по-прежнему является массивом String, а не целым числом –

+1

[см. Здесь] (http://stackoverflow.com/questions/236129/split-a-string-in-c) для того, как разделите строку. Затем преобразуйте каждую строку в целое. –

ответ

1

Использование std::istringstream, чтобы разобрать этот вариант, было бы, безусловно, более удобным.

Но вопрос в том, что будет наиболее «эффективным». И, к лучшему или к худшему, #include <iostream> не известен своей эффективностью.

Простой цикл for будет трудно превзойти, ради эффективности.

Предполагая, что входные данные не содержат каких-либо пробелов, только запятые и цифры:

std::vector<int> split(const std::string &s) 
{ 
    std::vector<int> r; 

    if (!s.empty()) 
    { 
     int n=0; 

     for (char c:s) 
     { 
      if (c == ',') 
      { 
       r.push_back(n); 
       n=0; 
      } 
      else 
       n=n*10 + (c-'0'); 
     } 
     r.push_back(n); 
    } 
    return r; 
} 

Смело бенчмарка это снова любой istream или istream_iterator основанное подход.

+0

Возможно, это означало« эффективную »с точки зрения времени кодирования или строки кода –

+0

Ваше решение вызывает неопределенное поведение в случае переполнения целых чисел. –

+0

Поскольку' push_back' может быть дорогостоящим, вероятно, было бы более эффективно рассчитывать запятыми и do 'r.reserve (number_of_commas + 1);' Кроме того, целые числа могут иметь ведущий «-» (он не записывал целые числа без знака). – user31264

0

Если НУ уже известно количество элементов в строке, то самый быстрый способ заключается в использовании с функцией sscanf, которая намного быстрее, чем istringstream (http://lewismanor.blogspot.fr/2013/07/stdstringstream-vs-scanf.html):

#include <cstdio> 
#include <iostream> 

using namespace std; 

int main() { 
    const char * the_string= "1,2,3,45"; 
    int numbers[4]; 
    sscanf(the_string, "%d,%d,%d,%d", numbers+0, numbers+1, numbers+2, numbers+3); 

    // verification 
    for(int i=0; i<4; i++) 
     cout<<numbers[i]<<endl; 
} 
+0

Вы должны проверить возвращаемое значение 'sscanf' –

+0

Вы серьезно написали' numbers + 0'? –

+1

можно утверждать, что это для согласованности @KenWhite: D – deW1

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