In this article we will discuss how to check if a given element exists in set or not.

Suppose we have a set of strings i.e.

// Set of strings
std::set<std::string> setOfStrs = { "the", "is", "of" , "from" , "at" , "hello" , "the" };

Now we wnat to check if any given string exists in the set or not. Let’s do this using two different techniques i.e.

Search for an element in Set using set::find()

std::set provides a member function to find the existance of a given element in set i.e.

iterator find (const value_type& val);

It accepts the element as argument and search for that in the set. If the element is found in set then it returns the iterator pointing to that element else it returns the iterator pointing to the end of set.

Let’s use set::find() function to check if “at” exists in above set or not i.e.

// search for the iterator of given string in set
std::set<std::string>::iterator it = setOfStrs.find("at");

// Check if iterator it is valid
if (it != setOfStrs.end())
{
	std::cout << "'at' found in set" << std::endl;
}

We can not modify the element pointed by this iterator because this element is used for indexing inside the set, changing it will make the indexing wrong. Therefore we can access the element through iterator but cannot modify it.

Search for an element in Set using set::count()

std::set provides a member function to find the occurrence count of a given element in set i.e.

size_type count (const value_type& val) const;

It accepts the element as argument and search for its occurrence count in the set. As std::set can contain only unique elements, so occurrence count of the given element can be only 0 or 1 i.e,

If found then 1 else 0.

Let’s use set::count() function to check if “hello” exists in above set or not i.e.

// Fetch the occurrence count of given string in set
if (setOfStrs.count("hello") != 0)
{
	std::cout << "'hello' found in set" << std::endl;
}

Checkout the complete example as follows,
#include <iostream>
#include <set>
#include <string>
#include <algorithm>
#include <iterator>

int main()
{
	// Set of strings
	std::set<std::string> setOfStrs = { "the", "is", "of" , "from" , "at" , "hello" , "the" };

	// search for the iterator of given string in set
	std::set<std::string>::iterator it = setOfStrs.find("at");

	// Check if iterator it is valid
	if (it != setOfStrs.end())
	{
		std::cout << "'at' found in set" << std::endl;
	}

	// Modification is not allowed
	//*it = "AND";

	// search for the iterator of given string in set
	it = setOfStrs.find("text");
	// Check if iterator it is valid
	if (it != setOfStrs.end())
		std::cout << "'text' found in set" << std::endl;
	else
		std::cout << "'text' not found in set" << std::endl;

	// Fetch the occurrence count of given string in set
	if (setOfStrs.count("hello") != 0)
	{
		std::cout << "'hello' found in set" << std::endl;
	}

	return 0;

}

Output:
'at' found in set
'text' not found in set
'hello' found in set

set::find() vs set::count()

Both set::find() and set:: count() helps to check the existence of an element in set. But why 2 different method for same thing ?

Complexity wise both find() and count() are same. Main difference is that set::find() returns the iterator of the given element. Iterator is useful if we have user define objects in set, instead of primitive data types.

As set::find() returns the iterator, We can perform operations on the object pointed by iterator, also we can modify the mutable content of that object

Suppose we have a struct Student i.e.

// Student with ID and name
// Name is mutable, so can be modified by const object
struct Student
{
	int mId;
	mutable std::string mName;
	Student(int id, std::string name) :
			mId(id), mName(name)
	{
	}
};

A Functor / Comparator, to compare Student objects using ID i.e.
// Student comparator / Functor
// Compare objects with ID only
struct StudentComp
{
	bool operator()(const Student& lhs, const Student& rhs) const
	{
		return lhs.mId < rhs.mId;
	}
};

Let’s Create a set of Student objects i.e.
// Set of Student class objects
std::set<Student, StudentComp> setOfStudents =
		{ Student(1, "Shaun"), Student(2, "Riti"), Student(3, "Aadi"),
		  Student(4,"Vicky"), Student(5, "Renu") };


Find a Student object with id 3 using set::find() and modify its name, because mName is mutable and can be modifies eve with const objects i.e.
// Find a student with id 3
std::set<Student, StudentComp>::iterator it = setOfStudents.find( Student(3, ""));

// Check if Iterator is valid
if (it != setOfStudents.end())
{
	// Modify the mutuable content which is not
	// used in comparision or indexing
	it->mName = "Aarav";
	std::cout << it->mId << " :: " << it->mName << std::endl;
}

Now search for an element with count() i.e.
// Check if a student with ID 3 exists in set
// Not possible to fetch the iterator with count(),
// It returns the count only
if (setOfStudents.count(Student(3, "")) != 0)
{
	std::cout << it->mId << " Exist in Set" << std::endl;
}

We will not get any iterator with set::count(), so its not possible to perform any operation or modify content with count().

Complete example is as follows,

#include <iostream>
#include <set>
#include <string>
#include <algorithm>
#include <iterator>

// Student with ID and name
// Name is mutable, so can be modified by const object
struct Student
{
	int mId;
	mutable std::string mName;
	Student(int id, std::string name) :
			mId(id), mName(name)
	{
	}
};

// Student comparator / Functor
// Compare objects with ID only
struct StudentComp
{
	bool operator()(const Student& lhs, const Student& rhs) const
	{
		return lhs.mId < rhs.mId;
	}
};

int main()
{
	// Set of Student class objects
	std::set<Student, StudentComp> setOfStudents =
			{ Student(1, "Shaun"), Student(2, "Riti"), Student(3, "Aadi"),
			  Student(4,"Vicky"), Student(5, "Renu") };

	// Find a student with id 3
	std::set<Student, StudentComp>::iterator it = setOfStudents.find( Student(3, ""));

	// Check if Iterator is valid
	if (it != setOfStudents.end())
	{
		// Modify the mutuable content which is not
		// used in comparision or indexing
		it->mName = "Aarav";
		std::cout << it->mId << " :: " << it->mName << std::endl;
	}

	// Check if a student with ID 3 exists in set
	// Not possible to fetch the iterator with count(),
	// It returns the count only
	if (setOfStudents.count(Student(3, "")) != 0)
	{
		std::cout << it->mId << " Exist in Set" << std::endl;
	}

	return 0;

}

#include <iostream>
#include <set>
#include <string>
#include <algorithm>
#include <iterator>

// Student with ID and name
// Name is mutable, so can be modified by const object
struct Student
{
	int mId;
	mutable std::string mName;
	Student(int id, std::string name) :
			mId(id), mName(name)
	{
	}
};

// Student comparator / Functor
// Compare objects with ID only
struct StudentComp
{
	bool operator()(const Student& lhs, const Student& rhs) const
	{
		return lhs.mId < rhs.mId;
	}
};

int main()
{
	// Set of Student class objects
	std::set<Student, StudentComp> setOfStudents =
			{ Student(1, "Shaun"), Student(2, "Riti"), Student(3, "Aadi"),
			  Student(4,"Vicky"), Student(5, "Renu") };

	// Find a student with id 3
	std::set<Student, StudentComp>::iterator it = setOfStudents.find( Student(3, ""));

	// Check if Iterator is valid
	if (it != setOfStudents.end())
	{
		// Modify the mutuable content which is not
		// used in comparision or indexing
		it->mName = "Aarav";
		std::cout << it->mId << " :: " << it->mName << std::endl;
	}

	// Check if a student with ID 3 exists in set
	// Not possible to fetch the iterator with count(),
	// It returns the count only
	if (setOfStudents.count(Student(3, "")) != 0)
	{
		std::cout << it->mId << " Exist in Set" << std::endl;
	}

	return 0;

}

Output:
3 :: Aarav
3 Exist in Set

 

Join a list of 2000+ Programmers for latest Tips & Tutorials