Как я могу проверить, существует ли объект класса в наборе C ++?

0

Я пытаюсь написать фрагмент кода, который позволяет пользователю вводить определенное количество имен, а затем проверяет, существуют ли в наборе объекты, содержащие эти имена. Я хочу, чтобы программа взяла имена, введенные пользователем, провела цикл через набор и посмотрела, существует ли имя в любом из элементов объекта, а затем печатайте в командной строке, существует ли это имя или нет.

По какой-то причине он печатает "Имя не существует в наборе" для каждого элемента в наборе, даже если имя существует в наборе. Как я могу проверить это правильно? Кроме того, как я могу заставить его печатать сообщение "не существует" один раз, даже если проверка завершилась несколько раз, прежде чем найти (или не найти) совпадение?

Мой код пока:

#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;
}
  • 1
    Используйте, например, std::find (с соответствующим оператором сравнения) или std::find_if ?
  • 1
    Ваше class Name , похоже, не делает ничего, что не делает std::string . Почему бы просто не использовать вместо него std::string ?
Показать ещё 2 комментария
Теги:
class
set

4 ответа

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

  • 0
    Работает отлично, без заморозков или еще чего-нибудь :) спасибо за помощь!
  • 0
    пожалуйста ;)
Показать ещё 2 комментария
3

Ваше Name::operator< неверно. Он всегда возвращает true, что означает, что set всегда будет считать, что два объекта Name сравнивают неравные.

Вместо этого сравните строки имен, возвратив this->name < right.name, и вы увидите правильное поведение из своего set.

(Кстати, ваш operator< должен принять const Name & для эффективности).

  • 0
    Я попробовал это с обоими «вернуть this.name <right.name» и «вернуть this-> name <right-> name» и оба из-за ошибок. Как я могу реализовать это правильно? Я даже не использую это в main (), так зачем это нужно?
  • 0
    @Ultimabuster: std::set использует operator< для сравнения элементов. Поэтому для правильной работы требуется правильная реализация.
Показать ещё 2 комментария
1

Ты нуждаешься в этом

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

Однако в этом случае вы можете напрямую использовать строку вместо имени.

  • 0
    Я думаю, что это работает сейчас, по крайней мере, это не из-за каких-либо ошибок при компиляции, спасибо! Но теперь моя программа зависает, когда находит совпадение. : /
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";
     }
  • 0
    Я думаю, что оператор <работает благодаря всем остальным подсказкам, но когда я запускаю этот код, он правильно выдает сообщение «not found», но останавливает / завершает работу приложения, когда находит действительное совпадение.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню