unordered_set
- Each value must be unique
- Keys are immutable, cannot be modified, but can be inserted and removed
- Store elements in no particular order
- Elements are organized into buckets depending on their hash values
- Implemented as hash table
Container Iterator
#include <iostream>
#include <string>
#include <unordered_set>
int main(int argc, char *argv[])
{
std::unordered_set<std::string> s = {"Mercury", "Venus", "Earth", "Mars", "Jupiter", "Saturn", "Uranus", "Neptune"};
std::cout<<"#Bucket: "<<s.bucket_count()<<std::endl;
//begin and end
for(auto it = s.begin(); it != s.end(); ++it)
std::cout<<*it<<"|";
std::cout<<std::endl;
return 0;
}
- Tranverse elements in the hash table
Bucket Iterator
#include <iostream>
#include <string>
#include <unordered_set>
int main(int argc, char *argv[])
{
std::unordered_set<std::string> s = {"Mercury", "Venus", "Earth", "Mars", "Jupiter", "Saturn", "Uranus", "Neptune"};
std::cout<<"#Bucket: "<<s.bucket_count()<<std::endl;
//begin and end
for(int i = 0; i < s.bucket_count(); i++)
{
std::cout<<"Bucket "<<i<<": ";
for(auto it = s.begin(i); it != s.end(i); ++it)
std::cout<<*it<<"|";
std::cout<<std::endl;
}
return 0;
}
- Tranverse elements in a bucket
Buckets
#include <iostream>
#include <string>
#include <unordered_set>
int main(int argc, char *argv[])
{
std::unordered_set<std::string> s = {"Mercury", "Venus", "Earth", "Mars", "Jupiter", "Saturn", "Uranus", "Neptune"};
//bucket_count
std::cout<<"Bucket_Count: "<<s.bucket_count()<<std::endl;
//max_bucket_count
std::cout<<"Max_Bucket_Count: "<<s.max_bucket_count()<<std::endl;
//bucket_size
for(int i = 0; i < s.bucket_count(); i++)
std::cout<<"#"<<i<<" Bucket_Size: "<<s.bucket_size(i)<<std::endl;
//bucket
std::cout<<"Bucket: "<<s.bucket("Mars")<<std::endl;
return 0;
}
Operations
#include <iostream>
#include <string>
#include <unordered_set>
template <class T>
void display(T it, T end)
{
while(it != end)
{
std::cout<<*it<<" ";
std::advance(it, 1);
}
std::cout<<std::endl;
}
int main(int argc, char *argv[])
{
std::unordered_set<std::string> s = {"Mercury", "Venus", "Earth", "Mars", "Jupiter", "Saturn", "Uranus", "Neptune"};
//insert
s.insert("Unknown");
//size
std::cout<<"Size: "<<s.size()<<std::endl;
//find
auto it = s.find("Earth");
//erase
s.erase(it);
display(s.begin(), s.end());
return 0;
}
Hash
//Comparison struct operator()
#include <iostream>
#include <functional>
#include <string>
#include <unordered_set>
struct StringHash
{
size_t operator()(const std::string &str) const
{
size_t t = 0;
for(int i = 0; i < str.size(); i++)
t += str[i];
return t%10;
}
};
template <class T>
void display(T it, T end)
{
while(it != end)
{
std::cout<<*it<<" ";
std::advance(it, 1);
}
std::cout<<std::endl;
}
int main(int argc, char *argv[])
{
std::unordered_set<std::string, StringHash> s;
s.insert("Mercury");
s.insert("Venus");
s.insert("Earth");
s.insert("Mars");
s.insert("Jupiter");
s.insert("Saturn");
s.insert("Uranus");
s.insert("Neptune");
std::cout<<"Size: "<<s.size()<<std::endl;
for(int i = 0; i < s.bucket_count(); i++)
{
std::cout<<"Bucket "<<i<<": ";
for(auto it = s.begin(i); it != s.end(i); ++it)
std::cout<<*it<<" ";
std::cout<<std::endl;
}
display(s.begin(), s.end());
return 0;
}
//Comparison function
#include <iostream>
#include <functional>
#include <string>
#include <unordered_set>
size_t h(const std::string &str)
{
size_t t = 0;
for(int i = 0; i < str.size(); i++)
t += str[i];
return t%10;
}
template <class T>
void display(T it, T end)
{
while(it != end)
{
std::cout<<*it<<" ";
std::advance(it, 1);
}
std::cout<<std::endl;
}
int main(int argc, char *argv[])
{
std::unordered_set<std::string, std::function<decltype(h)>> s(10, h);
s.insert("Mercury");
s.insert("Venus");
s.insert("Earth");
s.insert("Mars");
s.insert("Jupiter");
s.insert("Saturn");
s.insert("Uranus");
s.insert("Neptune");
std::cout<<"Size: "<<s.size()<<std::endl;
for(int i = 0; i < s.bucket_count(); i++)
{
std::cout<<"Bucket "<<i<<": ";
for(auto it = s.begin(i); it != s.end(i); ++it)
std::cout<<*it<<" ";
std::cout<<std::endl;
}
display(s.begin(), s.end());
return 0;
}
//Lambda
#include <iostream>
#include <functional>
#include <string>
#include <unordered_set>
auto h = [](const std::string &a){return a[0];};
template <class T>
void display(T it, T end)
{
while(it != end)
{
std::cout<<*it<<" ";
std::advance(it, 1);
}
std::cout<<std::endl;
}
int main(int argc, char *argv[])
{
std::unordered_set<std::string, std::function<size_t (const std::string &a)>> s(26, h);
s.insert("Mercury");
s.insert("Venus");
s.insert("Earth");
s.insert("Mars");
s.insert("Jupiter");
s.insert("Saturn");
s.insert("Uranus");
s.insert("Neptune");
std::cout<<"Size: "<<s.size()<<std::endl;
for(int i = 0; i < s.bucket_count(); i++)
{
std::cout<<"Bucket "<<i<<": ";
for(auto it = s.begin(i); it != s.end(i); ++it)
std::cout<<*it<<" ";
std::cout<<std::endl;
}
display(s.begin(), s.end());
return 0;
}
Hash with Objects
//Hash, struct; Equality, operator== in class
//Rectangle.h
#ifndef RECTANGLE_H
#define RECTANGLE_H
class Rectangle
{
private:
double width;
double length;
public:
//constructor
Rectangle(){}
Rectangle(double w, double l):width(w), length(l){}
//accessor
double getWidth() const;
double getLength() const;
double getArea() const;
//mutator
void setWidth(double w);
void setLength(double l);
//operator==
bool operator==(const Rectangle &right) const
{
return (getArea() == right.getArea());
}
};
#endif
//Rectangle.cpp
#include "Rectangle.h"
double Rectangle::getWidth() const
{
return width;
}
double Rectangle::getLength() const
{
return length;
}
double Rectangle::getArea() const
{
return width*length;
}
void Rectangle::setWidth(double w)
{
width = w;
}
void Rectangle::setLength(double l)
{
length = l;
}
//main.cpp
#include <iostream>
#include <functional>
#include <unordered_set>
#include "Rectangle.h"
struct RectangleHash
{
size_t operator()(const Rectangle &r) const
{
std::hash<double> h;
return (h(r.getWidth()) ^ h(r.getLength()));
}
};
template <class T>
void display(T it, T end)
{
while(it != end)
{
std::cout<<it->getArea()<<" ";
std::advance(it, 1);
}
std::cout<<std::endl;
}
int main(int argc, char *argv[])
{
std::unordered_set<Rectangle, RectangleHash> s;
s.insert(Rectangle(1, 2));
s.insert(Rectangle(2, 3));
s.insert(Rectangle(3, 4));
s.insert(Rectangle(4, 5));
std::cout<<"Size: "<<s.size()<<std::endl;
for(int i = 0; i < s.bucket_count(); i++)
{
std::cout<<"Bucket "<<i<<": ";
for(auto it = s.begin(i); it != s.end(i); ++it)
std::cout<<it->getArea()<<" ";
std::cout<<std::endl;
}
display(s.begin(), s.end());
return 0;
}
//Hash, struct; Equality, struct
//Rectangle.h
#ifndef RECTANGLE_H
#define RECTANGLE_H
class Rectangle
{
private:
double width;
double length;
public:
//constructor
Rectangle(){}
Rectangle(double w, double l):width(w), length(l){}
//accessor
double getWidth() const;
double getLength() const;
double getArea() const;
//mutator
void setWidth(double w);
void setLength(double l);
};
#endif
//Rectangle.cpp
#include "Rectangle.h"
double Rectangle::getWidth() const
{
return width;
}
double Rectangle::getLength() const
{
return length;
}
double Rectangle::getArea() const
{
return width*length;
}
void Rectangle::setWidth(double w)
{
width = w;
}
void Rectangle::setLength(double l)
{
length = l;
}
//main.cpp
#include <iostream>
#include <functional>
#include <unordered_set>
#include "Rectangle.h"
struct comp{
bool operator()(const Rectangle &a, const Rectangle &b) const
{
return (a.getArea() == b.getArea());
}
};
struct RectangleHash
{
size_t operator()(const Rectangle &r) const
{
std::hash<double> h;
return (h(r.getWidth()) ^ h(r.getLength()));
}
};
template <class T>
void display(T it, T end)
{
while(it != end)
{
std::cout<<it->getArea()<<" ";
std::advance(it, 1);
}
std::cout<<std::endl;
}
int main(int argc, char *argv[])
{
std::unordered_set<Rectangle, RectangleHash, comp> s;
s.insert(Rectangle(1, 2));
s.insert(Rectangle(2, 3));
s.insert(Rectangle(3, 4));
s.insert(Rectangle(4, 5));
std::cout<<"Size: "<<s.size()<<std::endl;
for(int i = 0; i < s.bucket_count(); i++)
{
std::cout<<"Bucket "<<i<<": ";
for(auto it = s.begin(i); it != s.end(i); ++it)
std::cout<<it->getArea()<<" ";
std::cout<<std::endl;
}
display(s.begin(), s.end());
return 0;
}
Reference