जवाबों:
मैं it - vec.begin()
नवीन द्वारा दिए गए विपरीत कारण के लिए सटीक रूप से पसंद करूंगा : यदि आप वेक्टर को एक सूची में बदलते हैं तो यह संकलन नहीं करेगा । यदि आप हर पुनरावृत्ति के दौरान ऐसा करते हैं, तो आप आसानी से O (n) एल्गोरिथ्म को O (n ^ 2) एल्गोरिथम में बदल सकते हैं।
एक अन्य विकल्प, यदि आप पुनरावृत्ति के दौरान कंटेनर में नहीं कूदते हैं, तो इंडेक्स को दूसरे लूप काउंटर के रूप में रखना होगा।
नोट: it
एक कंटेनर पुनरावृत्ति के लिए एक सामान्य नाम है std::container_type::iterator it;
,।
it
?
std::container_type::iterator it;
std::list
उनकी स्थिति के अनुसार तत्वों की सीधी पहुँच प्रदान नहीं करता है, इसलिए यदि आप ऐसा नहीं कर सकते हैं list[5]
, तो आपको करने में सक्षम नहीं होना चाहिए list.begin() + 5
।
मैं पसंद करूंगा std::distance(vec.begin(), it)
क्योंकि यह मुझे कंटेनर को बिना किसी कोड परिवर्तन के बदलने की अनुमति देगा। उदाहरण के लिए, आप का उपयोग करने का फैसला करता है, तो std::list
बजाय std::vector
जो एक यादृच्छिक अभिगम इटरेटर अपने कोड अभी भी संकलन होगा प्रदान नहीं करता है। चूंकि std :: दूरी इटैलिक लक्षणों के आधार पर इष्टतम विधि चुनती है, तो आपके पास कोई प्रदर्शन गिरावट भी नहीं होगी।
vec
है जो बुरी खबर है। यदि कोड को जेनेरिक होने के लिए फिर से लिखा गया था, तो कंटेनर प्रकार को एक टेम्पलेट पैरामीटर के रूप में लेते हुए, कि जब हम कर सकते हैं (और चाहिए) गैर-यादृच्छिक-पहुंच पुनरावृत्तियों को संभालने के बारे में ;-)
vec
होना बहुत बुरी खबर है, भी।
जैसा कि अंकल बीन्स और नवीन ने दिखाया है, दोनों के लिए अच्छे कारण हैं। कौन सा "बेहतर" है यह इस बात पर निर्भर करता है कि आप क्या व्यवहार चाहते हैं: क्या आप निरंतर समय के व्यवहार की गारंटी देना चाहते हैं, या क्या आप चाहते हैं कि जब आवश्यक हो, तो रैखिक समय पर वापस आ जाए?
it - vec.begin()
निरंतर समय लगता है, लेकिन operator -
इसे केवल यादृच्छिक अभिगम पुनरावृत्तियों पर परिभाषित किया जाता है, इसलिए कोड उदाहरण के लिए सूची पुनरावृत्तियों के साथ बिल्कुल संकलित नहीं करेगा।
std::distance(vec.begin(), it)
सभी पुनरावृत्त प्रकारों के लिए काम करता है, लेकिन केवल रैंडम एक्सेस पुनरावृत्तियों पर उपयोग किए जाने पर एक निरंतर-समय ऑपरेशन होगा।
न तो कोई "बेहतर" है। उस का उपयोग करें जो आपको चाहिए।
मुझे यह पसंद है: it - vec.begin()
क्योंकि, यह स्पष्ट रूप से "शुरुआत से दूरी" कहता है। पुनरावृत्तियों के साथ हम अंकगणित के संदर्भ में सोचने के आदी हैं, इसलिए यहाँ -
संकेत सबसे स्पष्ट संकेतक है।
distance
?
it++
और ऐसा कुछ नहीं है std::increment(it)
, क्या हम नहीं? यह भी कम स्पष्ट रूप में नहीं गिना जाएगा?
++
ऑपरेटर कैसे हम इटरेटर को बढ़ा देते रूप एसटीएल दृश्यों के भाग के रूप में परिभाषित किया गया है। std::distance
पहले और अंतिम तत्व के बीच तत्वों की संख्या की गणना करता है। तथ्य यह है कि -
ऑपरेटर काम करता है केवल एक संयोग है।
यदि आप पहले से ही std::vector::iterator
और std::vector::iterator
केवल अपने एल्गोरिथ्म को प्रतिबंधित / हार्डकोड कर रहे हैं , तो यह वास्तव में मायने नहीं रखता है कि आप किस विधि का उपयोग करेंगे। आपके एल्गोरिथ्म को पहले से ही उस बिंदु से आगे बढ़ाया जाता है जहां किसी एक को चुनने से कोई फर्क पड़ सकता है। वे दोनों बिल्कुल एक ही काम करते हैं। यह सिर्फ व्यक्तिगत पसंद की बात है। मैं व्यक्तिगत रूप से स्पष्ट घटाव का उपयोग करूंगा।
यदि, दूसरी ओर, आप अपने एल्गोरिथ्म में सामान्यता की एक उच्च डिग्री को बनाए रखना चाहते हैं, अर्थात्, इस संभावना को अनुमति देने के लिए कि भविष्य में किसी दिन यह किसी अन्य पुनरावृत्त प्रकार पर लागू हो सकता है, तो सबसे अच्छा तरीका आपके इरादे पर निर्भर करता है । यह इस बात पर निर्भर करता है कि आप यहाँ इस्तेमाल किए जा सकने वाले itter प्रकार के संबंध में कितना प्रतिबंधात्मक होना चाहते हैं।
यदि आप स्पष्ट घटाव का उपयोग करते हैं, तो आपका एल्गोरिथ्म पुनरावृत्तियों के बजाय संकीर्ण वर्ग तक सीमित रहेगा: यादृच्छिक अभिगम पुनरावृत्तियों। (यह वही है जो अब आपको मिलता है std::vector
)
यदि आप उपयोग करते हैं distance
, तो आपका एल्गोरिथ्म पुनरावृत्तियों के बहुत व्यापक वर्ग का समर्थन करेगा: इनपुट पुनरावृत्तियों।
बेशक, distance
गैर-यादृच्छिक-पहुंच पुनरावृत्तियों के लिए गणना सामान्य स्थिति में एक अक्षम ऑपरेशन है (जबकि, फिर से, यादृच्छिक-पहुंच वाले लोगों के लिए यह घटाव के रूप में कुशल है)। यह आपको तय करना है कि आपका एल्गोरिथ्म गैर-यादृच्छिक-पहुंच वाले पुनरावृत्तियों, दक्षता-वार के लिए समझ में आता है या नहीं । यह दक्षता में परिणामी हानि आपके एल्गोरिदम को पूरी तरह से बेकार बनाने के बिंदु पर विनाशकारी है, फिर आपको घटाव के लिए बेहतर रहना चाहिए, इस प्रकार अक्षम उपयोगों को रोकना और उपयोगकर्ता को अन्य पुनरावृत्त प्रकारों के लिए वैकल्पिक समाधान प्राप्त करने के लिए मजबूर करना चाहिए। यदि गैर-यादृच्छिक-पहुंच वाले पुनरावृत्तियों के साथ दक्षता अभी भी प्रयोग करने योग्य सीमा में है, तो आपको distance
इस तथ्य का उपयोग और दस्तावेज करना चाहिए कि एल्गोरिथ्म यादृच्छिक-पहुंच पुनरावृत्तियों के साथ बेहतर काम करता है।
Http://www.cplusplus.com/reference/std/iterator/distance/ के अनुसार , चूंकि vec.begin()
एक यादृच्छिक अभिगमकर्ता है, दूरी विधि -
ऑपरेटर का उपयोग करता है ।
तो जवाब है, प्रदर्शन के दृष्टिकोण से, यह समान है, लेकिन शायद distance()
यह समझना आसान है कि क्या किसी को आपके कोड को पढ़ना और समझना होगा।
मैं केवल -
संस्करण का उपयोग करूँगा std::vector
- यह बहुत स्पष्ट है कि इसका क्या मतलब है, और ऑपरेशन की सादगी (जो एक सूचक घटाव से अधिक नहीं है) को सिंटैक्स द्वारा व्यक्त किया जाता है ( distance
दूसरी तरफ, पाइथागोरस की तरह लगता है) पहले पढ़ना, है ना?)। जैसा कि अंकल बताते हैं, -
यह भी एक स्टेटिक अभिकथन के रूप में कार्य करता है कि मामले vector
में गलती से बदल दिया गया है list
।
इसके अलावा, मुझे लगता है कि यह बहुत अधिक सामान्य है - हालांकि, इसे साबित करने के लिए कोई संख्या नहीं है। मास्टर तर्क: it - vec.begin()
स्रोत कोड में कम है - कम टाइपिंग का काम, कम जगह की खपत। जैसा कि यह स्पष्ट है कि आपके प्रश्न का सही उत्तर स्वाद का मामला है, यह एक मान्य तर्क भी हो सकता है।
सूचकांक के साथ 10 के "सभी" घटनाओं को खोजने के लिए यहां एक उदाहरण है। सोचा कि इससे कुछ मदद मिलेगी।
void _find_all_test()
{
vector<int> ints;
int val;
while(cin >> val) ints.push_back(val);
vector<int>::iterator it;
it = ints.begin();
int count = ints.size();
do
{
it = find(it,ints.end(), 10);//assuming 10 as search element
cout << *it << " found at index " << count -(ints.end() - it) << endl;
}while(++it != ints.end());
}