2012-03-21 13 views
19

मुझे क्या करना कोशिश कर रहा हूँ:एक वेक्टर को दो छोटे सरणी में विभाजित करने का सबसे अच्छा तरीका?

मैं दो अलग विन्यास में, एक वेक्टर विभाजित करने के लिए कोशिश कर रहा हूँ। वर्तमान int वेक्टर में टेक्स्ट फ़ाइल में प्रति पंक्ति एक तत्व होता है। पाठ फ़ाइल यादृच्छिक पूर्णांक की एक सूची है।

मैं कैसे यह करने के लिए योजना बना रही है:

मेरे वर्तमान विचार दो नियमित पूर्णांक सरणियों बनाने के लिए, उसके बाद पूरे वेक्टर से अधिक पुनरावृति और सरणियों से प्रत्येक के लिए n/2 तत्वों कॉपी करने के लिए है।

मैं जानना चाहूंगा क्या:

मेरे कार्य को पूरा करने की सबसे खूबसूरत तरीका क्या है? मुझे एहसास है कि मैं वेक्टर पर कई बार फिर से बिना इसे कर सकता हूं।

कोड:

#include <vector> 
#include <fstream> 
#include <iterator> 
#include <iostream> 
using namespace std; 

vector<int> ifstream_lines(ifstream& fs) 
{ 
    vector<int> out; 
    int temp; 
    while(fs >> temp) 
    { 
    out.push_back(temp); 
    } 
    return out; 
} 

vector<int> MergeSort(vector<int>& lines) 
{ 
    int split = lines.size()/2; 
    int arrayA[split]; 
    int arrayB[split]; 
} 

int main(void) 
{ 
    ifstream fs("textfile.txt"); 
    vector<int> lines; 
    lines = ifstream_lines(fs); 

    return 0; 
} 

धन्यवाद :)

+0

मैं '' हैडर (http से कुछ की सलाह देते हैं /en.cppreference.com/w/cpp/algorithm)। 'std :: copy' या' std :: move' रुचि का हो सकता है। –

+0

मुझे पसंद है कि सवाल कैसे पूछा जाता है। आपको नए उपयोगकर्ताओं से अक्सर इस तरह के अच्छे संरचित प्रश्न नहीं दिखते हैं। – MOnsDaR

+0

यदि आप 2 सरणी के आकार को बदलने की योजना नहीं बनाते हैं, तो आप 'array_view' – sp2danny

उत्तर

44

उपयोग iterators।

std::vector<int> lines; 
// fill 
std::size_t const half_size = lines.size()/2; 
std::vector<int> split_lo(lines.begin(), lines.begin() + half_size); 
std::vector<int> split_hi(lines.begin() + half_size, lines.end()); 

के बाद से इटरेटर पर्वतमाला आधे खुले पर्वतमाला [begin, end) प्रतिनिधित्व करते हैं, तो आप दूसरा शुरू इटरेटर को 1 जोड़ने की जरूरत नहीं है: lines.begin() + half_size प्रथम वेक्टर में कॉपी नहीं किया गया है।


ध्यान दें कि चीजों

तरह
int split = lines.size()/2; 
int arrayA[split]; 
int arrayB[split]; 

मानक सी नहीं हैं ++ (और इस तरह पोर्टेबल नहीं के रूप में)। ये तथाकथित परिवर्तनीय-लंबाई सरणी (लघु के लिए वीएलए) हैं और एक सी 99 चीज हैं। सी ++ कोड (जीसीसी, क्लैंग) संकलित करते समय कुछ कंपाइलर्स उन्हें विस्तार के रूप में रखते हैं। चेतावनी प्राप्त करने के लिए हमेशा -pedantic के साथ संकलित करें। ये वीएलए गैर-पीओडी प्रकारों के लिए फंकी कार्य करते हैं और आमतौर पर उपयोगी नहीं होते हैं, क्योंकि आप उन्हें वापस भी नहीं कर सकते हैं।

+0

पर एक नज़र डाल सकते हैं, बहुत अच्छा जवाब है, "आपको दूसरे प्रारंभ करने वाले को 1 में जोड़ने की आवश्यकता नहीं है" –

2

आप केवल उन्हें जोड़ तोड़ के बिना नंबर के लिए एक संदर्भ की जरूरत है, तो आप कर सकते हैं:

int *array_1 = &lines[0]; 
int *array_2 = &lines[lines.size()/2]; 

array_1 और array_2, कर रहे हैं वास्तव में, आरंभ और वेक्टर के बीच की ओर इशारा। यह काम करता है क्योंकि एसटीएल गारंटी देता है कि वैक्टर अपने तत्वों को निरंतर स्मृति में संग्रहीत करते हैं। ध्यान दें कि line.begin() का जिक्र इस के लिए उपयोग नहीं किया जा सकता है।

1

आप सख्त संकलक नियमों के कारण Xeo जवाब से कोड का उपयोग नहीं कर सकते हैं या आप अधिक सामान्य तरीके से चाहते हैं, std::advance कोशिश: /:

#include <vector> 
#include <iterator> 

size_t middle = input.size()/2; 
std::vector<int>::const_iterator middleIter(input.cbegin()); 
std::advance(middleIter, middle); 

std::vector<int> leftHalf(input.begin(), middleIter); 
std::vector<int> rightHalf(middleIter, input.end()); 
संबंधित मुद्दे

 संबंधित मुद्दे