2009-08-11 24 views
55

मुझे std::queue से अधिक पुनरावृत्त करने की आवश्यकता है। www.cplusplus.com का कहना है:std :: कतार पुनरावृत्ति

डिफ़ॉल्ट रूप से, यदि कोई कंटेनर वर्ग एक विशेष कतार वर्ग के लिए निर्दिष्ट किया जाता है, मानक कंटेनर वर्ग टेम्पलेट Deque प्रयोग किया जाता है।

तो क्या मैं किसी भी तरह से कतार के अंतर्निहित डेक पर जा सकता हूं और इसे फिर से कर सकता हूं?

उत्तर

56

यदि आपको queue पर फिर से शुरू करने की आवश्यकता है तो आपको कतार से कुछ और चाहिए। मानक कंटेनर एडाप्टर का बिंदु न्यूनतम इंटरफ़ेस प्रदान करना है। यदि आपको पुनरावृत्ति करने की भी आवश्यकता है, तो क्यों न केवल डेक (या सूची) का उपयोग करें?

+73

जबकि मुझे पता है कि आप क्या कह रहे हैं, मैंने हमेशा इस वाक्यांश को "कतार से कुछ और" नापसंद किया है। गणना के साथ एक कतार अभी भी एक कतार है ... साथ ही, ध्यान दें कि पूरी तरह से मनमाने ढंग से गणना का समर्थन करने के लिए 'डेक' कैसे होता है। आप बस तर्क दे सकते हैं कि 'डेक' को 'कतार' के रूप में शुद्धवादी होना चाहिए और पुनरावृत्ति का समर्थन नहीं करना चाहिए, और यदि आप इसे फिर से बनाना चाहते हैं तो आप कुछ "अधिक" चाहते हैं; जैसे एक 'deque_enumerable'। हालांकि यह एक फिसलन ढलान है, और मेरी व्यक्तिगत भावना यह है कि 'कतार' को पहली जगह में गणना का समर्थन करना चाहिए था। –

+4

@romkyns: अगर मैं इसे फिर से लिखता हूं तो बेहतर होगा: "आपको 'कतार' इंटरफ़ेस की तुलना में एक अमीर इंटरफ़ेस के साथ कुछ चाहिए, इसलिए आपको एक उपयुक्त इंटरफ़ेस वाला ऑब्जेक्ट चुनना चाहिए"। इसकी तरह या नहीं, पुनरावृत्ति 'कतार' इंटरफ़ेस का हिस्सा नहीं है, इसलिए यदि आप पुनरावृत्ति चाहते हैं तो आपको कुछ और चुनना होगा। –

+1

क्योंकि मेरे उपयोग के मामले में एक कतार की आवश्यकता है, लेकिन मुझे डीबग और लॉगिंग उद्देश्यों के लिए इसे बाहर निकालना होगा। आम तौर पर यह मानने के लिए रचनात्मक नहीं है कि पोस्टर नहीं जानते कि वे क्या कर रहे हैं। – EML

-2

संक्षेप में: नहीं

वहाँ एक हैक, underlaid कंटेनर के रूप में वेक्टर उपयोग करते हैं, तो queue::front वैध संदर्भ वापस आ जाएगी, यह परिवर्तित जब तक < = queue::back

+0

लेकिन आप इसके बजाय सीधे एक वेक्टर का उपयोग कर सकते हैं ... –

+1

आप सीधे डेक का उपयोग भी कर सकते हैं - जिसमें कतार के रूप में सभी आवश्यक विधियां हैं लेकिन पुनरावृत्ति का समर्थन भी करती है – Dewfy

0

एक पुनरावृति सूचक को आप पुनरावृति करने की आवश्यकता है है एक कतार ... कतार आपको आवश्यक कंटेनर नहीं है।
आपने कतार क्यों ली?
आप एक कंटेनर क्यों नहीं लेते जिसे आप फिर से कर सकते हैं?


1. यदि आप एक कतार तो लेने आप कहते हैं कि आप एक 'कतार' इंटरफेस में एक कंटेनर रैप करने के लिए करना चाहते हैं: - सामने - वापस - धक्का - पॉप - ...

यदि आप पुन: प्रयास करना चाहते हैं, तो कतार में एक गलत इंटरफ़ेस है। एक कतार एक एडाप्टर है कि मूल कंटेनर की एक सीमित सबसेट प्रदान करता है

2. एक कतार की परिभाषा एक फीफो और परिभाषा के द्वारा एक फीफो iterable

+24

मैं नहीं हूं ओपी, लेकिन यहां मेरे जवाब हैं, अगर कोई उत्सुक है: 1) मैंने एक कतार उठाई क्योंकि मुझे कतार चाहिए। मैं एक तरफ enqueue और दूसरे पर dequeue करना चाहता हूँ। क्या यह उचित विकल्प नहीं है? 2) यह स्पष्ट नहीं है कि एक "कतार" गणना योग्य नहीं है, न ही इसके लिए किस संरचना का उपयोग करना है। यदि आपने समझाया कि किस कंटेनर का उपयोग करना है तो आपका उत्तर अधिक उपयोगी होगा। –

28

जब मैं अन्य लोगों के साथ सहमत नहीं है कि एक के प्रत्यक्ष उपयोग इटेरेबल कंटेनर एक पसंदीदा समाधान है, मैं यह इंगित करना चाहता हूं कि सी ++ मानक किसी भी कारण से आप इसे चाहे किसी भी तरह के समाधान के लिए पर्याप्त समर्थन की गारंटी देता है।

अर्थात्, आप std::queue से विरासत और अंतर्निहित कंटेनर के शुरू() और अंत तक पहुँचने के लिए() अपने संरक्षित सदस्य Container c; उपयोग कर सकते हैं (बशर्ते कि इस तरह के तरीकों वहाँ मौजूद हैं)। यहाँ एक उदाहरण है कि VS 2010 और tested with ideone में काम करता है:

#include <queue> 
#include <deque> 
#include <iostream> 

template<typename T, typename Container=std::deque<T> > 
class iterable_queue : public std::queue<T,Container> 
{ 
public: 
    typedef typename Container::iterator iterator; 
    typedef typename Container::const_iterator const_iterator; 

    iterator begin() { return this->c.begin(); } 
    iterator end() { return this->c.end(); } 
    const_iterator begin() const { return this->c.begin(); } 
    const_iterator end() const { return this->c.end(); } 
}; 

int main() { 
    iterable_queue<int> int_queue; 
    for(int i=0; i<10; ++i) 
     int_queue.push(i); 
    for(auto it=int_queue.begin(); it!=int_queue.end();++it) 
     std::cout << *it << "\n"; 
    return 0; 
} 
+1

तो हम वही वरीयता_क्यू' पर कर सकते हैं, है ना? – Deqing

+3

@ डेकिंग: दाएं; लेकिन अंतर्निहित कंटेनर पर पुनरावृत्ति प्राथमिकता क्रम में नहीं होगा। –

+0

क्यों एक नई कक्षा को फिर से परिभाषित करें और सीधे 'डेक' का उपयोग न करें ?! –

-2

std::queue एक कंटेनर एडाप्टर है, और आप कंटेनर इस्तेमाल किया (यह चूक एक deque उपयोग करने के लिए) निर्दिष्ट कर सकते हैं। यदि आपको एडाप्टर में उससे परे कार्यक्षमता की आवश्यकता है तो बस deque या किसी अन्य कंटेनर का उपयोग करें।

+3

जबकि आपका उत्तर सही है, इसकी बिल्कुल आवश्यकता नहीं थी, क्योंकि इस 2 साल के पुराने प्रश्न में पहले से ही दो जवाब हैं (उनमें से एक स्वीकार्य उत्तर है)। –

0

क्यों न केवल उस कतार की एक प्रति बनाएं जिसे आप फिर से चालू करना चाहते हैं, और एक समय में आइटम को हटाएं, उन्हें प्रिंट करते समय प्रिंट करें? यदि आप तत्वों के साथ जितना अधिक करना चाहते हैं, तो एक कतार गलत डेटा संरचना है।

+2

एर, नहीं। फिर एक कतार को नष्ट करने की प्रतिलिपि बनाने की आवश्यकता के मुकाबले ज्यादा ओवरहेड है। यही कारण है कि इटरेटर का आविष्कार किया गया था। – Mac

+1

सरल: खाली कतार बनाएं। खाली होने तक अपनी मुख्य कतार से प्रत्येक आइटम को पॉप करें, इसे वांछित रूप से संसाधित करें, और इसे खाली कतार पर दबाएं। समाप्त होने पर, खाली कतार के बराबर मुख्य कतार सेट करें। प्राथमिकता_क्यू के लिए भी काम करता है। चेतावनी: थ्रेड-सुरक्षित नहीं है अगर कुछ अन्य धागे एक ही समय में कतार तक पहुंचने का प्रयास कर रहे हैं। साथ ही, यदि आपका मूल ढेर-आवंटित किया गया था ('malloc' /' new' के माध्यम से बनाया गया), तो सुनिश्चित करें कि इसे 'मुक्त'/'हटाएं 'या आप स्मृति को रिसाव करेंगे। –

0

https://stackoverflow.com/a/471461/383779 पर छवि देखें और फिर यह तय करें कि कौन सी कंटेनर आपकी आवश्यकताओं के अनुरूप सर्वोत्तम है।

+2

यह वास्तव में उपयोगी नहीं है। चार्ट मुझे बताता है कि मुझे एक - ड्रमोलोल की आवश्यकता है - * कतार *। –

3

आप मूल कतार को अस्थायी कतार में सहेज सकते हैं।तो फिर तुम बस अपने सामान्य पॉप अस्थायी कतार पर, मूल एक के माध्यम से जाने के लिए उदाहरण के लिए कार्य करें: अंत में

queue tmp_q = original_q; //copy the original queue to the temporary queue 

while (!tmp_q.empty()) 
{ 
    q_element = tmp_q.top(); 
    std::cout << q_element <<"\n"; 
    tmp_q.pop(); 
} 

, tmp_q खाली हो जाएगा लेकिन मूल कतार अछूता है।

+0

'std :: queue' में' .top() 'विधि प्रतीत नहीं होती है –

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