Thursday, June 11, 2020

C++ example: custom class type used in unordered_map

C++ example: custom class type used in unordered_map

To use a custom class type as key in unordered_map, we need to overload the == operator and define custom hash function for this type. See the below example.

#include <iostream>
#include <string>
#include <unordered_map>

using namespace std;

class Student{
public:
    Student(const string& name, int age):name(name), age(age){}

    friend bool operator==(const Student& lhs, const Student& rhs){
        return lhs.name == rhs.name && lhs.age == rhs.age;
    }

    void output() const{
        cout<<"Name "<<name<<" Age "<<age<<endl;
    }

public:
    string name;
    int age;
};

struct hashStudent{
    std::size_t operator()(const Student& stu) const{
        return hash<string>()(stu.name)| (hash<int>()(stu.age)<<1);
    }
};

int main(){
    unordered_map<Student, int, hashStudent> m;
    m.emplace(Student{"John", 21}, 4);
    m.emplace(Student{"John", 12}, 3);
    m.emplace(Student{"Ann", 24}, 2);

    for(const auto& [key, val]: m){
        cout<<key.name<<" "<<key.age<<" "<<val<<endl;
    }
    return 0;
}

Saturday, June 6, 2020

C++ priority queue custom comparator

C++ priority queue custom comparator

Method1

#include <iostream>
#include <string>
#include <vector>
#include <queue>

using namespace std;

class Student{
public:
	Student(const string& name, int age):name(name), age(age){}

	friend bool operator<(const Student& lhs, const Student& rhs){
		if(lhs.name == lhs.name){
			return lhs.age < rhs.age;
		}
		return lhs.name < rhs.name;		
	}

	void output() const{
		cout<<"Name "<<name<<" Age "<<age<<endl;
	}

public:
	string name;
	int age;
};

int main(){
	priority_queue<Student> q;
	q.push(Student{"John", 21});
	q.push(Student{"John", 12});
	q.push(Student{"Ann", 24});

	while(!q.empty()){
		q.top().output();
		q.pop();
	}
	return 0;
}

Method2

#include <iostream>
#include <string>
#include <vector>
#include <queue>

using namespace std;

class Student{
public:
	Student(const string& name, int age):name(name), age(age){}

	bool operator<(const Student& other) const{
		if(name == other.name){
			return age < other.age;
		}
		return name < other.name;
	}

	void output() const{
		cout<<"Name "<<name<<" Age "<<age<<endl;
	}

public:
	string name;
	int age;
};

int main(){
	priority_queue<Student> q;
	q.push(Student{"John", 21});
	q.push(Student{"John", 12});
	q.push(Student{"Ann", 24});

	while(!q.empty()){
		q.top().output(); 
		q.pop();
	}
	return 0;
}

Method3

#include <iostream>
#include <string>
#include <vector>
#include <queue>

using namespace std;

class Student{
public:
	Student(const string& name, int age):name(name), age(age){}

	void output() const{
		cout<<"Name "<<name<<" Age "<<age<<endl;
	}

public:
	friend struct comp;

	string name;
	int age;
};

struct comp{
	bool operator()(const Student& lhs, const Student& rhs){
		if(lhs.name == lhs.name){
			return lhs.age < rhs.age;
		}
		return lhs.name < rhs.name;				
	}
};

int main(){
	priority_queue<Student, vector<Student>, comp> q;
	q.push(Student{"John", 21});
	q.push(Student{"John", 12});
	q.push(Student{"Ann", 24});

	while(!q.empty()){
		q.top().output(); 
		q.pop();
	}
	return 0;
}

Method4*

#include <iostream>
#include <string>
#include <vector>
#include <queue>

using namespace std;

class Student{
public:
	Student(const string& name, int age):name(name), age(age){}

	void output() const{
		cout<<"Name "<<name<<" Age "<<age<<endl;
	}

public:
	string name;
	int age;
};

bool comp(const Student& lhs, const Student& rhs){
	if(lhs.name == lhs.name){
		return lhs.age < rhs.age;
	}
	return lhs.name < rhs.name;				
}

int main(){
	priority_queue<Student, vector<Student>, std::function<bool(const Student&, const Student&)>> q(comp);
	q.push(Student{"John", 21});
	q.push(Student{"John", 12});
	q.push(Student{"Ann", 24});

	while(!q.empty()){
		q.top().output(); 
		q.pop();
	}
	return 0;
}

Method5

#include <iostream>
#include <string>
#include <vector>
#include <queue>

using namespace std;

class Student{
public:
	Student(const string& name, int age):name(name), age(age){}

	void output() const{
		cout<<"Name "<<name<<" Age "<<age<<endl;
	}

public:
	string name;
	int age;
};

int main(){

	auto comp = [](const Student& lhs, const Student& rhs)->bool{
		if(lhs.name == lhs.name){
			return lhs.age < rhs.age;
		}
		return lhs.name < rhs.name;	
	};

	priority_queue<Student, vector<Student>, decltype(comp)> q(comp);
	q.push(Student{"John", 21});
	q.push(Student{"John", 12});
	q.push(Student{"Ann", 24});

	while(!q.empty()){
		q.top().output(); 
		q.pop();
	}
	return 0;
}