c++ - Using map.find() and count() on a key, which is a class object type -
is there way possible use map.find() / map.count() algorithms key, of type object of class?
my multimap made of pairs - map.<myclass, enum> , myclass has member, filename example. search duplicate filenames in map , have read find() , count() functions keys, possible implement them search member of key?
here code:
cdirectory (string n) { fp.open (n, ios::in); string dirname, filename, ftype; int filesize; fp >> dirname; m_strdirectory = dirname; while (fp >> filename >> filesize >> ftype) { cfile obj (filename, filesize); if (ftype == "archive") filetype = filetype::archive; else if (ftype == "hidden") filetype = filetype::hidden; else if (ftype == "readonly") filetype = filetype::readonly; else if (ftype == "system") filetype = filetype::system; else filetype = filetype::filenotsupported; m_directorymap.insert(pair<cfile, filetype>(cfile(obj.getfilename(), obj.getfilesize()), filetype(filetype))); } multimap<cfile, filetype>::iterator p = m_directorymap.begin(); while ( p != m_directorymap.end()) { cout << endl << p->first.getfilename() << '\t' << p->first.getfilesize() << '\t' << p->second << endl; ++p; } } this constructor of second class, has multimap of pairs (objects of class, enum>).
and here first class:
class cfile { string m_strfile; unsigned int m_size; public: cfile () { m_strfile = ""; m_size = 0; } cfile (string name, int size ) { m_strfile = name; m_size = size; } string getfilename () const { return m_strfile; } int getfilesize () const { return m_size; } void setfilesize ( int size ) { m_size = size; } bool operator< (cfile& obj) { return ( m_size < obj.m_size ); } bool operator== (const cfile& obj) { return ( m_size == obj.m_size ); } friend ostream& operator<< ( ostream& ost, const cfile& obj ) { return ost << obj.m_strfile << obj.m_size; } friend istream& operator>> ( istream& ist, cfile& obj ) { return ist >> obj.m_strfile >> obj.m_size; } static bool greater(const cfile& obj1, const cfile& obj2) { if ( obj1.m_size > obj2.m_size ) return true; else return false; } }; i want find duplicates of string m_strfile;
a std::multimap compares keys through predicate (a function object call operator takes reference 2 objects of type key).
the default predicate std::multimap std::less<>, why maps ordered ascending key.
in order make keys comparable, either need specify custom predicate in map's template argument list (in third position), or give class < operator.
then iterate through map in groups of pairs, such as:
struct mykey { mykey(std::string fname) : _filename { std::move(fname) } {} const std::string& filename() const { return _filename; } private: std::string _filename; }; // define predicate order map struct order_by_filename { bool operator()(const mykey& l, const mykey& r) const { return l.filename() < r.filename(); } }; struct dataobject {}; std::multimap<mykey, dataobject, order_by_filename> my_map; void strip_duplicates() { for(auto current = my_map.begin() ; current != my_map.end() ; ) { auto range = my_map.equal_range(current->first); // range std::pair containing first , last iterator // of range equal keys auto num_items = range.second - range.first; if (num_items > 1) { // strip duplicates my_map.erase(std::next(range.first), range.second); } // move next range of keys current = range.second; } } for completeness, here's way eliminating duplicates without using equal_range:
void erase_all_but_one(std::multimap<key, value>& mmap, const key& to_erase) { auto ifind = mmap.find(to_erase); if (ifind == mmap.end()) return; for(ifind = std::next(ifind) ; ifind != mmap.end() && ifind->first == to_erase ; ) { // note: take copy of advanced iterator before erasing // iterator. auto inext = std::next(ifind); mmap.erase(ifind); ifind = inext; } }
Comments
Post a Comment