मेरे वर्तमान सी ++ में के लिए की वजह से कोड की नकल - परियोजना मैं एक एसटीएल नक्शा जो वस्तुओं पर पूर्णांक कुंजी के नक्शे की है। एक एल्गोरिदम प्रविष्टियों का एक सेट देता है। दिए गए डेटा एल्गोरिथ्म के इनपुट पर निर्भर करता है और इसलिए भविष्यवाणी नहीं की जा सकती है:सी ++ एसटीएल: लापता आधार स्तरीय इटरेटर और reverse_iterator
class MyClass
{
//...
};
int myAlgorithm(vector<int>::iterator inputIt)
{
// return a key for myMap which is calculated by the current value of inputData
}
int main(int argc, char *argv[])
{
vector<int> inputData;
map<int, MyClass> myMap;
//<fill map with some data>
//<fill inputData>
vector<MyClass> result;
for (vector<int>::iterator it = inputData.begin(); it != inputData.end(); it++)
{
int myMapKey = myAlgorithm(*it);
// count() > 0 means "check whether element exists. Performance can be improved by replacing
// the operator[] and count() calls by map::find(). However, I want to simplify things
// in this example.
if (myMap.count(myMapKey) > 0)
{
// in some cases there is no entry in myMap
result.push_back(myMap[myMapKey]);
}
}
}
उदाहरण में उल्लेख किया है मुझे लगता है के साथ map::count()
और operator[]
-calls बदल सकते हैं। STL-reference कहता है कि नक्शा :: ढूंढें() की जटिलता आकार में लॉगरिदमिक है (O(log n)
)।
मुझे पता चला कि ज्यादातर मामलों में myMap में प्रविष्टियों परिणाम में दो सिलसिलेवार प्रविष्टियों के लिए बहुत करीब हैं। इसलिए मैं निष्कर्ष है कि मैं अपना प्रदर्शन सुधार होगा अगर मैं map.find (प्रतिस्थापित) के लिए आया था iterators द्वारा कॉल:
map<int, MyClass>::iterator myMapIt = myMap.begin();
for (vector<int>::iterator it = inputData.begin(); it != inputData.end(); it++)
{
int myMapKey = myAlgorithm(*it);
// just increment iterator
while (myMapKey != myMapIt->first)
{
myMapIt++;
// we didn't find anything for the current input data
if (myMapIt == myMap::end() || myMapIt->first > myMapKey)
{
break;
}
}
// I know that I'm checking this twice, but that's not the point of my
// question ;)
if (myMapIt == myMap::end() || myMapIt->first > myMapKey)
{
// probably it would be better to move the iterator back to the position
// where we started searching, to improve performance for the next entry
myMapIt = myMap.begin();
}
else
{
result.push_back(myMapIt.second);
}
}
इस अवधारणा काम करता है लेकिन मैं एक बड़ी समस्या है: inputData के आधार पर, मैं करने के लिए है आगे या पीछे खोजें। इस बात पर विचार करें कि मैं कोड को main()
के अंदर कई बार कॉल करता हूं और इनपुट कॉल इन कॉल के लिए बदलता है। को बढ़ा या while
-loop अंदर इटरेटर घटती है कि क्या जाँच करने के बजाय, मैं तय कर सकता है कि for
-loop प्रवेश करने से पहले।
मैंने सोचा था कि मैं सिर्फ map<>::reverse_iterator
करने के लिए map<>::iterator
स्विचिंग और rbegin()
/rend()
बजाय begin()
/end()
उपयोग करने के साथ ठीक हूँ। लेकिन तब मुझे एहसास हुआ कि reverse_iterator
और iterator
कोई आम आधार वर्ग है:
map<int, MyClass>::base_iterator myIt;
if (/* ... */)
{
myMapIt = myMap::begin();
myMapEndIt = myMap::end();
}
else
{
myMapIt = myMap::rbegin();
myMapEndIt = myMap::rend();
}
/* for (...) ... */
कि बहुत अच्छा होगा, लेकिन कोई base_iterator
है।
मैं इस समस्या के लिए एक सरल समाधान का पता: मैं बस दोनों ही मामलों के लिए पूरी for
-loop को कॉपी करें और समायोजित करने की आवश्यकता:
if (/* ... */)
{
/* for(...) which uses normal iterator in the while-loop */
}
else
{
/* for(...) which uses reverse iterator in the while-loop */
}
बहुत बुरा ... क्या आप एक बेहतर समाधान पता है?
फ़ंक्शन टेम्पलेट कार्य को कॉल करेगा? – PlasmaHH
आप इस निष्कर्ष पर कैसे पहुंचे कि आप बेहतर प्रदर्शन प्राप्त करेंगे? क्या आपके पास इसका बैक अप लेने के लिए डेटा है? यदि यह आपके आवेदन में वास्तविक बाधा नहीं है तो आप अपने लिए और अधिक काम कर सकते हैं। उस ने कहा, यह अभी भी एक दिलचस्प सवाल है। :) – Scott
'नक्शा :: ढूंढें()' का उपयोग करते समय ओ (लॉग एन) जटिलता के कारण जो यह मानने में सक्षम नहीं है कि अगली प्रविष्टि वर्तमान के करीब है। यह कोड बहुत ही महत्वपूर्ण स्थिति में है, कुछ नेस्टेड लूप – fishbone