2013-03-25 31 views
7

Czy istnieje metoda konwersji wektora na wektor w C++, win32?convert <vector><string> TO <vector><int> C++, Win32

Mam ten ciąg wektor z numerami:

std::vector<std::string> DataNumbers; 

muszę przekonwertować ten ciąg do wektora wektor liczb całkowitych.

+0

Czym dokładnie jest Twoim celem? W jakim formacie są liczby? Jak ważna jest wydajność a czytelność? –

+0

Potrzebuję tylko liczb całkowitych. I po tym chciałbym pomnożyć przez kilka liczb z tego wektora int –

Odpowiedz

2

Spróbuj tego:

std::vector<std::string> DataNumbers; 
    // Fill DataNumbers 
    std::vector<int> intNumbers; 
    for (int i=0; i<= 5; i++) 
    { 
    int num = atoi(DataNumbers.at(i).c_str()); 
    intNumbers.push_back(num); 
    } 
+1

Myślę, że poprzednie rozwiązania były dobre, ale działa to dla mnie dobrze, ponieważ mój kompilator nie ma "funkcji C++ 11". Dziękuję! –

+3

Nie sądzę, aby poleganie na trwałych kodach i korzystaniu ze starszych funkcji języka C było dobrym rozwiązaniem. Jeśli nie masz C++ 11, użyj odpowiedzi Richarda J Rossa i zmień 'dla (auto & s: input)' na 'dla (wektor :: iterator it = DataNumbers.begin(); it! = DataNumbers. end(); it ++) 'a także' std :: stringstream parser (s); 'do' std :: stringstream parser (* it); '. – us2012

+0

Ten kod dał mi raka. – Puppy

4

C++ sposób to zrobić to:

vector<std::string> input = ...; 
vector<int> output; 

for (auto &s : input) { 
    std::stringstream parser(s); 
    int x = 0; 

    parser >> x; 

    output.push_back(x); 
} 

Nie wiedząc, co chcesz zrobić, gdy wejście nie powiedzie, nie ma wiele więcej do powiedzenia tutaj.

+0

Dzięki. Ale co oznacza "s" w pętli for? –

+1

iterator na ciąg wektor – Alon

+1

@alon nie, kopia tego ciągu – jrok

19

Dane:

std::vector<std::string> DataNumbers; 
// Fill DataNumbers 
std::vector<int> Data; 

Można użyć std::transform. Użyj wartości std::back_inserter, aby wstawić wartości do std::vector<int>. Dla funkcji jednoargumentowej użyj wyrażenia lambda, które używa std::stoi do konwersji ciągów na liczby całkowite.

std::transform(DataNumbers.begin(), DataNumbers.end(), std::back_inserter(Data), 
       [](const std::string& str) { return std::stoi(str); }); 

A oto wersja bez lambda (z wykorzystaniem std::bind zamiast):

typedef int(*stoi_type)(const std::string&, std::size_t*, int); 
std::transform(DataNumbers.begin(), DataNumbers.end(), std::back_inserter(Data), 
       std::bind(static_cast<stoi_type>(&std::stoi), 
         std::placeholders::_1, nullptr, 10)); 
+0

Byłbym niezdecydowany, aby zwariować z lambdami. Zwykle są wolniejsze niż w przypadku pętli for i mogą powodować długoterminową czytelność. Nie wspominając o tym, że jeszcze nie wszystkie kompilatory obsługują je w pełni. –

+0

@ RichardJ.Ross Jest tam jedna lambda, nie jestem pewien, jak to się kwalifikuje jako "wariactwo". Ponadto, nie sądzę, żadnego kompilatora, który nie obsługuje lambda tak proste, jak to nie ośmieliłoby się wspomnieć o * cokolwiek * o zgodności C++ 11 w swoich dokumentach ... – us2012

+1

@ us2012 Mogłem mieć kompilator, który tylko obsługuje 'auto' i' decltype' i mówią, że ma "funkcje C++ 11", czyż nie? Ponadto, upowszałem twoją odpowiedź. –

1

Co o:

#include <algorithm> 
#include <boost/lexical_cast.hpp> 

template<typename C1, typename C2> 
void castContainer(const C1& source, C2& destination) 
{ 
    typedef typename C1::value_type source_type; 
    typedef typename C2::value_type destination_type; 
    destination.resize(source.size()); 
    std::transform(source.begin(), source.end(), destination.begin(), boost::lexical_cast<destination_type, source_type>); 
} 

Może konwertować wektor < ciąg> do wektora < int>, a także inny kontener < T1> do kontenera2 < T2>, np .: lista -> lista.

Pełny kod:

#include <iostream> 
#include <vector> 
#include <algorithm> 
#include <iterator> 
#include <string> 
#include <boost/lexical_cast.hpp> 

template<typename C1, typename C2> 
void castContainer(const C1& source, C2& destination) 
{ 
    typedef typename C1::value_type source_type; 
    typedef typename C2::value_type destination_type; 
    destination.resize(source.size()); 
    std::transform(source.begin(), source.end(), destination.begin(), boost::lexical_cast<destination_type, source_type>); 
} 

template<typename T, typename T2> 
std::vector<T>& operator<<(std::vector<T>& v, T2 t) 
{ 
    v.push_back(T(t)); 
    return v; 
} 

main(int argc, char *argv[]) 
{ 
    std::vector<std::string> v1; 
    v1 << "11" << "22" << "33" << "44"; 
    std::cout << "vector<string>: "; 
    std::copy(v1.begin(), v1.end(), std::ostream_iterator<std::string>(std::cout, ", ")); 
    std::cout << std::endl; 

    std::vector<int> v2; 
    castContainer(v1, v2); 

    std::cout << "vector<int>: "; 
    std::copy(v2.begin(), v2.end(), std::ostream_iterator<int>(std::cout, ", ")); 
    std::cout << std::endl; 
}