2016-11-17 17 views
5

मैं इस सदिश में एक std::vector<std::string> है मैं पाठ फ़ाइल से push_back स्ट्रिंग, इस तरह:सी ++ का सबसे अच्छा तरीका

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

मैं vector 10 लाइन के दूसरी n में पथ vector विभाजित करने के लिए चाहते हैं उदाहरण के लिए। तो यदि मेरे vector का आकार 25 है, तो मुझे 5 तत्वों के 2 अन्य वेक्टर और 5 तत्वों में से vector चाहिए।

ऐसा करने का सबसे अच्छा तरीका क्या है?

+3

आप इस्तेमाल कर सकते हैं [ 'एसटीडी की प्रति-निर्माता :: vector'] (http://en.cppreference.com/w/cpp/container/vector/vector) जो दो इटरेटर लेता है –

उत्तर

4

बेस्ट राय की बात है, लेकिन आप (bunch_size जा रहा है 10 के साथ) निम्नलिखित की तरह कुछ कर सकता है:

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; 
} 

आप विभाजित करना चाहते हैं लाइनों की संख्या निर्दिष्ट कर सकते हैं

उदाहरण के लिए: {"First", "Second"} और {"Third"}:

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

यह दो वैक्टर का उत्पादन करेगा।

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; 
    } 
} 
संबंधित मुद्दे