2016-11-17 59 views
5

我在這個載體中的std::vector<std::string>我從txt文件push_back串,這樣的:C++最佳方式

std::string line; 
std::vector<std::string> path; 
while(getline(fichier, line)) 
{  
    path.push_back(line); 
} 

我想路徑vector分成其他vector 10線的n個例如。 所以如果我的vector的大小是25,我想要另外兩個10元素的矢量和一個5元素的vector

這樣做的最好方法是什麼?

+3

您可以使用[STD的'拷貝構造函數:: VECTOR'(http://en.cppreference.com/w/cpp/container/vector/vector)需要兩個迭代器 –

回答

4

最好是見仁見智的問題,但你可以不喜歡以下(含bunch_size10):

for(size_t i = 0; i < strings.size(); i += bunch_size) { 
    auto last = std::min(strings.size(), i + bunch_size); 
    bunches.emplace_back(strings.begin() + i, strings.begin() + last); 
} 

demo

如果你的字符串是大,要避免複製,你可以用移動版本,請:

for(size_t i = 0; i < strings.size(); i += bunch_size) { 
    auto last = std::min(strings.size(), i + bunch_size); 
    auto index = i/bunch_size; 
    auto& vec = bunches[index]; 
    vec.reserve(last - i); 
    move(strings.begin() + i, strings.begin() + last, back_inserter(vec)); 
} 

demo

1

我提出的東西很一般(它與不同的容器和不同類型的複雜性將在這種情況下發生變動):

#include <algorithm> 
#include <iterator> 
#include <vector> 

template<typename Vector> 
auto split_vector(const Vector& v, unsigned number_lines) { 
    using Iterator = typename Vector::const_iterator; 
    std::vector<Vector> rtn; 
    Iterator it = v.cbegin(); 
    const Iterator end = v.cend(); 

    while (it != end) { 
    Vector v; 
    std::back_insert_iterator<Vector> inserter(v); 
    const auto num_to_copy = std::min(static_cast<unsigned>(
     std::distance(it, end)), number_lines); 
    std::copy(it, it + num_to_copy, inserter); 
    rtn.push_back(std::move(v)); 
    std::advance(it, num_to_copy); 
    } 

    return rtn; 
} 

您可以指定要拆分的行數:

例如:

int main(int argc, char *argv[]) { 
    std::vector<std::string> input_vector = {"First", "Second", "Third"}; 
    auto vs = split_vector(input_vector, 2); 
    return 0; 
} 

這將產生兩個矢量:{"First", "Second"}{"Third"}

1

您可以使用stream iterators做在讀取文件的作業:

using packet_t = Packet<5>; 
using filler_t = std::istream_iterator<packet_t>; 

std::vector<packet_t> packets{ 
    filler_t(stream), 
    filler_t() 
}; 

隨着結構Packet聲明需要operator>>

template<size_t size> 
struct Packet 
{ 
    std::vector<std::string> lines; 

    friend std::istream& operator>>(std::istream& is, Packet& packet) 
    { 
     packet.lines.clear(); 
     std::string line; 
     for(size_t i = 0; i < size && std::getline(is, line); ++i) 
     { 
      packet.lines.push_back(line); 
     } 
     if(packet.lines.size() > 0) 
     { 
      is.clear(); 
     } 
     return is; 
    } 
}; 

注意,當包不是流被清除空的最後一行。

完整代碼:

#include <iostream> 
#include <iterator> 
#include <sstream> 
#include <vector> 

template<size_t size> 
struct Packet 
{ 
    std::vector<std::string> lines; 

    friend std::istream& operator>>(std::istream& is, Packet& packet) 
    { 
     packet.lines.clear(); 
     std::string line; 
     for(size_t i = 0; i < size && std::getline(is, line); ++i) 
     { 
      packet.lines.push_back(line); 
     } 
     if(packet.lines.size() > 0) 
     { 
      is.clear(); 
     } 
     return is; 
    } 
}; 

int main() 
{ 
    std::istringstream stream("1\n2\n3\n4\n5\n6\n7\n"); 

    using packet_t = Packet<5>; 
    using filler_t = std::istream_iterator<packet_t>; 

    std::vector<packet_t> packets{ 
     filler_t(stream), 
     filler_t() 
    }; 

    for(auto& packet : packets) 
    { 
     for(auto& line : packet.lines) 
     { 
      std::cout << line << " "; 
     } 
     std::cout << std::endl; 
    } 
}