영넌 개발로그

[C++ STL] algorithm) find, find_if, count, count_if, for_each, lambda 본문

코딩/C++

[C++ STL] algorithm) find, find_if, count, count_if, for_each, lambda

영넌 2020. 12. 7. 22:29

container는 data를 저장하는 공간, iterator는 container 안에 있는 data를 순차적으로 모두 access할 수 있는 방법을 제공한다. 그럼 그 데이터를 읽어서 무엇을 할지에 대한 처리는?? 그런 것을 알고리즘(algorithm)이라고 한다. 이 또한 STL 라이브러리에서 제공한다. 여기서는 핵심적인 몇 가지만 다뤄보도록 하겠다.

아래 7개는 대부분의 컨테이너에 대해서 동작하며, 통일된 방법으로 사용할 수 있다.

 

1. find 

container 자체에서 find 메소드를 제공하는 컨테이너도 있기는 한데 그렇지 않은 것들도 있다. 내가 원하는 데이터가 어디있는지 찾기 위해 사용하는 알고리즘이다. 아주 똑같아야만 찾을 수 있다. 

2. find_if 

find랑 비슷한데 내가 찾고자 하는 것은 어떤 조건을 만족시키는 것이다. 라는 조건을 붙일 수 있다. 조건을 만족하는 데이터를 찾는다. 

#include <iostream> 
#include <vector>
#include <algorithm>
#include <string>

using namespace std;


class Person {

private:	//데이터 은닉성 (실제 데이터와 내보내는 데이터를 다르게하고 싶을 때 사용)
	string name;
	int age;
public:
	Person(string _name, int _age) : name(_name), age(_age) {};
	bool operator== (const Person & p1) {
		if ((name == p1.name) && (age == p1.age)) {
			return true;
		}
		return false;
	}

	void showPerson() {
		cout << "Name: " << name << ", Age: " << age << endl;
	}
	int getAge() {		//getter
		return age;
	}
	string getName() {	//getter
		return name;
	}
	
};

bool findCondition(Person& p1) {
	if (p1.getAge() == 31) {
		return true;
	}
	return false;
}

int main() {
	vector<Person> peopleDB;

	peopleDB.push_back(Person("mike1", 26));
	peopleDB.push_back(Person("mike2", 20));
	peopleDB.push_back(Person("mike3", 31));
	peopleDB.push_back(Person("mike4", 24));
	peopleDB.push_back(Person("mike5", 19));

	cout << "-------------------------------------" << endl;

	for (auto& e : peopleDB) {
		e.showPerson();
	}

	//1. 찾는 범위를 iterator를 이용해서 지정
	//2. 찾는 값을 지정
	//3. 반환값으로 iterator(point) 위치..
	//auto pos = find(peopleDB.begin(), peopleDB.end(), Person("mike2",21));
	auto pos = find(peopleDB.begin(), peopleDB.end(), Person("mike2",20));

	if (pos == peopleDB.end()) {
		cout << "Failed to find" << endl;
	}
	else { //success
		cout << "Success: ";
		(*pos).showPerson();
	}

	cout << "------find_if--------------------------" << endl;
	//여러개 찾으려면 범위지정을 계속적으로 해주어야한다.
	pos = find_if(peopleDB.begin(), peopleDB.end(), findCondition);

	if (pos == peopleDB.end()) {
		cout << "Failed to find" << endl;
	}
	else { //success
		cout << "Success: ";
		(*pos).showPerson();
	}
	return 0;

}

 

3. count 

나와 똑같은 것이 몇 개가 있는가? 를 찾는 알고리즘이다.

4. count_if 

조건을 만족하는 것의 개수를 세는 알고리즘이다. 예를 들어 어떤 그룹에서 나이가 20대인 사람은 모두 몇명인가? 와 같은 질문에 답하기 좋은 알고리즘이다.

	cout << "------count--------------------------" << endl;

	int cnt = count(peopleDB.begin(), peopleDB.end(), Person("mike2", 20));

	cout << "Count result: " << cnt << endl;
	
	cout << "------count_it--------------------------" << endl;
	cnt = count_if(peopleDB.begin(), peopleDB.end(),
		[](Person& p1) {
			if (p1.getAge() > 21)
			{
				return true;
			}
			else {
				return false;
			}
		}
	);

 

5. for_each 

컨테이너에 들어있는 모든 데이터에 대해서 어떤 함수를 일괄적으로 적용해보고 싶을 때 사용한다. iterator를 활용하여 코딩을 할 수도 있지만 별도의 알고리즘을 제공해준다.

 

	cout << "------for_each--------------------------" << endl;
	for_each(peopleDB.begin(), peopleDB.end(),
		[](Person& p1) {
			p1.showPerson();
		}
	);

 

6. sort 

순차적으로 맞춰준다.

이런 알고리즘이 없으면 일일이 프로그래밍해서 사용해야하는데 제공해줘서 그냥 가져다 쓰면 된다. 

 

cout << "------sort--------------------------" << endl;

	sort(peopleDB.begin(), peopleDB.end(),
		//p1이 p2보다 순서가 빠르다면, true를 넘겨다오
		[](Person& p1, Person& p2) {
			if (p1.getAge() < p2.getAge()) {
				return true;
			}
			return false;

		});


	//sort 후에 vector안의 순서대로 출력
	for (auto& e : peopleDB) {
		e.showPerson();
	}

 

7. lambda expression 

이름이 없는 함수이다. (funtion without name)

  위에 2, 4번에서 조건을 지정해줄 때 함수(bool반환)를 지정해 주는데 이런 함수는 find_if나 count_if와 같은 알고리즘이 동작할 때만 쓰이는 함수이다. 그래서 굳이 이름을 가질 필요 없이 즉석 함수로서 일회용으로 쓰고 버릴 수 있다.

	//lambda expression
	//[](arguments...) { }


	//여러개 찾으려면 범위지정을 계속적으로 해주어야한다.
	//pos = find_if(peopleDB.begin(), peopleDB.end(), findCondition);
	pos = find_if(peopleDB.begin(), peopleDB.end(),
		[](Person& p1) {
			if (p1.getAge() == 31) {
				return true;
			}
			return false;
		}
	);

 

'코딩 > C++' 카테고리의 다른 글

[C++ SFML] 지뢰찾기 게임 만들기  (0) 2022.10.25
[C++ STL] container map  (0) 2020.12.07
[C++ STL] container set 집합  (0) 2020.12.07
[C++ STL] Standard template library /Container adaptor  (0) 2020.12.07
Comments