আমার একটি স্টাড :: ভেক্টর <int> আছে, এবং আমি n'th উপাদানটি মুছতে চাই। আমি কেমন করে ঐটি করি?
std::vector<int> vec;
vec.push_back(6);
vec.push_back(-17);
vec.push_back(12);
vec.erase(???);
আমার একটি স্টাড :: ভেক্টর <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
ঘটতে থাকে তবে @QrtL গুলি আসলে সংকলন করতে পারে ...
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);
আপনি যদি ঘনিষ্ঠভাবে লক্ষ্য করেন তবে, vec.begin () আমাদের ভেক্টরের প্রারম্ভিক অবস্থানের জন্য কেবলমাত্র একটি পয়েন্টার এবং এতে i এর মান যুক্ত করে পয়েন্টারটিকে i পজিশনে বৃদ্ধি করে, সুতরাং পরিবর্তে আমরা আইথ উপাদানটিতে পয়েন্টারটি অ্যাক্সেস করতে পারি:
&vec[i]
সুতরাং আমরা লিখতে পারি:
vec.erase(&vec[i]); // To delete the ith element
যদি আপনার কোনও অ-নিরক্ষিত ভেক্টর থাকে তবে আপনি এটি আনর্ডারড হওয়া এবং আপনি সিপিপিসন-এ ড্যান হিগিন্সের কাছ থেকে দেখেছি এমন কিছু ব্যবহার করতে পারেন advantage
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;
}
যেহেতু তালিকার অর্ডারটি কোনও বিষয় নয়, কেবলমাত্র তালিকার সর্বশেষ উপাদানটি নিন এবং আপনি যে আইটেমটি সরাতে চান তার উপরে এটি অনুলিপি করুন, তারপরে শেষ আইটেমটি পপ করুন এবং মুছুন delete
iterator + index
আপনাকে সেই সূচকটিতে পুনরাবৃত্তি অবস্থানটি ফিরিয়ে দেবে, যা সমস্ত পুনরাবৃত্তিযোগ্য ধারকগুলির ক্ষেত্রে সত্য নয়। এটি ব্যাক পয়েন্টারের সুবিধা গ্রহণ করে লিনিয়ার পরিবর্তে স্থির জটিলতা।
unordered_remove
এবং unordered_remove_if
... যতক্ষণ না এটি হয়েছে এবং আমি এটি মিস করেছি, যা এই দিনগুলিতে বেশি বেশি
std::remove
কনটেইনারটি পুনরায় অর্ডার করে যাতে সরানো সমস্ত উপাদানগুলি শেষে হয়, আপনি যদি সি ++ 17 ব্যবহার করেন তবে ম্যানুয়ালি এটি করার দরকার নেই
std::remove
সাহায্য করে? সিপ্রেফারেন্স দাবি করে যে এমনকি সি ++ 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;
}
কোডটি ভিসিতে প্রতিটি সংখ্যা নেয় যা 3 দ্বারা ভাগ করা যায় না এবং এটি ভিস 2 তে অনুলিপি করে। এরপরে এটি ভিসি-তে কপি করে। এটি বেশ দ্রুত। 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);
আপনি ভেক্টরের এন-তম উপাদানটি মুছবেন তবে যখন আপনি দ্বিতীয় উপাদানটি মুছবেন তখন ভেক্টরের অন্যান্য সমস্ত উপাদান স্থানান্তরিত হবে এবং ভেক্টরের আকার -1 হবে। ভেক্টরের আকার () হ্রাস হওয়ায় আপনি যদি ভেক্টরের মধ্য দিয়ে লুপ করেন তবে এটি সমস্যা হতে পারে। আপনার যদি এইর মতো সমস্যা থাকে তবে স্ট্যান্ডার্ড সি ++ লাইব্রেরিতে বিদ্যমান অ্যালগরিদম ব্যবহার করার পরামর্শ দেওয়া হয়েছে। এবং "অপসারণ" বা "মুছে ফেলা"
আশা করি এটি সাহায্য করেছে
পূর্ববর্তী উত্তরগুলি ধরে নিয়েছে যে আপনার কাছে সর্বদা স্বাক্ষরিত সূচি থাকে। দুঃখের বিষয়, সূচকের জন্য 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 সেকেন্ডে 100 এম আইটেম মুছতে পারে;
vector<int> it = (vector<int>::iterator) &vec[pos];
vec.erase(it);
এবং সর্বাধিক পঠনযোগ্য উপায়:
vec.erase(vec.begin() + pos);
vector<int>::iterator
অগত্যা একইরকম নয়int *