एक सूची में एक निश्चित तत्व कैसे प्राप्त किया जाए, स्थिति को देखते हुए?


92

इसलिए मुझे एक सूची मिली है:

list<Object> myList;
myList.push_back(Object myObject);

मुझे यकीन नहीं है, लेकिन मुझे विश्वास है कि यह सरणी में "0 वां" तत्व होगा। क्या कोई फ़ंक्शन है जो मैं उपयोग कर सकता हूं जो "myObject" लौटाएगा?

Object copy = myList.find_element(0);

?


8
कोई सरणी नहीं है - यह एक सूची है। यदि आप पूर्णांक द्वारा अनुक्रमण करना चाहते हैं, तो vectorइसके बजाय आप इसका उपयोग क्यों नहीं करते ?
पॉल जे। लुकास

2
यदि आप हमेशा तत्व 0 चाहते हैं, तो उपयोग करें front()
पॉल जे। लुकास

मैंने इसका परीक्षण नहीं किया है, लेकिन मुझे लगता है कि myList.front () + num यहां काम करेगा
Serguei Fedorov

2
@SergueiFedorov: नहीं, यह नहीं है
Algoman 27:56 15:56

जवाबों:


129

यदि आपको अक्सर किसी अनुक्रम के Nth तत्व तक पहुंचने की आवश्यकता होती है std::list, जिसे एक दोहरी लिंक की गई सूची के रूप में कार्यान्वित किया जाता है, तो शायद सही विकल्प नहीं है। std::vectorया std::dequeबेहतर होगा।

उस ने कहा, आप Nth तत्व का उपयोग करके एक पुनरावृत्ति प्राप्त कर सकते हैं std::advance:

std::list<Object> l;
// add elements to list 'l'...

unsigned N = /* index of the element you want to retrieve */;
if (l.size() > N)
{
    std::list<Object>::iterator it = l.begin();
    std::advance(it, N);
    // 'it' points to the element at index 'N'
}

एक कंटेनर के लिए जो रैंडम एक्सेस प्रदान नहीं करता है, जैसे std::list, पुनरावृत्त समय पर std::advanceकॉल । वैकल्पिक रूप से, यदि आपका मानक पुस्तकालय कार्यान्वयन इसे प्रदान करता है, तो आप कॉल कर सकते हैं :operator++Nstd::next

if (l.size() > N)
{
    std::list<Object>::iterator it = std::next(l.begin(), N);
}

std::nextप्रभावी ढंग से एक कॉल को लपेटता है std::advance, जिससे Nकोड की कम लाइनों और कम उत्परिवर्तनीय चर के साथ एक पुनरावृत्त समय को आगे बढ़ाना आसान हो जाता है । std::nextC ++ 11 में जोड़ा गया था।


18
जब आप रैंडम एक्सेस की कमी के कारण लिंक की गई सूची को खोजने के लिए एक पेनल्टी पेनल्टी का भुगतान करते हैं, तो आप एक वेक्टर या डीके के बीच में डेटा डालने या निकालने की आवश्यकता होने पर एक बहुत बड़ा प्रदर्शन पेनल्टी देते हैं। प्रश्न में वास्तव में यह तय करने के लिए पर्याप्त जानकारी नहीं है कि क्या वे अपने उद्देश्यों के लिए आदर्श कंटेनर का उपयोग कर रहे हैं।
क्लोच

1
यह ध्यान देने योग्य है कि उपयोग करते समय std::advanceया std::next, यूबी को लागू करना आसान है। कोई सीमा जाँच नहीं है।
ओकोवो

33

std::listतत्व को इंडेक्स देने के लिए कोई फ़ंक्शन प्रदान नहीं करता है। आप इसे कुछ कोड लिखकर प्राप्त करने का प्रयास कर सकते हैं, जिसकी मैं अनुशंसा नहीं करूंगा, क्योंकि अगर आपको अक्सर ऐसा करने की आवश्यकता होती है, तो यह अक्षम होगा।

क्या आप की जरूरत है: std::vector। इसे इस रूप में उपयोग करें:

std::vector<Object> objects;
objects.push_back(myObject);

Object const & x = objects[0];    //index isn't checked
Object const & y = objects.at(0); //index is checked 

7
std::list<Object> l; 
std::list<Object>::iterator ptr;
int i;

for( i = 0 , ptr = l.begin() ; i < N && ptr != l.end() ; i++ , ptr++ );

if( ptr == l.end() ) {
    // list too short  
} else {
    // 'ptr' points to N-th element of list
}

3

शायद सबसे कुशल तरीका नहीं है। लेकिन आप सूची को वेक्टर में बदल सकते हैं।

#include <list>
#include <vector>

list<Object> myList;

vector<Object> myVector(myList.begin(), myList.end());

फिर [x] ऑपरेटर का उपयोग करके वेक्टर तक पहुंचें।

auto x = MyVector[0];

आप एक सहायक समारोह में रख सकते हैं:

#include <memory>
#include <vector>
#include <list>

template<class T>
shared_ptr<vector<T>> 
ListToVector(list<T> List) {
shared_ptr<vector<T>> Vector {
        new vector<string>(List.begin(), List.end()) }
return Vector;
}

तो इस तरह हेल्पर funciton का उपयोग करें:

auto MyVector = ListToVector(Object);
auto x = MyVector[0];
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.