আমি যা করতে চাই তা হ'ল ভেক্টরে কোনও উপাদান রয়েছে কিনা তা যাচাই করা, যাতে আমি প্রতিটি ক্ষেত্রে মোকাবেলা করতে পারি।
if ( item_present )
do_this();
else
do_that();
আমি যা করতে চাই তা হ'ল ভেক্টরে কোনও উপাদান রয়েছে কিনা তা যাচাই করা, যাতে আমি প্রতিটি ক্ষেত্রে মোকাবেলা করতে পারি।
if ( item_present )
do_this();
else
do_that();
উত্তর:
আপনি এর std::find
থেকে ব্যবহার করতে পারেন <algorithm>
:
#include <vector>
vector<int> vec;
//can have other data types instead of int but must same datatype as item
std::find(vec.begin(), vec.end(), item) != vec.end()
এটি একটি বিল দেয় ( true
যদি উপস্থিত থাকে তবে false
অন্যথায়)। আপনার উদাহরণ সহ:
#include <algorithm>
#include <vector>
if ( std::find(vec.begin(), vec.end(), item) != vec.end() )
do_this();
else
do_that();
#include <algorithm>
অন্যথায় আপনি খুব অদ্ভুত ত্রুটি পেতে পারেন যেমন 'নেমস্পেস
.find()
এখনও এর সদস্য ফাংশন নয়std::vector
, যেমনটি আপনি আশা করেছিলেন যে এটি হওয়া উচিত? আমি ভাবছি যদি এটি কোনওভাবেই টেম্প্লেটিংয়ের পরিণতি হয়।
std::vector<>::find()
কোনও সুবিধা দেয় না, প্রয়োজনও হয় না, সুতরাং এটির সদস্য হওয়া উচিত নয়। আরও দেখুন en.wikedia.org/wiki/Coupling_%28computer_programming%29
mvec.find(key) != mvec.cend()
চেয়ে ভাল std::find(mvec.cbegin(), mvec.cend(), key) != mvec.cend()
।
অন্যরা যেমন বলেছে, এসটিএল find
বা find_if
ফাংশন ব্যবহার করুন । কিন্তু আপনি যদি ও খুব বড় ভেক্টর মধ্যে অনুসন্ধান করা হয় এই প্রভাব কর্মক্ষমতা, আপনি আপনার ভেক্টর বাছাই এবং তারপর ব্যবহার করতে পারেন binary_search
, lower_bound
অথবাupper_bound
আলগোরিদিম।
Stl এর অ্যালগরিদম শিরোনামটি থেকে অনুসন্ধানটি ব্যবহার করুন I আমি এর ব্যবহারটি টাইপ দিয়ে চিত্রিত করেছি। আপনি যতক্ষণ না সাম্যতার জন্য তুলনা করতে পারেন আপনার পছন্দ মতো কোনও প্রকারের ব্যবহার করতে পারেন (ওভারলোড == আপনার কাস্টম শ্রেণীর জন্য আপনার প্রয়োজন হলে)।
#include <algorithm>
#include <vector>
using namespace std;
int main()
{
typedef vector<int> IntContainer;
typedef IntContainer::iterator IntIterator;
IntContainer vw;
//...
// find 5
IntIterator i = find(vw.begin(), vw.end(), 5);
if (i != vw.end()) {
// found it
} else {
// doesn't exist
}
return 0;
}
যদি আপনার ভেক্টরকে অর্ডার না দেওয়া হয় তবে এমএসএন প্রস্তাবিত পদ্ধতির ব্যবহার করুন:
if(std::find(vector.begin(), vector.end(), item)!=vector.end()){
// Found the item
}
যদি আপনার ভেক্টরকে অর্ডার দেওয়া হয় তবে বাইনারি_সার্চ পদ্ধতিটি ব্যবহার করুন ব্রায়ান নিল প্রস্তাবিত:
if(binary_search(vector.begin(), vector.end(), item)){
// Found the item
}
বাইনারি অনুসন্ধান ও (লগ এন) সবচেয়ে খারাপ ক্ষেত্রে পারফরম্যান্স দেয় যা প্রথম পদ্ধতির চেয়ে বেশ দক্ষ efficient বাইনারি অনুসন্ধান ব্যবহার করার জন্য, আপনি আদেশটি দেওয়ার গ্যারান্টি দেওয়ার জন্য প্রথমে ভেক্টরকে বাছাই করার জন্য Qsort ব্যবহার করতে পারেন।
আমি এরকম কিছু ব্যবহার করি ...
#include <algorithm>
template <typename T>
const bool Contains( std::vector<T>& Vec, const T& Element )
{
if (std::find(Vec.begin(), Vec.end(), Element) != Vec.end())
return true;
return false;
}
if (Contains(vector,item))
blah
else
blah
... সেভাবে এটি আসলে পরিষ্কার এবং পাঠযোগ্য। (স্পষ্টতই আপনি একাধিক জায়গায় টেম্পলেটটি পুনরায় ব্যবহার করতে পারেন)।
value_type
উপাদান ধরণের জন্য ধারক থেকে ব্যবহার করেন তবে আপনি 1 টি টেম্পলেট যুক্তি দিয়ে সরে যেতে পারেন । আমি এর মতো একটি উত্তর যুক্ত করেছি।
সি ++ 11 এ আপনি ব্যবহার করতে পারেন any_of
। উদাহরণস্বরূপ যদি এটি হয় vector<string> v;
তবে:
if (any_of(v.begin(), v.end(), bind(equal_to<string>(), _1, item)))
do_this();
else
do_that();
বিকল্পভাবে, একটি ল্যাম্বডা ব্যবহার করুন:
if (any_of(v.begin(), v.end(), [&](const std::string& elem) { return elem == item; }))
do_this();
else
do_that();
bind1st
এবং bind2nd
করছে সি যেহেতু ++, 11 অবচিত এবং সম্পূর্ণরূপে C ++ 17 সরানো হয়েছে। ব্যবহার করুন bind
সঙ্গে placeholders
এবং / অথবা পরিবর্তে lambdas।
এখানে একটি ফাংশন যা কোনও কনটেইনারটির জন্য কাজ করবে:
template <class Container>
const bool contains(const Container& container, const typename Container::value_type& element)
{
return std::find(container.begin(), container.end(), element) != container.end();
}
নোট করুন যে আপনি 1 টি টেম্পলেট প্যারামিটার নিয়ে চলে যেতে পারেন কারণ আপনি value_type
ধারক থেকে এটিটি বের করতে পারেন । আপনার প্রয়োজন typename
কারণ Container::value_type
একটি নির্ভরশীল নাম ।
মনে রাখবেন যে, আপনি যদি অনেকগুলি অনুসন্ধান করতে যাচ্ছেন তবে এমন এসটিএল পাত্রে রয়েছে যে এটির জন্য ভাল। আপনার অ্যাপ্লিকেশন কী তা আমি জানি না, তবে এসটিডি :: মানচিত্রের মতো সাহসী পাত্রগুলি বিবেচনা করার মতো হতে পারে।
std :: ভেক্টর হ'ল পছন্দের ধারক না হয়ে থাকে যদি না আপনি অন্য কারার কারণ হয়ে থাকেন এবং মান অনুসারে অনুসন্ধানগুলি এর কারণ হতে পারে।
এসটিএল অনুসন্ধানটি ব্যবহার করুন ফাংশন।
মনে রাখবেন যে একটি সন্ধান_আইএফ ফাংশন রয়েছে, যা আপনার অনুসন্ধান আরও জটিল হলে আপনি ব্যবহার করতে পারেন, উদাহরণস্বরূপ, যদি আপনি কেবল কোনও উপাদান অনুসন্ধান করেন না, তবে উদাহরণস্বরূপ, এমন কোনও উপাদান রয়েছে যা নির্দিষ্ট কিছু পূরণ করে কিনা তা দেখতে চান শর্ত, উদাহরণস্বরূপ, একটি স্ট্রিং যা "abc" দিয়ে শুরু হয়। ( find_if
আপনাকে এমন একটি পুনরাবৃত্তি দেবে যা এই জাতীয় উপাদানটিকে প্রথম দেখায়)।
বুস্ট দিয়ে আপনি ব্যবহার করতে পারেন any_of_equal
:
#include <boost/algorithm/cxx11/any_of.hpp>
bool item_present = boost::algorithm::any_of_equal(vector, element);
আপনি এই কোড চেষ্টা করতে পারেন:
#include <algorithm>
#include <vector>
// You can use class, struct or primitive data type for Item
struct Item {
//Some fields
};
typedef std::vector<Item> ItemVector;
typedef ItemVector::iterator ItemIterator;
//...
ItemVector vtItem;
//... (init data for vtItem)
Item itemToFind;
//...
ItemIterator itemItr;
itemItr = std::find(vtItem.begin(), vtItem.end(), itemToFind);
if (itemItr != vtItem.end()) {
// Item found
// doThis()
}
else {
// Item not found
// doThat()
}
নেমস্পেসে find
পাওয়া ফাংশনটি আপনি ব্যবহার করতে পারেন std
, যেমন std::find
। আপনি যে ভেক্টরটি সন্ধান করতে চান তার কাছ থেকে এবং পুনরুদ্ধারটি std::find
ফাংশনটি পাস করুন begin
এবং end
আপনি যে উপাদানটি সন্ধান করছেন তা বরাবর এবং ফলস্বরূপ পুনরাবৃত্তিকে ভেক্টরের শেষের সাথে তুলনা করে দেখুন তারা মিলছে কি না।
std::find(vector.begin(), vector.end(), item) != vector.end()
আপনি সেই পুনরুক্তিটিকে অবনমিত করতে এবং অন্য যে কোনও পুনরুক্তকারীর মতো এটিকে স্বাভাবিক হিসাবে ব্যবহার করতে সক্ষম হন।
আপনিও গণনা ব্যবহার করতে পারেন। এটি কোনও ভেক্টরে উপস্থিত আইটেমগুলির সংখ্যা ফিরিয়ে দেবে।
int t=count(vec.begin(),vec.end(),item);
find
এর চেয়ে দ্রুততর count
, কারণ এটি প্রথম ম্যাচের পরে গণনা অব্যাহত রাখে না।
সি ++ অপারেটর ব্যবহার করে অন্য একটি নমুনা।
#include <vector>
#include <algorithm>
#include <stdexcept>
template<typename T>
inline static bool operator ==(const std::vector<T>& v, const T& elem)
{
return (std::find(v.begin(), v.end(), elem) != v.end());
}
template<typename T>
inline static bool operator !=(const std::vector<T>& v, const T& elem)
{
return (std::find(v.begin(), v.end(), elem) == v.end());
}
enum CODEC_ID {
CODEC_ID_AAC,
CODEC_ID_AC3,
CODEC_ID_H262,
CODEC_ID_H263,
CODEC_ID_H264,
CODEC_ID_H265,
CODEC_ID_MAX
};
void main()
{
CODEC_ID codec = CODEC_ID_H264;
std::vector<CODEC_ID> codec_list;
codec_list.reserve(CODEC_ID_MAX);
codec_list.push_back(CODEC_ID_AAC);
codec_list.push_back(CODEC_ID_AC3);
codec_list.push_back(CODEC_ID_H262);
codec_list.push_back(CODEC_ID_H263);
codec_list.push_back(CODEC_ID_H264);
codec_list.push_back(CODEC_ID_H265);
if (codec_list != codec)
{
throw std::runtime_error("codec not found!");
}
if (codec_list == codec)
{
throw std::logic_error("codec has been found!");
}
}
template <typename T> bool IsInVector(T what, std::vector<T> * vec)
{
if(std::find(vec->begin(),vec->end(),what)!=vec->end())
return true;
return false;
}
(সি ++ 17 এবং উপরে):
ব্যবহার করতে পারেন std::search
এছাড়াও
এটি উপাদানগুলির ক্রম অনুসন্ধানের জন্যও কার্যকর।
#include <algorithm>
#include <iostream>
#include <vector>
template <typename Container>
bool search_vector(const Container& vec, const Container& searchvec)
{
return std::search(vec.begin(), vec.end(), searchvec.begin(), searchvec.end()) != vec.end();
}
int main()
{
std::vector<int> v = {2,4,6,8};
//THIS WORKS. SEARCHING ONLY ONE ELEMENT.
std::vector<int> searchVector1 = {2};
if(search_vector(v,searchVector1))
std::cout<<"searchVector1 found"<<std::endl;
else
std::cout<<"searchVector1 not found"<<std::endl;
//THIS WORKS, AS THE ELEMENTS ARE SEQUENTIAL.
std::vector<int> searchVector2 = {6,8};
if(search_vector(v,searchVector2))
std::cout<<"searchVector2 found"<<std::endl;
else
std::cout<<"searchVector2 not found"<<std::endl;
//THIS WILL NOT WORK, AS THE ELEMENTS ARE NOT SEQUENTIAL.
std::vector<int> searchVector3 = {8,6};
if(search_vector(v,searchVector3))
std::cout<<"searchVector3 found"<<std::endl;
else
std::cout<<"searchVector3 not found"<<std::endl;
}
এছাড়াও কিছু অনুসন্ধান অ্যালগরিদম পাস করার নমনীয়তা রয়েছে। এখানে উল্লেখ করুন।
আমি ব্যক্তিগতভাবে কেবলমাত্র ভেক্টরদের সাথে ডিল করার পরিবর্তে একাধিক ধরণের পাত্রে হ্যান্ডেল করার জন্য দেরির টেমপ্লেটগুলি ব্যবহার করেছি। আমি অনলাইনে একটি অনুরূপ উদাহরণ খুঁজে পেয়েছি (কোথায় তা মনে করতে পারে না) তাই যার যার কাছ থেকে আমি এটি চালিয়েছি তার creditণ যায়। এই নির্দিষ্ট প্যাটার্নটি কাঁচা অ্যারেগুলিও হ্যান্ডেল করে বলে মনে হচ্ছে।
template <typename Container, typename T = typename std::decay<decltype(*std::begin(std::declval<Container>()))>::type>
bool contains(Container && c, T v)
{
return std::find(std::begin(c), std::end(c), v) != std::end(c);
}
নিউটন সি ++ ব্যবহার করে স্ট্যান্ড :: এর চেয়ে সহজ, স্ব-ডকুমেন্টেড এবং দ্রুত ::
bool exists_linear( INPUT_ITERATOR first, INPUT_ITERATOR last, const T& value )
bool exists_binary( INPUT_ITERATOR first, INPUT_ITERATOR last, const T& value )
আমি মনে করি এটি কার্যকারিতা কী করে তা স্পষ্ট।
include <newton/algorithm/algorithm.hpp>
if ( newton::exists_linear(first, last, value) )
do_this();
else
do_that();