কীগুলির মাধ্যমে পুনরাবৃত্তি করার কোনও উপায় আছে, কোনও সি ++ মানচিত্রের জোড়া নয়?
কীগুলির মাধ্যমে পুনরাবৃত্তি করার কোনও উপায় আছে, কোনও সি ++ মানচিত্রের জোড়া নয়?
উত্তর:
"সত্যিকারের" পুনরাবৃত্তির ফিরে আসা মানটি যদি আপনার সত্যই লুকিয়ে রাখতে হয় (উদাহরণস্বরূপ আপনি স্ট্যান্ডার্ড অ্যালগরিদমের সাহায্যে আপনার কী-পুনরুক্তি করতে চান, যাতে তারা জোড়গুলির পরিবর্তে কীগুলিতে কাজ করে) তবে বুস্টের দিকে একবার নজর দিন transform_iterator ।
[টিপ: একটি নতুন শ্রেণীর জন্য বুস্ট ডকুমেন্টেশন দেখার সময়, প্রথমে "উদাহরণগুলি" পড়ুন। তারপরে আপনার কাছে পৃথিবীর অন্যান্য অংশগুলি কী সম্পর্কে কথা বলছে তা নির্ধারণের একটি স্পোর্টস সুযোগ রয়েছে:]
মানচিত্রটি সহকারী ধারক। অতএব, পুনরাবৃত্তি হ'ল একজোড়া কী, ভাল। যদি আপনার কেবল কীগুলির দরকার হয় তবে আপনি জোড়া থেকে মান অংশটি উপেক্ষা করতে পারেন।
for(std::map<Key,Val>::iterator iter = myMap.begin(); iter != myMap.end(); ++iter)
{
Key k = iter->first;
//ignore value
//Value v = iter->second;
}
সম্পাদনা করুন: আপনি যদি কেবল বাইরের কীগুলিই প্রকাশ করতে চান তবে আপনি মানচিত্রটিকে ভেক্টর বা কীতে রূপান্তর করতে পারবেন এবং প্রকাশ করতে পারবেন।
const Key& k(iter->first);
std::vector<Key> v(myMap.begin(), myMap.end())
।
সি ++ 11 দিয়ে পুনরাবৃত্তির বাক্য গঠন সহজ is আপনি এখনও জোড়ায় পুনরাবৃত্তি করেন তবে কেবল কীটি অ্যাক্সেস করা সহজ।
#include <iostream>
#include <map>
int main()
{
std::map<std::string, int> myMap;
myMap["one"] = 1;
myMap["two"] = 2;
myMap["three"] = 3;
for ( const auto &myPair : myMap ) {
std::cout << myPair.first << "\n";
}
}
আপনি এই মানচিত্রের জন্য কেবল এসটিএল পুনরায় প্রসারিত করে এটি করতে পারেন। উদাহরণস্বরূপ, ইনটগুলিতে স্ট্রিংয়ের ম্যাপিং:
#include <map>
typedef map<string, int> ScoreMap;
typedef ScoreMap::iterator ScoreMapIterator;
class key_iterator : public ScoreMapIterator
{
public:
key_iterator() : ScoreMapIterator() {};
key_iterator(ScoreMapIterator s) : ScoreMapIterator(s) {};
string* operator->() { return (string* const)&(ScoreMapIterator::operator->()->first); }
string operator*() { return ScoreMapIterator::operator*().first; }
};
আপনি এই টেম্পলেটটিতে এই এক্সটেনশনটি সম্পাদন করতে পারেন আরও সাধারণ সমাধানের জন্য কোনও ।
ঠিক মত আপনি, একটি তালিকা পুনরুক্তিকারীর ব্যবহার করেন ব্যতীত আপনি iterating মানচিত্রের উপর করছি আপনি আপনার পুনরুক্তিকারীর ব্যবহার begin()
এবং end()
।
ScoreMap m;
m["jim"] = 1000;
m["sally"] = 2000;
for (key_iterator s = m.begin(); s != m.end(); ++s)
printf("\n key %s", s->c_str());
template<typename C> class key_iterator : public C::iterator
, ইত্যাদি
সি ++ 17 এর সাহায্যে আপনি লুপের জন্য একটি পরিসীমা-ভিত্তিক স্ট্রাকচার্ড বাইন্ডিং ব্যবহার করতে পারেন ( সেই অনুযায়ী জন এইচ এর উত্তর অভিযোজিত ):
#include <iostream>
#include <map>
int main() {
std::map<std::string, int> myMap;
myMap["one"] = 1;
myMap["two"] = 2;
myMap["three"] = 3;
for ( const auto &[key, value]: myMap ) {
std::cout << key << '\n';
}
}
দুর্ভাগ্যক্রমে সি ++ 17 স্ট্যান্ডার্ডের আপনাকে value
ভেরিয়েবল ঘোষণা করতে হবে , যদিও আপনি এটি ব্যবহার করছেন না ( std::ignore
যেহেতু এটি ব্যবহার করবে std::tie(..)
না তেমন কার্যকর হয় না, এই আলোচনা দেখুন) )।
কিছু সংকলক অপ্রয়োজনীয় value
ভেরিয়েবল সম্পর্কে আপনাকে সতর্ক করতে পারে ! অব্যবহৃত ভেরিয়েবল সম্পর্কিত সংকলন -কালীন সতর্কতাগুলি আমার মনে যে কোনও প্রোডাকশন কোডের জন্য যেতে হবে না। সুতরাং, এটি নির্দিষ্ট সংকলক সংস্করণের জন্য প্রযোজ্য নাও হতে পারে।
for ([[maybe_unused]] const auto &[key, v_not_used] : my_map) { use(key); }
আরও সাধারণ টেম্পলেটযুক্ত সমাধানের নীচে যা ইয়ান উল্লেখ করেছে ...
#include <map>
template<typename Key, typename Value>
using Map = std::map<Key, Value>;
template<typename Key, typename Value>
using MapIterator = typename Map<Key, Value>::iterator;
template<typename Key, typename Value>
class MapKeyIterator : public MapIterator<Key, Value> {
public:
MapKeyIterator ( ) : MapIterator<Key, Value> ( ) { };
MapKeyIterator ( MapIterator<Key, Value> it_ ) : MapIterator<Key, Value> ( it_ ) { };
Key *operator -> ( ) { return ( Key * const ) &( MapIterator<Key, Value>::operator -> ( )->first ); }
Key operator * ( ) { return MapIterator<Key, Value>::operator * ( ).first; }
};
template<typename Key, typename Value>
class MapValueIterator : public MapIterator<Key, Value> {
public:
MapValueIterator ( ) : MapIterator<Key, Value> ( ) { };
MapValueIterator ( MapIterator<Key, Value> it_ ) : MapIterator<Key, Value> ( it_ ) { };
Value *operator -> ( ) { return ( Value * const ) &( MapIterator<Key, Value>::operator -> ( )->second ); }
Value operator * ( ) { return MapIterator<Key, Value>::operator * ( ).second; }
};
সমস্ত ক্রেডিট আয়ানের দিকে যায় ... ধন্যবাদ ইয়ান।
আপনি মানচিত্র_কিজ খুঁজছেন , এটির সাহায্যে আপনি এই জাতীয় জিনিস লিখতে পারেন
BOOST_FOREACH(const key_t key, the_map | boost::adaptors::map_keys)
{
// do something with key
}
BOOST_FOREACH(const key_t& key, ...
বুস্টের ট্রান্সফর্ম_পিটর ব্যবহার করে এটি কীভাবে করা যায় তার একটি উদাহরণ এখানে
#include <iostream>
#include <map>
#include <iterator>
#include "boost/iterator/transform_iterator.hpp"
using std::map;
typedef std::string Key;
typedef std::string Val;
map<Key,Val>::key_type get_key(map<Key,Val>::value_type aPair) {
return aPair.first;
}
typedef map<Key,Val>::key_type (*get_key_t)(map<Key,Val>::value_type);
typedef map<Key,Val>::iterator map_iterator;
typedef boost::transform_iterator<get_key_t, map_iterator> mapkey_iterator;
int main() {
map<Key,Val> m;
m["a"]="A";
m["b"]="B";
m["c"]="C";
// iterate over the map's (key,val) pairs as usual
for(map_iterator i = m.begin(); i != m.end(); i++) {
std::cout << i->first << " " << i->second << std::endl;
}
// iterate over the keys using the transformed iterators
mapkey_iterator keybegin(m.begin(), get_key);
mapkey_iterator keyend(m.end(), get_key);
for(mapkey_iterator i = keybegin; i != keyend; i++) {
std::cout << *i << std::endl;
}
}
যখন কোনও স্পষ্ট begin
এবং end
প্রয়োজন হয় না, যেমন পরিসর-লুপিংয়ের জন্য, লুপ ওভার কীগুলি (প্রথম উদাহরণ) বা মানগুলি (দ্বিতীয় উদাহরণ) এর সাথে পাওয়া যায়
#include <boost/range/adaptors.hpp>
map<Key, Value> m;
for (auto k : boost::adaptors::keys(m))
cout << k << endl;
for (auto v : boost::adaptors::values(m))
cout << v << endl;
আপনি এটি করতে চান?
std::map<type,type>::iterator iter = myMap.begin();
std::map<type,type>::iterator iter = myMap.end();
for(; iter != endIter; ++iter)
{
type key = iter->first;
.....
}
আপনার যদি এমন একটি পুনরুত্থানকারী প্রয়োজন যা কেবলমাত্র আপনার নিজের শ্রেণিতে মানচিত্রের পুনরাবৃত্তি মোড়ানোর জন্য প্রয়োজনীয় কীগুলি ফেরত দেয় যা পছন্দসই ইন্টারফেস সরবরাহ করে। আপনি এখানে নতুন স্ক্র্যাচ থেকে নতুন পুনরায় শ্রেণীর ক্লাস ঘোষণা করতে পারেন, বিদ্যমান সহায়ক সহায়িকা ব্যবহারের জন্য। এই উত্তরটি দেখায় যে কীভাবে বুস্টকে কীভাবে transform_iterator
পুনরাবৃত্তকারীকে মোড়ক ব্যবহার করতে হয় যা কেবলমাত্র মান / কীগুলি দেয়।
এই উত্তরটি রডরিববের মতো, বাদে BOOST_FOREACH
। পরিবর্তে এর জন্য আপনি সি ++ এর ব্যাপ্তি ব্যবহার করতে পারেন।
#include <map>
#include <boost/range/adaptor/map.hpp>
#include <iostream>
template <typename K, typename V>
void printKeys(std::map<K,V> map){
for(auto key : map | boost::adaptors::map_keys){
std::cout << key << std::endl;
}
}
বুস্ট ব্যতীত আপনি এটি এটি করতে পারেন। এটি ভাল হবে যদি আপনি getKeyIterator () এর পরিবর্তে একটি কাস্টার অপারেটর লিখতে পারেন তবে আমি এটি সংকলন করতে পারি না।
#include <map>
#include <unordered_map>
template<typename K, typename V>
class key_iterator: public std::unordered_map<K,V>::iterator {
public:
const K &operator*() const {
return std::unordered_map<K,V>::iterator::operator*().first;
}
const K *operator->() const {
return &(**this);
}
};
template<typename K,typename V>
key_iterator<K,V> getKeyIterator(typename std::unordered_map<K,V>::iterator &it) {
return *static_cast<key_iterator<K,V> *>(&it);
}
int _tmain(int argc, _TCHAR* argv[])
{
std::unordered_map<std::string, std::string> myMap;
myMap["one"]="A";
myMap["two"]="B";
myMap["three"]="C";
key_iterator<std::string, std::string> &it=getKeyIterator<std::string,std::string>(myMap.begin());
for (; it!=myMap.end(); ++it) {
printf("%s\n",it->c_str());
}
}
উত্তরোত্তর জন্য, এবং যেহেতু আমি একটি পরিসীমা তৈরির উপায় অনুসন্ধান করার চেষ্টা করছিলাম, তাই বিকল্পটি হ'ল :: অ্যাডাপ্টার :: ট্রান্সফর্ম ব্যবহার করা
এখানে একটি ছোট উদাহরণ:
#include <boost/range/adaptor/transformed.hpp>
#include <iostream>
#include <map>
int main(int argc, const char* argv[])
{
std::map<int, int> m;
m[0] = 1;
m[2] = 3;
m[42] = 0;
auto key_range =
boost::adaptors::transform(
m,
[](std::map<int, int>::value_type const& t)
{ return t.first; }
);
for (auto&& key : key_range)
std::cout << key << ' ';
std::cout << '\n';
return 0;
}
আপনি যদি মানগুলি নিয়ে পুনরাবৃত্তি করতে চান t.second
তবে ল্যাম্বডায় ব্যবহার করুন।
এখানে প্রচুর ভাল উত্তর, নীচে তাদের কয়েকটি ব্যবহার করে এমন একটি পদ্ধতির সাহায্য দেওয়া হয়েছে যা আপনাকে এটি লিখতে দেয়:
void main()
{
std::map<std::string, int> m { {"jim", 1000}, {"sally", 2000} };
for (auto key : MapKeys(m))
std::cout << key << std::endl;
}
আপনি যদি সর্বদা এটি চেয়েছিলেন তবে ম্যাপকি () এর কোড এখানে রয়েছে:
template <class MapType>
class MapKeyIterator {
public:
class iterator {
public:
iterator(typename MapType::iterator it) : it(it) {}
iterator operator++() { return ++it; }
bool operator!=(const iterator & other) { return it != other.it; }
typename MapType::key_type operator*() const { return it->first; } // Return key part of map
private:
typename MapType::iterator it;
};
private:
MapType& map;
public:
MapKeyIterator(MapType& m) : map(m) {}
iterator begin() { return iterator(map.begin()); }
iterator end() { return iterator(map.end()); }
};
template <class MapType>
MapKeyIterator<MapType> MapKeys(MapType& m)
{
return MapKeyIterator<MapType>(m);
}
আমি সমস্ত মানচিত্রের ধরণের সাথে কাজ করার জন্য আয়ানের উত্তর গ্রহণ করেছি এবং এর জন্য কোনও রেফারেন্স ফিরিয়ে দেওয়া ঠিক করেছি operator*
template<typename T>
class MapKeyIterator : public T
{
public:
MapKeyIterator() : T() {}
MapKeyIterator(T iter) : T(iter) {}
auto* operator->()
{
return &(T::operator->()->first);
}
auto& operator*()
{
return T::operator*().first;
}
};
আমি জানি এটি আপনার প্রশ্নের উত্তর দেয় না, তবে আপনি যে বিকল্পটি দেখতে চাইতে পারেন তা হ'ল একই সূচকটির সাথে দুটি ভেক্টর রয়েছে যা "লিঙ্কযুক্ত" তথ্যযুক্ত ..
সুতরাং ..
std::vector<std::string> vName;
std::vector<int> vNameCount;
আপনি যদি নাম অনুসারে নামের গণনা চান তবে আপনি কেবলমাত্র vName.size () এর লুপের জন্য আপনার দ্রুত কাজটি করতে পারেন এবং যখন আপনি এটি খুঁজে পেয়েছেন যে আপনি vNameCount এর জন্য সূচক।
অবশ্যই এটি আপনাকে মানচিত্রের সমস্ত কার্যকারিতা না দেয় এবং নির্ভর করে আরও ভাল হতে পারে বা না পারে তবে আপনি কীগুলি জানেন না, এবং খুব বেশি প্রসেসিং যুক্ত না করা সহজ be
কেবল মনে রাখবেন আপনি যখন একটি থেকে যুক্ত / মুছবেন তখন আপনাকে অন্যটি থেকে এটি করতে হবে বা জিনিসগুলি পাগল হয়ে উঠবে হে: পি