প্রদত্ত কীটি কোনও সি ++ এসডিডি :: মানচিত্রে উপস্থিত রয়েছে কীভাবে তা সন্ধান করবেন


449

আমি প্রদত্ত কীটি কোনও মানচিত্রে রয়েছে কিনা তা যাচাই করার চেষ্টা করছি এবং কিছুটা এটি করতে পারে না:

typedef map<string,string>::iterator mi;
map<string, string> m;
m.insert(make_pair("f","++--"));
pair<mi,mi> p = m.equal_range("f");//I'm not sure if equal_range does what I want
cout << p.first;//I'm getting error here

সুতরাং আমি কীভাবে মুদ্রণ করতে পারি?


std::pair<iterator,bool> insert( const value_type& value );এটি ফিরে আসে কি বুল? এটি কি বলে, কীটি যদি ইতিমধ্যে উপস্থিত থাকে বা না থাকে?
কৃতিকাগোপালকৃষ্ণন

উত্তর:


691

ব্যবহার map::find

if ( m.find("f") == m.end() ) {
  // not found
} else {
  // found
}

105
আপনি যদি কেবল কোনও নির্দিষ্ট কী উপস্থিত আছে কিনা তা পরীক্ষা করতে চান তবে আপনি সম্ভবত ব্যবহার করতে চানmap::count
টমসডিং

10
@ টমসমিডিং একটি স্ট্যান্ড :: ম্যাপে কেবল একটি একক কী আছে। সুতরাং গণনা হয় হয় 0 বা 1। এক অন্য তুলনায় আরও দক্ষ?
গোলেখ

34
@গোলাকাশ শক্তভাবেই; এটা ঠিক যে countআয় একটি intসময় findএকটি সম্পূর্ণ পুনরুক্তিকারীর ফেরৎ। আপনি পরে করতে যাচ্ছি, তাহলে একথাও ঠিক যে পুনরুক্তিকারীর :) নির্মাণের সংরক্ষণ ব্যবহার মান যদি উপস্থিত থাকে, ব্যবহার খোঁজ এবং তার ফলাফলের সংরক্ষণ করি।
টমসডিং

9
@ টমসমিডিং আপনি যদি কোনও মাল্টিম্যাপ ব্যবহার করছেন তবে আপনাকে পুরো ধারকটি দেখতে হবে। যে ক্ষেত্রে, () দ্রুততর হতে পারে।
ট্রেভর হিকি

11
যারা গতি খুঁজছেন তাদের কাছে: count এবং findঅনন্য কীগুলির প্রয়োজন এমন মানচিত্র ব্যবহার করার সময় গতিতে প্রায় অভিন্ন। (1) নির্দিষ্ট অর্ডার বজায় রাখার জন্য আপনার যদি উপাদানগুলির প্রয়োজন না হয়, তবে std :: unordered_map ব্যবহার করুন , যা নিয়মিত-ধ্রুবক চেহারা রয়েছে এবং কয়েকটি জোড়ের বেশি সঞ্চয় করার সময় খুব উপকারী হতে পারে। (২) যদি মানটি বিদ্যমান থাকে তবে তা ব্যবহার করতে চাইলে, ফলাফলটি সংরক্ষণ করুন :: 2 লুক-আপগুলি রোধ করতে পুনরুক্তিকারীর সন্ধান করুন এবং ব্যবহার করুন:auto it = m.find("f"); if (it != m.end()) {/*Use it->second*/}
সিডিগ্রাহাম

305

মানচিত্রে কোনও নির্দিষ্ট কী উপস্থিত রয়েছে কিনা তা পরীক্ষা করতে countনিম্নলিখিত একটি উপায়ের মাধ্যমে সদস্য ফাংশনটি ব্যবহার করুন :

m.count(key) > 0
m.count(key) == 1
m.count(key) != 0

এর জন্য ডকুমেন্টেশনmap::find বলে: "অন্য map::countকোনও সদস্য ফাংশনটি, নির্দিষ্ট কী উপস্থিত রয়েছে কিনা তা খতিয়ে দেখতে ব্যবহার করা যেতে পারে।"

এর জন্য ডকুমেন্টেশনmap::count বলে: "মানচিত্রের ধারকটিতে সমস্ত উপাদান স্বতন্ত্র হওয়ায় ফাংশনটি কেবল 1 (যদি উপাদানটি পাওয়া যায়) বা শূন্য (অন্যথায়) ফিরে আসতে পারে।"

আপনি যে কীটি বিদ্যমান থাকতে চান তার মাধ্যমে মানচিত্র থেকে মানটি পুনরুদ্ধার করতে, মানচিত্র :: এ এখানে ব্যবহার করুন :

value = m.at(key)

মানচিত্র :: অপারেটর [] এর বিপরীতে , map::atনির্দিষ্ট কী উপস্থিত না থাকলে মানচিত্রে একটি নতুন কী তৈরি করবে না।


33
আপনি যদি উভয় ক্রিয়াকলাপ করতে যাচ্ছেন তবে এটি বিদ্যমান কিনা তা পরীক্ষা করে দেখুন এবং তারপরে কিছু করুন। findপরিবর্তে ব্যবহার করুন। দ্বারা পুনরুদ্ধার করা secondপুনরাবৃত্তির বৈশিষ্ট্যটি findকীটির মান পুনরুদ্ধার করতে ব্যবহৃত হতে পারে। আপনি যদি countতখন ব্যবহার করেন atবা operator[]আপনি দুটি অপারেশন করছেন যখন আপনি কেবল একটি ব্যবহার করতে পারতেন।
ওডিআর এনকোডেড

1
আপনাকে> 0, == 1 বা! = 0 করার দরকার নেই; এটি if(m.count(key))
হ'ল

6
@ jv110 মাইক্রোসফ্ট সি ++ সংকলক যখন কোনও কাস্টের মুখোমুখি হয় তখন এটি একটি সতর্কতা জারিint করে bool। যদিও অন্যান্য সি ++ সংকলক রয়েছে যা একই ধরণের সতর্কতা জারি করে না, আমি অভিপ্রায়টি পরিষ্কার করতে এবং পাঠযোগ্যতা বাড়ানোর জন্য একটি সুস্পষ্ট তুলনা ব্যবহার পছন্দ করি । নোট করুন যে অন্যান্য ভাষাগুলি যেমন সি # তেমন সূক্ষ্ম প্রোগ্রামিং ত্রুটিগুলি প্রবর্তন করার সম্ভাবনা রোধ করার জন্য এই জাতীয় অন্তর্নিহিত রূপান্তরকে নিষেধ করে
ডেভিডআরআর

গণনা সময় জটিলতা কি? এটি কি কেবল ও (1) অপারেশন?
মাজারেট

1
@ ম্যাসারিট দেওয়া এই যে আমরা সি ++ স্ট্যান্ডার্ড লাইব্রেরির একটি শ্রেণির কথা বলছি, আমি অবশ্যই এটি অনুমান করব। আপনার প্রশ্নের ভাষা-অজ্ঞাত আলোচনার জন্য দেখুন কি হ্যাশ টেবিলগুলি সত্যই ও (1) হতে পারে?
ডেভিডআরআর

47

সি ++ 20 আমাদের এটি std::map::containsকরতে দেয় ।

#include <iostream>
#include <string>
#include <map>

int main()
{
    std::map<int, std::string> example = {{1, "One"}, {2, "Two"}, 
                                     {3, "Three"}, {42, "Don\'t Panic!!!"}};

    if(example.contains(42)) {
        std::cout << "Found\n";
    } else {
        std::cout << "Not found\n";
    }
}

33
আমার ধারণা আমি এটি বলব: অবশেষে।
এরিক ক্যামোপাডাল

2
প্রায় সময় .....
idদ্ধুর্শন

39

আপনি ব্যবহার করতে পারেন .find():

map<string,string>::iterator i = m.find("f");

if (i == m.end()) { /* Not found */ }
else { /* Found, i->first is f, i->second is ++-- */ }

14
m.find == m.end() // not found 

আপনি যদি অন্য এপিআই ব্যবহার করতে চান তবে সন্ধান করুন m.count(c)>0

 if (m.count("f")>0)
      cout << " is an element of m.\n";
    else 
      cout << " is not an element of m.\n";

12

আমি মনে করি আপনি চান map::find। যদি m.find("f")এর সমান হয় m.end(), তবে কীটি পাওয়া যায় নি। অন্যথায়, খুঁজে পাওয়া উপাদানটির দিকে ইঙ্গিত করে একটি পুনরাবৃত্তির সন্ধান করে।

ত্রুটিটি কারণ p.firstএকটি পুনরাবৃত্তিকারী, যা স্ট্রিম সন্নিবেশের জন্য কাজ করে না। আপনার শেষ লাইনটি এতে পরিবর্তন করুন cout << (p.first)->first;pপুনরাবৃত্তকারীগুলির একটি জোড়া, p.firstএকটি পুনরাবৃত্তকারী, p.first->firstমূল স্ট্রিং।

কোনও মানচিত্রে প্রদত্ত কীটির জন্য কেবল একটি উপাদান থাকতে পারে তাই equal_rangeএটি খুব কার্যকর নয়। এটি মানচিত্রের জন্য সংজ্ঞায়িত হয়েছে, কারণ এটি সমস্ত সংশ্লেষী ধারকগুলির জন্য সংজ্ঞায়িত করা হয়েছে তবে এটি মাল্টিম্যাপের জন্য অনেক বেশি আকর্ষণীয়।


প্রকৃতপক্ষে, কারণ এটি কোনও মানচিত্রে পুনরাবৃত্তকারীদের একজোড়া, এটি প্রথমে "cout << p.first-> হওয়া উচিত;"
স্টেফানভ

আমি আমার উত্তর স্থির করেছি, ধন্যবাদ। আমার কোডটি সংকলন না করার জন্য এটিই আমি পেয়েছি। এবং বৈধতার জন্য যাচাই করার বিষয়ে আপনি ঠিক (মুছে ফেলা মন্তব্যে) বলেছেন, তবে তিনি কেবল p.first প্রিন্ট করতে পারেন না কেন তা ব্যাখ্যা করার চেষ্টা করছিলাম, এবং এটি অবৈধ নয় - আমরা জানি "f" পাওয়া যাবে। যেহেতু আমি মোটামুটি_একটি ব্যবহার করার পরামর্শ দিচ্ছি না, আমি এর জন্য ত্রুটি-চেকিং কোডটি দেখানোর জন্য নেই।
স্টিভ জেসোপ

বাহ, আপনি সত্যিই স্ক্যান করছেন। আমি কেবল এটি সম্পূর্ণতার জন্য যুক্ত করছি, কারণ আপনার বক্তব্য পরিষ্কার ছিল। আমি আমার পূর্ববর্তী উত্তরের সাথে বৈধতা যাচাই করেছি, কিন্তু আপনার প্রতিক্রিয়া আমাকে মারধর করেছে, তাই আমি এটি মুছে ফেলেছি, কারণ আপনি যেমন উল্লেখ করেছেন তেমন এটি এতটা যোগ করেনি।
স্টেফানভ

হ্যাঁ, আমি এটি কেবলমাত্র দেখতে পেয়েছি কারণ আমার মন্তব্য পোস্ট করার সময় আপনার মন্তব্যটি উপস্থিত হয়েছিল।
স্টিভ জেসোপ

12

C++17এটি দিয়ে আরও কিছুটা সরলীকৃত If statement with initializer। এইভাবে আপনি আপনার কেক রাখতে পারেন এবং এটিও খেতে পারেন।

if ( auto it{ m.find( "key" ) }; it != std::end( m ) ) 
{
    // Use `structured binding` to get the key
    // and value.
    auto[ key, value ] { *it };

    // Grab either the key or value stored in the pair.
    // The key is stored in the 'first' variable and
    // the 'value' is stored in the second.
    auto mkey{ it->first };
    auto mvalue{ it->second };

    // That or just grab the entire pair pointed
    // to by the iterator.
    auto pair{ *it };
} 
else 
{
   // Key was not found..
}

4
map<string, string> m;

কী উপস্থিত রয়েছে কিনা তা যাচাই করুন, এবং সংখ্যার রিটার্ন নম্বর (মানচিত্রে 0/1):

int num = m.count("f");  
if (num>0) {    
    //found   
} else {  
    // not found  
}

কী উপস্থিত রয়েছে কিনা তা চেক করুন এবং পুনরাবৃত্তি পুনরুদ্ধার করুন:

map<string,string>::iterator mi = m.find("f");  
if(mi != m.end()) {  
    //found  
    //do something to mi.  
} else {  
    // not found  
}  

আপনার প্রশ্নে, খারাপ operator<<ওভারলোডের কারণে ত্রুটি ঘটেছে , কারণ p.firstএটি map<string, string>আপনি মুদ্রণ করতে পারবেন না। এটা চেষ্টা কর:

if(p.first != p.second) {
    cout << p.first->first << " " << p.first->second << endl;
}

1
আপনার টাইপো আছে "কাউট" কে "কাউন্ট" করুন
রিভকা

1
এবং সেই টাইপো সত্যিই কাউকে ফেলে দিতে পারে, কারণ এর থেকে coutআলাদা কিছু বোঝাতে পারেcount
Modulitos

4
template <typename T, typename Key>
bool key_exists(const T& container, const Key& key)
{
    return (container.find(key) != std::end(container));
}

অবশ্যই আপনি যদি ফ্যানসিয়ার পেতে চান তবে আপনি সর্বদা একটি ফাংশন টেমপ্লেট করতে পারেন যা একটি ফাংশন এবং একটি পাওয়া না পাওয়া ফাংশনও গ্রহণ করেছিল, এরকম কিছু:

template <typename T, typename Key, typename FoundFunction, typename NotFoundFunction>
void find_and_execute(const T& container, const Key& key, FoundFunction found_function, NotFoundFunction not_found_function)
{
    auto& it = container.find(key);
    if (it != std::end(container))
    {
        found_function(key, it->second);
    }
    else
    {
        not_found_function(key);
    }
}

এবং এটি এর মতো ব্যবহার করুন:

    std::map<int, int> some_map;
    find_and_execute(some_map, 1,
        [](int key, int value){ std::cout << "key " << key << " found, value: " << value << std::endl; },
        [](int key){ std::cout << "key " << key << " not found" << std::endl; });

এর নেতিবাচক দিকটি একটি ভাল নাম নিয়ে আসছে, "সন্ধান_আর_একসিকিউট" বিশ্রী এবং আমি আমার মাথার উপরের দিক থেকে আরও ভাল কিছু নিয়ে আসতে পারি না ...


3

শেষের সাথে ম্যাপ 'এম' এর মতো ফলাফলের সাথে তুলনা করতে সতর্ক হন যেমন সমস্ত উত্তর ম্যাপের উপরে করেছেন: পুনরুক্তি i = m.find ("f");

 if (i == m.end())
 {
 }
 else
 {
 }  

আপনার চেষ্টা এবং কোনও ক্রিয়াকলাপ করা উচিত নয় যেমন পুনরায় কী বা মান মুদ্রণের সাথে ইেটরেটর i এর সমান হলে এটি এম। ইন্ড () এর সমান হয় অন্যথায় এটি বিভাজন ত্রুটির দিকে পরিচালিত করবে।


0

স্টাড :: মানচিত্র :: সন্ধান এবং স্ট্যান্ড :: মানচিত্র :: গণনার কোডের তুলনা করে, আমি বলব প্রথমটি কিছুটা পারফরম্যান্স সুবিধা পেতে পারে:

const_iterator find(const key_type& _Keyval) const
    {   // find an element in nonmutable sequence that matches _Keyval
    const_iterator _Where = lower_bound(_Keyval); // Here one looks only for lower bound
    return (_Where == end()
        || _DEBUG_LT_PRED(this->_Getcomp(),
            _Keyval, this->_Key(_Where._Mynode()))
                ? end() : _Where);
    }

size_type count(const key_type& _Keyval) const
    {   // count all elements that match _Keyval
    _Paircc _Ans = equal_range(_Keyval); // Here both lower and upper bounds are to be found, which is presumably slower.
    size_type _Num = 0;
    _Distance(_Ans.first, _Ans.second, _Num);
    return (_Num);
    }

0

আমি জানি এই প্রশ্নের ইতিমধ্যে কিছু ভাল উত্তর রয়েছে তবে আমি মনে করি আমার সমাধানটি ভাগ করে নেওয়া উচিত।

এটা তোলে উভয়ের জন্য কাজ করে std::mapএবং std::vector<std::pair<T, U>>এবং সি ++ 11 থেকে পাওয়া যায়।

template <typename ForwardIterator, typename Key>
bool contains_key(ForwardIterator first, ForwardIterator last, Key const key) {
    using ValueType = typename std::iterator_traits<ForwardIterator>::value_type;

    auto search_result = std::find_if(
        first, last,
        [&key](ValueType const& item) {
            return item.first == key;
        }
    );

    if (search_result == last) {
        return false;
    } else {
        return true;
    }
}

-5

আপনি যদি জোড়ার মানচিত্রের তুলনা করতে চান তবে আপনি এই পদ্ধতিটি ব্যবহার করতে পারেন:

typedef map<double, double> TestMap;
TestMap testMap;
pair<map<double,double>::iterator,bool> controlMapValues;

controlMapValues= testMap.insert(std::pair<double,double>(x,y));
if (controlMapValues.second == false )
{
    TestMap::iterator it;
    it = testMap.find(x);

    if (it->second == y)
    {
        cout<<"Given value is already exist in Map"<<endl;
    }
}

এটি একটি দরকারী কৌশল।


সি ++ প্রোগ্রামিংয়ের শিক্ষানবিস হিসাবে, আমি কেন এই উত্তরকে হ্রাসযুক্ত তা সত্যই জানতে আগ্রহী। কেন এই উত্তর অপ্রিয় হয়?
gromit190

3
@ gromit190 কারণ এটি একটি সম্পূর্ণ অন্যান্য ডেটা স্ট্রাকচার ব্যবহার করছে এটি দেখার জন্য যে std :: মানচিত্রে ইতিমধ্যে ইতিমধ্যে এই ক্ষমতাটি রয়েছে কিনা exists এটির জন্য উভয় ডেটা স্ট্রাকচারের মধ্যে সুসংগত হওয়া দরকার যা একটি নির্ভরতা যার সাথে কারও মোকাবেলা করতে চায় না।
লাবাজ

-5
map <int , char>::iterator itr;
    for(itr = MyMap.begin() ; itr!= MyMap.end() ; itr++)
    {
        if (itr->second == 'c')
        {
            cout<<itr->first<<endl;
        }
    }

3
দয়া করে আপনার কোডটি বিস্তারিতভাবে বর্ণনা করুন। কোনও ব্যাখ্যা ছাড়াই একটি স্নিপেট দীর্ঘমেয়াদে সহায়ক হতে পারে না।
iBug
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.