2015-12-30 9 views
6

से स्ट्रिंग मैं तो मैं std :: स्ट्रिंग के रूप में सेट से सामग्री प्राप्त करना चाहते हैं वर्णप्रभावी निर्माण std :: std :: unordered_set <char>

std::unordered_set<char> u_setAlphabet; 

के unordered_set है। मेरा कार्यान्वयन अब इस तरह दिखता है:

std::string getAlphabet() { 
    std::string strAlphabet; 
    for (const char& character : u_setAlphabet) 
     strAlphabet += character; 
    return strAlphabet; 
} 

क्या यह इस काम को हल करने का एक अच्छा तरीका है? स्ट्रिंग के लिए सिग्नल वर्णों के जोड़ बड़े u_setAlphabet (एकाधिक reallocs?) के लिए इष्टतम नहीं लगते हैं। क्या इसके लिए कोई और तरीका है?

auto s = std::string(begin(u_setAlphabet), end(u_setAlphabet)); 
+1

शिष्टाचार के मामले के रूप में: कम से कम एक टुकड़े में एक पहचानकर्ता, प्रतिनिधि उदाहरण कोड शायद 'u_setAlphabet' की तरह अजीब रूप से अजीब नहीं होना चाहिए। उदाहरण कोड के लिए अच्छे पहचानकर्ता 'foo', 'bar' और' x' हैं। –

+1

@KerrekSB दूसरी तरफ, मुझे यह कहना होगा कि मैं कोड पसंद करता हूं जो एक अनियंत्रित सेट 'setAlphabet' को एक स्ट्रिंग' strAlphabet' में कॉपी करता है जो प्रतिलिपि बनाता है (या स्ट्रिंग था?) 'Foo' स्ट्रिंग में (या यह सेट था ?) 'बार'। – Angew

+0

@KerrekSB अच्छा बिंदु, मुझे अगले प्रश्न पर आपकी सिफारिश याद है। कुछ नाम अब इन नामों का उपयोग करते हैं, इसलिए मैं प्रश्न की सामग्री को यहां नहीं बदलूंगा – saleph

उत्तर

12

सबसे सरल, सबसे पठनीय और सबसे कारगर जवाब है:

return std:string(s.begin(), s.end()); 

कार्यान्वयन रेंज सामने और केवल एक बार आवंटित की लंबाई का पता लगाने के लिए चुन सकते हैं; libC++ और libstdC++ दोनों इसे आगे करते हैं जब एक आगे इटरेटर रेंज दिया जाता है।

string वर्ग भी आप क्षमता का प्रबंधन करने के reserve प्रदान करता है, बस vector की तरह,:

std::string result 
result.reserve(s.size()); 
for (unsigned char c : s) result.push_back(c); // or std::copy 
return result; 

यह भी assign, append और insert सदस्य कार्यों प्रदान करता है, लेकिन जब से उन की पेशकश मजबूत अपवाद गारंटी, वे हो सकता है पुराने को नष्ट करने से पहले एक नया बफर आवंटित करना होगा (इस महत्वपूर्ण विवरण को इंगित करने के लिए @ टीटी के लिए धन्यवाद!)। यदि मौजूदा क्षमता पर्याप्त है, तो libC++ कार्यान्वयन पुन: आवंटित नहीं होता है, जबकि GCC5 का libstdC++ कार्यान्वयन बिना शर्त के पुन: आवंटित करता है।

+0

ouh, रिजर्व, मैं इसके बारे में भूल गया :) लेकिन क्या std :: स्ट्रिंग कन्स्ट्रक्टर इसे स्वयं अनुकूलित नहीं करता है? – saleph

+2

मैं केवल 'आरक्षित()' कोड को दोबारा दूंगा यदि आप जानते हैं कि आप वास्तव में प्रदर्शन महत्वपूर्ण कोड में हैं और आपको इसे मापकर एक अंतर मिला है। यह आपके कोड को गले लगाता है, लेकिन अगर लाभ इसे औचित्य देता है, तो यह ठीक है। एक अच्छा मानक लाइब्रेरी कार्यान्वयन केवल निर्माता को ले जाने वाले कन्स्ट्रक्टर के साथ स्मृति को आरक्षित करेगा। एकमात्र ऊपरी भाग आपको आकार के सामने खोजने के लिए ट्रैवर्सल होगा। –

+3

@ सैलेफ संख्या, 'std :: set के रूप में :: इटेटरेटर केवल बोली लगाने के लिए बिडरेक्शनल इटरेटर' std :: distance' को ओ (एन) ऑपरेशन है। हालांकि, 'std :: set :: आकार' निरंतर समय ऑपरेशन है। – Daniel

12

std::string कि के लिए a constructor है। उदाहरण के लिए

std::string getAlphabet() { 
    return { u_setAlphabet.begin(), u_setAlphabet.end() }; 
} 
10

यह निर्माता कि iterators acepts उपयोग करने के लिए बेहतर है:

+0

यह सी ++ 11 शैली में बहुत अधिक है :) लेकिन आप अपने और @xtofl के बीच पठनीयता भिन्नता के बारे में क्या सोचते हैं (आपकी राय में) aswer? दाएं - आपका कार्यान्वयन सबसे छोटा है, लेकिन यह पहली नजर में किसी प्रकार का जादू दिखता है :) – saleph

+1

@ सैलेफ यदि सी ++ आपके लिए जादू की तरह दिखता है तो आपको सी ++ सीखना चाहिए :) तुलना के लिए 1) xtofl को C++ 11 सुविधाओं और 2 का उपयोग करके भी लिखा गया है) यह फ़ंक्शन परिभाषा के बारे में कहने वाले प्रश्न के अनुरूप नहीं है। –

+0

बेशक मैं आपका कोड समझता हूं :) लेकिन क्या आपका कार्यान्वयन @ केर्रेकएसबी के समान नहीं है? वह एक स्ट्रिंग बनाता है, जो निश्चित रूप से बाद में ही चलेगा (उदाहरण के लिए। 'Std :: string foo (getAlphabet()); ') – saleph

1

return std::string(u_setAlphabet.begin(), u_setAlphabet.end()); और return { u_setAlphabet.begin(), u_setAlphabet.end(); दोनों C++ 11 में समान हैं। मैं @VladfromMoscow समाधान पसंद करता हूं क्योंकि हमें अस्थायी वस्तु के लौटे प्रकार के बारे में कोई धारणा करने की आवश्यकता नहीं है।

+0

लेकिन क्या यह छिपी हुई संरचना आपकी राय में कम स्पष्ट नहीं है? मैं वास्तव में सी ++ में भिखारी हूँ, इसलिए मेरी पठनीयता भावना बहुत अनुभवी नहीं है :) – saleph

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