티스토리 뷰
이 함수는 앞서 소개한 all_of 나 any_of 과 비슷한 성격을 띠고 있는 함수지만, 앞의 두 함수보다 더 자주 사용하고 유용하게 사용할 수 있는 함수를 하나 소개하고자 한다.
만약, 다음과 같은 문제가 있다고 하여보자.
- 어떤 container 안에 모든 원소가 -1이 아닌지 확인하시오.
none_of를 알기 전, 필자는 이러한 코드를 작성하였을 것이다.
1 2 3 4 5 6 7 | bool is_not_minus_one = true; for (int i = 0; i < (int)num.size(); i++) { if (num[i] == -1) { is_not_minus_one = false; break; } } | cs |
이런이런! 7줄이나 먹는 코드라니, 매우 비효율적인 코드이다. 이를 none_of 함수를 사용하여 한 줄로 압축하여보자!
1. none_of
(※ https://www.cplusplus.com/reference/algorithm/none_of/ 에서 함수에 대한 정보를 확인할 수 있다.)
C++의 알고리즘 관련이 담긴 헤더 <algorithm.h>에서의 none_of 함수는 다음과 같은 구조를 가진다.
bool none_of (InputIterator first, InputIterator last, UnaryPredicate pred)
none_of는 3개의 인자를 받고 1개의 값을 반환한다.
- InputIterator first : 배열이나 어떤 container의 자료형의 시작부 혹은 포인터
- InputIterator last : 배열이나 어떤 container의 자료형의 끝부 혹은 포인터
- UnaryPredicate pred : 배열이나 어떤 container를 인자로 받아 bool 형태를 반환하는 함수, 본래 인자를 수정하지 않는 함수여야 하며, 함수의 포인터 혹은 함수가 올 수 있다.
- Return Value : pred의 반환 값이 true인 데이터가 적어도 하나 존재할 경우 False, 만약 데이터가 비어있거나 pred의 반환값이 모두 false일 경우 True
구체적으로 이 함수의 역할을 말하자면, 범위 [first, last)에서 모든 값이 각각 pred의 인자로 넣었을 때 모두 false를 반환하면 True를 반환하고, 아니라면 False를 반환한다. 예외적으로 배열이나 container가 비어있을 때 True를 반환한다. 만약 이해가 안 된다면, 같은 역할을 하는 코드를 작성하면 다음과 같이 작성할 수 있다.
1 2 3 4 5 6 7 8 | template<class InputIterator, class UnaryPredicate> bool none_of (InputIterator first, InputIterator last, UnaryPredicate pred) { while (first!=last) { if (pred(*first)) return false; ++first; } return true; } | cs |
쉽게 말해, 배열이나 자료형 안에 조건을 모두 만족하지 않는지 확인하는 함수이다. any_of 와는 반대 역할을 하는 함수라 생각하면 쉽다.
2. 예제 코드
위에서 7줄이나 된 코드를 람다 함수와 none_of를 이용하면 단 한 줄로 바꿀 수 있다.
1 | bool is_not_minus_one = none_of(num.begin(), num.end(), [](int x) { return x == -1; }); | cs |
7줄이나 되던 코드를 한 줄로 압축하였다. 이처럼 특정 배열이나 container에 조건을 만족하는데 유용하게 사용할 수 있는 함수이다.
특히, 그래프 탐색에서 특정 지점을 지나지 않았다는 것을 검사하거나, 방문하지 않은 지점, 혹은 특정 수가 아직 남아있는지 검사하는데 활용할 수 있다.
예를 들어, 방문을 했는 지 기록하는, 100x100의 크기를 가지는 boolean 배열 bool visited[100][100]이 있다고 하였을 때, 모두 방문하였는지 다음과 같은 방법으로 확인할 수 있다.
1 | bool is_all_visited= none_of(&visited[0][0], &visited[0][0]+100*100 ,[](bool x) { return !x ; }); | cs |
하나씩 배열에 접근하기에 시간복잡도는 배열의 길이인 O(n) 을 가지며, 만약 배열의 범위를 초과하여 index에 접근할 경우 undefined behavior 가 발생할 수 있다.
도움이 되었다면 지나가는 길에 하트 하나 눌러주세요, 양질의 글을 쓰는데 하나의 동기부여가 됩니다😍
지적이나 오타 수정 댓글 환영합니다!!
'C++' 카테고리의 다른 글
[C++] 최댓값과 최솟값을 한 번에 찾자 max_element / min_element (0) | 2022.04.12 |
---|---|
[C++] 아직도 sum += arr[i] 쓰시나요? accumulate으로 해결하세요! (0) | 2022.04.12 |
[C++] 배열 안을 한꺼번에 검사하는 손쉬운 방법 all_of (0) | 2022.04.12 |
[C++] 배열 안 원소가 있는지 한번에 확인하는 함수 any_of (0) | 2022.04.12 |
[C++] for문을 Python의 for문처럼 다루어보자. range-based for (0) | 2022.04.12 |
- Total
- Today
- Yesterday
- docker
- 사칙연산
- 함수
- 알고리즘
- Proactor
- C
- MIN
- BOJ
- JS
- Network
- 구현
- 문자열
- bomblab
- CSAPP
- equal
- GDSC
- BRONZE
- for
- 프로그래밍
- Max
- 백준
- 수학
- effective async
- 제어문
- C++
- Python
- 헤더
- 시간복잡도
- react
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |