2011-10-13 11 views
15

एक खेल मैं खिलाड़ियों की एक सूची है में, इस तरह मान लीजिए:जावा में एक इटरेटर क्लोन करें?

LinkedList<String> players = new LinkedList<String>(); 

मैं प्रत्येक खिलाड़ी अन्य खिलाड़ियों में से प्रत्येक के साथ बातचीत बताना चाहते हैं, तो मैं दो नेस्टेड छोरों लिखें:

Iterator<String> i1 = players.iterator(); 
while (i1.hasNext()) { 
    String p1 = i1.next(); 
    Iterator<String> i2 = players.iterator(); 
    // But I want to do this: Iterator<String> i2 = i1.clone(); 
    while (i2.hasNext()) { 
     String p2 = i2.next(); 
     System.out.println("Interact: " + p1 + ", " + p2); 
    } 
} 

चूंकि मैं केवल खिलाड़ियों की प्रत्येक जोड़ी को एक बार बातचीत करना चाहता हूं, इसलिए मैं बाहरी लूप के वर्तमान प्लेयर के बाद प्लेयर के साथ आंतरिक लूप शुरू करना चाहता हूं। तो मैं इटेटरेटर क्लोन करना चाहता हूं, लेकिन यह संकलित नहीं करता है।

तो, मुझे इसके बजाय क्या करना चाहिए?

+3

क्यों न केवल 'ऐरेलिस्ट ' का उपयोग क्यों करें? स्थिति का उपयोग कर एक एल्गोरिदम उस डेटा संरचना के साथ तुच्छ होगा। –

+0

क्या यह परिणाम ए के साथ खिलाड़ी ए जोड़ना नहीं होगा? –

+0

@ किर्क: हाँ, एक ऐरेलिस्ट काम करेगा, लेकिन चूंकि मुझे सूची के मध्य में खिलाड़ियों को सम्मिलित करना और निकालना पड़ सकता है, इसलिए मुझे एक लिंक्डलिस्ट चाहिए। –

उत्तर

25

निम्नलिखित यह करना होगा:

ListIterator<String> i1 = players.listIterator(0); 
while (i1.hasNext()) { 
    String p1 = i1.next(); 
    ListIterator<String> i2 = players.listIterator(i1.nextIndex()); 
    while (i2.hasNext()) { 
     String p2 = i2.next(); 
     System.out.println("Interact: " + p1 + ", " + p2); 
    } 
} 

यह ListIterator की दी गई स्थिति से शुरू करने के लिए और भी अपने मौजूदा स्थिति पता करने की क्षमता पर निर्भर करता है।

+1

ऐक्स फिर से हमला करता है। +1, सुंदर समाधान। – aioobe

+0

धन्यवाद! लेकिन, एक प्रश्न: सूचीइंटर (int) विधि कैसे काम करती है - यह सूची के शीर्ष पर शुरू नहीं होती है और दी गई स्थिति के लिए अपना रास्ता फिर से शुरू करती है, है ना? –

+3

@ थॉमसपैड्रॉन-मैककार्थी: यह इंटरफ़ेस के हिस्से के रूप में निर्दिष्ट नहीं है। हालांकि, लिंक की गई सूची की प्रकृति को लगभग निश्चित रूप से किया जाता है। दूसरी ओर, मुझे किसी भी समाधान से अवगत नहीं है जो इससे बच जाएगा। – NPE

2

aix answer के अलावा, मैं यह इंगित करना चाहता हूं कि हालांकि आप एक विशिष्ट इंडेक्स से शुरू होने वाला एक इटरेटर बनाते हैं, यह एक रैखिक ऑपरेशन होने के लिए बाध्य है। यदि ऐसा नहीं था, तो आप

elementN = createIterator(linkedList, N).next(); 

जो विरोधाभासी होगा का उपयोग कर लगातार समय में सूची में मनमाने ढंग से उपयोग कर सकते करने में सक्षम हो जाएगा।

अपनी स्थिति में मैं इसलिए मानते हैं कि सबसे कुशल समाधान वास्तव में हालांकि ऐसा करने के लिए

List<String> tmp = new ArrayList<String>(players); 
for (int p1 = 0; p1 < tmp.size(); p1++) 
    for (int p2 = p1+1; p2 < tmp.size(); p2++) 
     System.out.println("Interact: " + tmp.get(p1) + ", " + tmp.get(p2)); 

नोट हो सकता है, कि यह है अभी भी aix द्वारा समाधान के रूप में एक ही जटिलता; ओ (एन) लेकिन शायद एक छोटे स्थिर कारक के साथ।

+1

मैं असहमत हूं। यदि आपके पास इच्छित इंडेक्स को इंगित करने वाला एक इटेटरेटर है, तो आप इंटरफ़ेस परमिट के तुरंत बाद उस अनुक्रमणिका को तुरंत प्राप्त करने में सक्षम होना चाहिए। यह काल्पनिक 'i1.clone()' विधि 'ओ (1) 'होगी जबकि' players .listIterator (i1।अगला इंडेक्स()) 'ओ (एन)' है। 'क्लोन()' विधि क्लोन इटरेटर को उस नोड के साथ आपूर्ति करेगी जो वर्तमान में रखती है, सूची में उस बिंदु तक फिर से शुरू करने की आवश्यकता को समाप्त कर देती है। – anthropomorphic

+0

सिद्धांत रूप में आप सही हैं। काल्पनिक क्लोन विधि लागू करने के लिए तुच्छ होगी। इस मामले में, ओपी सबसे अधिक संभावना java.util.LinkedList का जिक्र कर रहा था जो क्लोनिंग का समर्थन नहीं करता है। इस विषय पर कई सवाल। उदाहरण के लिए देखें http://stackoverflow.com/questions/5963399/how-can-i-make-a-copy-of-an-iterator-in-java – aioobe

0

listIterator(int) (एनपीई का उत्तर) से जुड़े रैखिक लागत से बचने वाले समाधान के लिए, मेरे answer to a similar question देखें। संक्षेप में, जब तक आप सूची का दौरा करने के आदेश की परवाह नहीं करते हैं, तब तक आप अंतिम तत्व से बाहरी पाश शुरू कर सकते हैं और फिर से दोहरा सकते हैं, और पहले तत्व से आंतरिक पाश शुरू कर सकते हैं और दो पुनरावृत्तियों तक आगे बढ़ सकते हैं मिलते हैं। List.listIterator (list.size()) पर कॉल तेज़ है क्योंकि सूची एक लिंक्डलिस्ट है, यानी एक दोगुनी-लिंक्ड सूची है, और अंतिम तत्व तक पहुंचने के लिए सूची के माध्यम से पुनरावृत्ति की आवश्यकता नहीं है। नीचे उदाहरण देखें:

public static int iterRevIterator(List<Integer> list) { 
    int sum = 0; 
    for(ListIterator<Integer> outer = list.listIterator(list.size()); outer.hasPrevious();) { 
     Integer oVal = outer.previous(); 
     for(ListIterator<Integer> inner = list.listIterator(); inner.nextIndex() <= outer.previousIndex();) { 
      sum += oVal * inner.next(); 
     } 
    } 
    return sum; 
} 
संबंधित मुद्दे