简体   繁体   English

Stl Set查找项目C ++

[英]Stl Set find an item c++

I have a set where i want to find items in it. 我有一个我想在其中找到物品的地方。 Right now i have global objects that i am using to store my finds - (ItemSetMap allMusicByBand) 现在我有全局对象,用于存储我的发现-(ItemSetMap allMusicByBand)

I would like to get away from this and just search the sets directly. 我想摆脱这个,直接搜索集合。

All the cd info are stored in the private section - (ItemSet allCDS;) 所有的CD信息都存储在专用部分中-(ItemSet allCDS;)

here is the library.cpp - 这是library.cpp-

the commented code is where i was doing my search and adding to the global object... 评论的代码是我进行搜索并将其添加到全局对象的地方...

I would like to do the search in the musicByBand function instead.. 我想改为在musicByBand函数中进行搜索。

#include "Library.h"
#include "book.h"
#include "cd.h"
#include "dvd.h"

#include <iostream>




//ItemSetMap allBooksByAuthor;       //these are what i am trying to get away from...
ItemSetMap allmoviesByDirector;
ItemSetMap allmoviesByActor;

//ItemSetMap allMusicByBand;
ItemSetMap allMusicByMusician;


const Item* Library::addMusicCD(const string& title, const string& band, const int nSongs)
{

CD* item = new CD(title,band,nSongs);

allCDS.insert(item);

//ItemSetMap::iterator myband = allMusicByBand.find(band);

//if(myband != allMusicByBand.end())
//{
    //myband->second->insert(item);

//}
//else{
    //ItemSet* obj = new ItemSet();
    //obj->insert(item);
    //allMusicByBand.insert(make_pair(band, obj));
//}




return item;
    }


const ItemSet* Library::musicByBand(const string& band) const
{



return allMusicByBand[author];
}

i hope i was clear enough on what i wanted. 我希望我对我想要的东西足够清楚。

I have tried to iterate through it. 我试图遍历它。 I have tried just about everything i can think of.. CD class is a superclass of item class. 我已经尝试了几乎所有我能想到的东西。CD类是项类的超类。

Thank you.. 谢谢..

An "idiomatic" way to do it might be to use the std::remove_copy_if algorithm . 一种“惯用的”方法可能是使用std :: remove_copy_if算法 It would look something like this: 它看起来像这样:

class NotMatching {
   string bandName_;
public:
   NotMatching( const string& band ) : bandName_( band ) {}
   bool operator()( const Item& item ) {
      return item.bandName() != bandName_;
   }
};

const ItemSet musicByBand(const string& band)
{
   ItemSet matchingItems;

   std::remove_copy_if( allCDS.begin(), allCDS.end(),
      insert_iterator< ItemSet >( matchingItems, matchingItems.begin() ),
      NotMatching( band ) );

   return matchingItems;
}

But to be honest I think Tyler's approach is simpler and clearer. 但老实说,我认为泰勒的方法更简单明了。

The simplest way to do it would be this: 最简单的方法是:

const ItemSet* Library::musicByBand(const string& band) const
{
    ItemSet* bandMusic = new ItemSet();

    for (ItemSet::const_iterator i = allCDs.begin(); i != allCDs.end(); ++i)
    {
      if ((*i)->getBand() == band) {
        bandMusic->insert(*i);
      }
    }

   return itemSet;
}

Although this runs in O(n) time, which doesn't at all take advantage of the fact that you are using a set. 尽管这是在O(n)时间中运行的,但这完全没有利用您使用集合的事实。 These could just as well be in a vector. 这些也可能在向量中。 The way you were doing it before with the "index" sets is actually a faster-performing solution, although it will take somewhat more memory. 以前使用“索引”集进行处理的方法实际上是一种性能更快的解决方案,尽管它会占用更多的内存。 Plus, presumably the retrieval methods will be called far more frequently than the insertion methods, so it makes sense to do more work on insertion in order to save on work during retrieval. 另外,大概检索方法的调用频率要比插入方法要高得多,因此有意义的是在插入上进行更多工作,以节省检索期间的工作。 But of course if you do this, you will want the index sets to be private members, not globals. 但是,当然,如果这样做,您将希望索引集是私有成员,而不是全局成员。

You should also be very careful about your memory management here. 您还应该在这里对内存管理非常小心。 The fact that you are returning a const pointer to an ItemSet from the musicByBand method concerns me. 你是一个常量指针返回到一个事实ItemSetmusicByBand方法与我有关。 Why can it not be just an ItemSet that you are returning? 为什么它不只是您要返回的ItemSet

This is a sample code which uses the functor with std::find_if algorithm to search for a particular element in the set 这是一个示例代码,它使用带有std::find_if算法的std::find_if函数来搜索set的特定元素

struct BandComparison : public std::binary_function<Item*, std::string, bool>
{
public:
    bool operator()(Item* pItem, const std::string& bandName) const
    {
        bool equal = false;
        CD* pCD = dynamic_cast<CD*>(pItem);
        if(pCD)
        {
            equal = pCD->getBand() == bandName;
        }
        return equal;
    }
};

void Library::addCD(const std::string &band)
{
    //First check whether CD with this band name exists
    ItemSet::iterator iter = std::find_if(m_cds.begin(), m_cds.end(), std::bind2nd(BandComparison(), band));
    if(iter == m_cds.end())
    {
        m_cds.insert(new CD(band));
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM