मेरे पास एक std :: वेक्टर <int> है, और मैं n'th तत्व को हटाना चाहता हूं। मैं उसको कैसे करू?
std::vector<int> vec;
vec.push_back(6);
vec.push_back(-17);
vec.push_back(12);
vec.erase(???);
मेरे पास एक std :: वेक्टर <int> है, और मैं n'th तत्व को हटाना चाहता हूं। मैं उसको कैसे करू?
std::vector<int> vec;
vec.push_back(6);
vec.push_back(-17);
vec.push_back(12);
vec.erase(???);
जवाबों:
किसी एक तत्व को हटाने के लिए, आप यह कर सकते हैं:
std::vector<int> vec;
vec.push_back(6);
vec.push_back(-17);
vec.push_back(12);
// Deletes the second element (vec[1])
vec.erase(vec.begin() + 1);
या, एक से अधिक तत्वों को एक साथ हटाने के लिए:
// Deletes the second through third elements (vec[1], vec[2])
vec.erase(vec.begin() + 1, vec.begin() + 3);
operator+
है नहीं जरूरी अन्य कंटेनर प्रकार पर iterators के लिए परिभाषित किया, जैसे list<T>::iterator
(आप ऐसा नहीं कर सकते list.begin() + 2
एक पर std::list
, आप का उपयोग करने के std::advance
लिए है कि)
std::find_if
एसटीडी पर मिटा विधि :: वेक्टर अतिभारित है, इसलिए यह संभवतः कॉल करने के लिए स्पष्ट है
vec.erase(vec.begin() + index);
जब आप केवल एक ही तत्व को मिटाना चाहते हैं।
vec.begin()
जो वैध है।
vec.erase(0)
काम नहीं करता, लेकिन vec.erase(vec.begin()+0)
(या बिना +0) करता है। अन्यथा मुझे कोई मेलिंग फंक्शन कॉल नहीं मिलता है, यही वजह है कि मैं यहां आया था
vec.erase(0)
वास्तव में संकलित कर सकता है यदि 0
ऐसा होता है कि इसे शून्य सूचक स्थिरांक के रूप में व्याख्यायित किया जाता है ...
template <typename T>
void remove(std::vector<T>& vec, size_t pos)
{
std::vector<T>::iterator it = vec.begin();
std::advance(it, pos);
vec.erase(it);
}
template <typename T> void remove(std::vector<T>& vec, size_t pos) { vec.erase(vec.begin + pos); }
मैं या तो बेहतर नहीं कह रहा हूं, केवल व्यक्तिगत हित से बाहर पूछ रहा हूं और सबसे अच्छा परिणाम वापस करने के लिए यह प्रश्न हो सकता है।
vector<T>::iterator
रैंडम-एक्सेस इटरेटर है, इसलिए आपका संस्करण ठीक है और शायद थोड़ा साफ है। लेकिन जो संस्करण मैक्स ने पोस्ट किया है वह ठीक काम करना चाहिए यदि आप कंटेनर को दूसरे में बदलते हैं जो रैंडम-एक्सेस पुनरावृत्तियों का समर्थन नहीं करता है
erase
विधि को दो तरह से उपयोग किया जाएगा:
एकल तत्व को मिटा देना:
vector.erase( vector.begin() + 3 ); // Deleting the fourth element
तत्वों की श्रेणी को मिटाना:
vector.erase( vector.begin() + 3, vector.begin() + 5 ); // Deleting from fourth element to sixth element
दरअसल, erase
फंक्शन दो प्रोफाइल के लिए काम करता है:
किसी एक तत्व को हटाना
iterator erase (iterator position);
तत्वों की एक सीमा को हटाना
iterator erase (iterator first, iterator last);
चूंकि std :: vec.begin () कंटेनर की शुरुआत को चिह्नित करता है और यदि हम अपने वेक्टर में ith तत्व को हटाना चाहते हैं, तो हम यह कर सकते हैं:
vec.erase(vec.begin() + index);
यदि आप निकट से देखते हैं, तो वेजबिन () हमारे वेक्टर की शुरुआती स्थिति के लिए एक संकेतक है और इसमें i का मान जोड़कर पॉइंटर को i स्थिति में ले जाता है, इसलिए इसके बजाय हम पॉइंटर को ith तत्व तक एक्सेस कर सकते हैं:
&vec[i]
तो हम लिख सकते हैं:
vec.erase(&vec[i]); // To delete the ith element
यदि आपके पास एक अनियंत्रित वेक्टर है, तो आप इस तथ्य का लाभ उठा सकते हैं कि यह अनियंत्रित है और CPPCON से डैन हिगिंस से देखी गई किसी चीज़ का उपयोग करें
template< typename TContainer >
static bool EraseFromUnorderedByIndex( TContainer& inContainer, size_t inIndex )
{
if ( inIndex < inContainer.size() )
{
if ( inIndex != inContainer.size() - 1 )
inContainer[inIndex] = inContainer.back();
inContainer.pop_back();
return true;
}
return false;
}
चूंकि सूची क्रम कोई मायने नहीं रखता है, बस सूची में अंतिम तत्व लें और उस आइटम के शीर्ष पर प्रतिलिपि करें जिसे आप निकालना चाहते हैं, फिर अंतिम आइटम को पॉप और हटाएं।
iterator + index
वास्तव में आपको उस सूचकांक में पुनरावृत्ति की स्थिति प्रदान करेगा, जो सभी पुनरावृत्त कंटेनरों के लिए सही नहीं है। यह बैक पॉइंटर का लाभ उठाकर रैखिक के बजाय निरंतर जटिलता भी है।
unordered_remove
और unordered_remove_if
जब तक यह नहीं हुआ है और मुझे यह याद नहीं है, जो इन दिनों अधिक से अधिक बार हो रहा है :)
std::remove
कंटेनर को फिर से चालू करें ताकि निकाले जाने वाले सभी तत्व अंत में हों, इसे मैन्युअल रूप से करने की आवश्यकता नहीं है यदि आप C ++ 17 का उपयोग कर रहे हैं।
std::remove
मदद करता है? cppreference का दावा है कि C ++ 17 में भी, सभी remove
अधिभार को एक विधेय की आवश्यकता होती है, और कोई भी एक सूचकांक नहीं लेता है।
यदि आप बड़े वैक्टर (आकार> 100,000) के साथ काम करते हैं और बहुत सारे तत्वों को हटाना चाहते हैं, तो मैं इस तरह से कुछ करने की सलाह दूंगा:
int main(int argc, char** argv) {
vector <int> vec;
vector <int> vec2;
for (int i = 0; i < 20000000; i++){
vec.push_back(i);}
for (int i = 0; i < vec.size(); i++)
{
if(vec.at(i) %3 != 0)
vec2.push_back(i);
}
vec = vec2;
cout << vec.size() << endl;
}
कोड vec में प्रत्येक संख्या लेता है जिसे 3 से विभाजित नहीं किया जा सकता है और इसे vec2 में कॉपी कर सकता है। बाद में यह vec में vec2 को कॉपी करता है। यह बहुत तेज है। 20,000,000 तत्वों को संसाधित करने के लिए यह एल्गोरिथ्म केवल 0.8 सेकंड लेता है!
मैंने इरेज़-मेथड के साथ एक ही काम किया, और इसमें बहुत सारे और बहुत समय लगता है:
Erase-Version (10k elements) : 0.04 sec
Erase-Version (100k elements) : 0.6 sec
Erase-Version (1000k elements): 56 sec
Erase-Version (10000k elements): ...still calculating (>30 min)
किसी तत्व को हटाने के लिए निम्न तरीके का उपयोग करें:
// declaring and assigning array1
std:vector<int> array1 {0,2,3,4};
// erasing the value in the array
array1.erase(array1.begin()+n);
एक के लिए और अधिक विस्तृत अवलोकन आप यात्रा कर सकते हैं: http://www.cplusplus.com/reference/vector/vector/erase/
मैं इसे पढ़ने का सुझाव देता हूं क्योंकि मेरा मानना है कि आप वही चाहते हैं जो आप खोज रहे हैं। https://en.wikipedia.org/wiki/Erase%E2%80%93remove_idiom
यदि आप उदाहरण के लिए उपयोग करते हैं
vec.erase(vec.begin() + 1, vec.begin() + 3);
आप वेक्टर के n -th तत्व को मिटा देंगे, लेकिन जब आप दूसरे तत्व को मिटा देंगे, तो वेक्टर के अन्य सभी तत्व स्थानांतरित हो जाएंगे और वेक्टर का आकार -1 हो जाएगा। यह समस्या हो सकती है यदि आप वेक्टर के माध्यम से लूप करते हैं क्योंकि वेक्टर आकार () कम हो रहा है। यदि आपके पास इस तरह की समस्या है, तो मानक C ++ लाइब्रेरी में मौजूदा एल्गोरिदम का उपयोग करने के लिए दिए गए लिंक का सुझाव दिया गया है। और "हटाएं" या "remove_if"।
उम्मीद है कि इससे मदद मिली
पिछले उत्तर मान लेते हैं कि आपके पास हमेशा एक हस्ताक्षरित सूचकांक है। अफसोस की बात है, अनुक्रमण के लिए std::vector
उपयोग करता size_type
है, औरdifference_type
इटरेटर अंकगणित के लिए, इसलिए वे एक साथ काम नहीं करते हैं यदि आपके पास "-Wconversion" और मित्र सक्षम हैं। यह हस्ताक्षरित और अहस्ताक्षरित दोनों को संभालने में सक्षम होते हुए, सवाल का जवाब देने का एक और तरीका है:
दूर करना:
template<class T, class I, class = typename std::enable_if<std::is_integral<I>::value>::type>
void remove(std::vector<T> &v, I index)
{
const auto &iter = v.cbegin() + gsl::narrow_cast<typename std::vector<T>::difference_type>(index);
v.erase(iter);
}
लेना:
template<class T, class I, class = typename std::enable_if<std::is_integral<I>::value>::type>
T take(std::vector<T> &v, I index)
{
const auto &iter = v.cbegin() + gsl::narrow_cast<typename std::vector<T>::difference_type>(index);
auto val = *iter;
v.erase(iter);
return val;
}
यहाँ ऐसा करने का एक और तरीका है यदि आप वेक्टर में इसके मान के साथ किसी तत्व को हटाना चाहते हैं, तो आपको बस वेक्टर पर ऐसा करने की आवश्यकता है।
vector<int> ar(n);
ar.erase(remove(ar.begin(), ar.end()), (place your value here from vector array));
यह आपके मूल्य को यहां से हटा देगा। धन्यवाद
सबसे तेज तरीका (समय की जटिलता से प्रोग्रामिंग प्रतियोगिता के लिए) = स्थिर)
1 सेकंड में 100M आइटम मिटा सकते हैं;
vector<int> it = (vector<int>::iterator) &vec[pos];
vec.erase(it);
और सबसे पठनीय तरीका:
vec.erase(vec.begin() + pos);
vector<int>::iterator
जरूरी नहीं है किint *