2010-06-03 19 views
6

पर दिशानिर्देश मेरे पास एक लाल काला पेड़ सी ++ में लागू किया गया है। यह एक एसटीएल मानचित्र की कार्यक्षमता का समर्थन करता है। वृक्ष नोड्स में कुंजी और मैप किए गए मान होते हैं। मैं इसके लिए इटेटर श्रेणी लिखना चाहता हूं, लेकिन मैं इसे कैसे करना है इसके साथ अटक गया हूं। क्या मुझे इसे पेड़ वर्ग के आंतरिक वर्ग बनाना चाहिए? क्या कोई मुझे इसे लिखने के बारे में कुछ दिशानिर्देश दे सकता है + कुछ संसाधन ??एक इटरेटर कक्षा

धन्यवाद !!

+0

आपकी जानकारी के लिए, अधिकांश एसटीएल कार्यान्वयन अपने std :: मानचित्र को लाल-काले पेड़ पर आधारित करते हैं, इसलिए जब तक यह शैक्षणिक उद्देश्य के लिए नहीं है, तो आप स्वयं को बनाने के बजाय std :: map का उपयोग करने पर विचार कर सकते हैं। –

उत्तर

7

ज़रूर, एसटीएल iterators लिखने पर यह अच्छा लेख को पढ़ने के लिए, यह आप की जरूरत सिंहावलोकन दे सकता है:

http://www.drdobbs.com/184401417

सामान्य तौर पर, हाँ, एक आंतरिक वर्ग अच्छा है, क्योंकि इटरेटर लिए उपयोग की जरूरत अपने कार्यान्वयन विशिष्ट पेड़ नोड्स:

struct container { ... 
public: 
    struct iterator { 
    // these typedefs are needed if you want to be STL compatible 
    typedef std::forward_iterator_tag iterator_category; 
    typedef T   value_type; 
    typedef T*  pointer; 
    typedef T&  reference; 
    typedef size_t size_type; 
    typedef ptrdiff_t difference_type; 

    // the element points to your implementation node 
    iterator(element* init = 0) : current(init) {} 
    T& operator*() { return current->data; } // dereference 
    const T& operator*() const { return current->data; } 
    iterator& operator++() { // prefix 
     if (current) current = current->next; 
     return *this; 
    } 
    iterator operator++(int) { // postfix 
     iterator temp = *this; 
     ++*this; 
     return temp; 
    } 
    bool operator==(const iterator& x) const { return current == x.current; } 
    bool operator!=(const iterator& x) const { return current != x.current; } 

    private: 
    // the element points to your implementation node 
    element* current; 
    } 
    ... 

अच्छी बात यह है कि इटरेटर सार्वजनिक है, तत्व अभी भी निजी रह सकता है :)। और हाँ, उपरोक्त कोड एसटीएल संकलक भी है!

+0

आपको बहुत ज्यादा कॉर्नेल धन्यवाद। यह वही है जो मैं खोज रहा था और यह बहुत उपयोगी है: डी – Izza

+0

@ कॉर्नेल: एक और सवाल, क्या आप अपनी दूसरी टिप्पणी के बाद कोड लाइन को समझा सकते हैं, ** iterator (element * init = 0): वर्तमान (init) {} ** मैं कोलन के बाद आने वाले भाग को समझ नहीं सकता। धन्यवाद! – Izza

+0

@isurulucky, यह एक प्रारंभकर्ता सूची है (http://www.codeguru.com/forum/showthread.php?t=464084) –

1

इटेटर श्रेणी को या तो एक नेस्टेड क्लास, या कम से कम एक टाइपेडफ होना चाहिए जो your_map::iterator को किसी अन्य प्रकार से परिभाषित किया गया है जो किसी अन्य प्रकार से परिभाषित किया गया है। एक घोंसला वर्ग आमतौर पर सबसे साफ/आसान मार्ग है।

जहां तक ​​संसाधन जाते हैं, सहायता का एक संभावित स्रोत Boost::iterator लाइब्रेरी होगा, जिसमें घटकों को कार्यान्वित करने में आसान बनाने के उद्देश्य से घटक शामिल हैं।

+0

+1 - लेकिन अगर कोई एसटीएल का उपयोग करने के बजाय अपने स्वयं के लाल-काले पेड़ों को रोल करता है तो वह शायद बूस्ट का उपयोग नहीं करेगा। –

+0

@ कॉर्नेल: यह हो सकता है - मुझे यह मानना ​​है कि मेरे द्वारा लिखे गए सभी पुनरावर्तक "प्राथमिकता से" हैं, मानक के साथ मेरे प्राथमिक संसाधन ... –

1

मैंने सोचा कि मैं सलाह का अपना छोटा बैच जोड़ूंगा।

पहली बात यह है कि मैं ध्यान रखना चाहता हूं कि iterator और const_iterator उनके सामान्य कार्यान्वयन में बहुत अधिक संभावना है। हालांकि, भले ही उनका कोड समान है, यह बिल्कुल समान नहीं है। यह टेम्पलेट्स के लिए begs।

दूसरी बात जो मैं नोट करना चाहता हूं वह यह है कि const_iteratoriterator (निस्संदेह) से रचनात्मक होना चाहिए, लेकिन दूसरी तरफ नहीं।

तीसरी बात यह है कि मैं नोट करना चाहता हूं कि यदि आप map-इंटरफ़ेस की तरह चाहते हैं, तो आपको reverse_iterator और const_reverse_iterator भी प्रदान करना होगा।

एक शैली के दृष्टिकोण से, मैं कक्षा में iterator के कार्यान्वयन को अपने आप में नहीं डालता। मुझे यह अपठनीय लगता है जब कक्षा कार्यान्वयन इतने सारे कोड से घिरा हुआ है कि आप उपलब्ध प्रकारों और विधियों को देखने के लिए संघर्ष करते हैं। इस कारण से मैं कक्षा के बाहर कार्यान्वयन की सिफारिश करने की सिफारिश करता हूं।

अंत में, मैं निश्चित रूप से बूस्ट.इटरेटर की अनुशंसा करता हूं। आप इसका उपयोग नहीं कर सकते हैं, लेकिन सामग्री को पढ़ सकते हैं, यह आपको एक बार कोड लिखने और 4 प्रकार के लिए इसका उपयोग करने के बारे में अंतर्दृष्टि प्रदान करेगा!

त्वरित उदाहरण:

namespace detail { 
    template <class Value> class base_iterator; 
} 

template <class Value> 
class container 
{ 
public: 
    typedef detail::base_iterator<Value> iterator; 
    typedef detail::base_iterator<Value const> const_iterator; 

    typedef boost::reverse_iterator<iterator> reverse_iterator; 
    typedef boost::reverse_iterator<const_iterator> const_reverse_iterator; 
}; 

मैं तुम्हारे बारे में पता नहीं है, लेकिन मैं अच्छा लग रहा है जब मैं काम के केवल एक चौथाई करते हैं और एक संकलक/पुस्तकालय मेरे लिए बाकी हिस्सों में भरने के लिए का लाभ उठाता है :)

+0

+1: बिंदु लिया गया: पी –

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