如何检查C ++集中是否存在类对象?

时间:2014-09-15 01:26:35

标签: c++ class set

我正在尝试编写一段代码,允许用户输入一定数量的名称,然后检查该组中是否存在包含这些名称的任何对象。 我想要的是程序获取用户输入的名称,遍历集合并查看该名称是否存在于任何对象元素中,然后打印到命令行是否存在名称。

由于某种原因,即使名称存在于集合中,它也会为集合中的每个元素打印“名称在集合中不存在”。我怎样才能正确检查?另外,即使在查找(或未找到)匹配之前多次检查失败,我怎么能只打印“不存在”消息呢?

到目前为止我的代码是:

#include <iostream>
#include <set>
#include <string>
#include <cassert>

using namespace std;

class Name {
   public:
      Name();
      Name(string n);
      bool operator<(Name right)const; 
      string get_name()const;
   private:
      string name;             
};

Name::Name(){}

Name::Name(string n)
{
   name = n;
}

bool Name::operator<(Name right)const
{
      bool result = true;
      return result;
}

string Name::get_name()const
{
      return "Name name is: " + name + "\n";
}

int main(){

set<Name>NamesSet;
NamesSet.insert(Name("Patrick Star"));
NamesSet.insert(Name("Jason"));
NamesSet.insert(Name("Bob Marl"));
NamesSet.insert(Name("Greg"));
set<Name>::iterator pos; 


int numjobs;
string cusname;
cout << "Number of names to enter:" << endl;
cin >> numjobs;
cin.ignore();
if (numjobs != 0 || numjobs > 0) {
   for (int i = 0; i != numjobs; i++)
   {
      cout << endl;
      cout << "Name " << i+1 << ": " << endl;
      getline(cin, cusname);

      for (pos = NamesSet.begin(); pos != NamesSet.end(); pos++) 
      {
         if (NamesSet.count((*pos).get_name()))
         {
            cout << (*pos).get_name() << " exists in set";
            break;
         }
         else 
         {
            cout << "Name does not exist in set";
         }
      }
   }
}

   return 0;
}

4 个答案:

答案 0 :(得分:3)

您的Name::operator<不正确。它始终返回true,这意味着set将始终相信两个Name个对象进行比较不相等。

相反,通过返回this->name < right.name来比较您的姓名字符串,您应该会从set中看到正确的行为。

(顺便提一下,为了提高效率,您的operator<应该const Name &

答案 1 :(得分:1)

这部分代码对于初学者来说是错误的

  for (pos = NamesSet.begin(); pos != NamesSet.end(); pos++) <-------- count does this for you
  {
     if (NamesSet.count((*pos).get_name())) <------ you check the whole set to see if it is in itself
     {
        cout << (*pos).get_name() << " exists in set";
        break;
     }
     else 
     {
        cout << "Name does not exist in set";
     }
  }

这应该更好,用以下代替上面的内容:

     if (NamesSet.count(cusname))
     {
        cout << cusname << " exists in set";
        break;
     }
     else 
     {
        cout << "Name does not exist in set";
     }

答案 2 :(得分:1)

你需要这个

bool operator< (const Name& right) {
    return name < right.name;
};

但是,在这种情况下,您可以直接使用字符串,而不是名称。

答案 3 :(得分:1)

你需要改变这些:

bool Name::operator<(const Name& right)const
{
      return (this->name < right.name);
}

string Name::get_name()const
{
      return name;
}

这将是一个有效的样本:

#include <iostream>
#include <set>
#include <string>
#include <cassert>

using namespace std;

class Name {
   public:
      Name();
      Name(string n);
      bool operator<(const Name& right)const; 
      string get_name()const;
   private:
      string name;             
};

Name::Name(){}

Name::Name(string n)
{
   name = n;
}

bool Name::operator<(const Name& right)const
{
      return (this->name < right.name);
}

string Name::get_name()const
{
      return name;
}

int main()
{

set<Name>NamesSet;
NamesSet.insert(Name("Patrick Star"));
NamesSet.insert(Name("Jason"));
NamesSet.insert(Name("Bob Marl"));
NamesSet.insert(Name("Greg"));
set<Name>::iterator pos; 

string cusname = "Greg";

if ( NamesSet.count(cusname) == 1 )
{
    cout << cusname << " exists in set"<<endl;
}
else 
{
    cout<<"Nanda!";
}

   return 0;
}

http://codepad.org/kg9gtSsX