[C++] 더이상 arr[i] = i는 그만! 고수들은 쓰는 함수 iota
Union-Find / 분리집합 알고리즘이나 여러 문제를 풀 때 종종 자기 자신의 index를 값으로 초기화 해야하는 경우가 많다.
우린 그럴때마다 for문을 이용한 방법으로 다음과 같은 코드를 사용한다.
1 2 3 | for (int i = 0; i < n; i++) { par[i] = i; } | cs |
이를 한 방에 처리해주는 함수가 있으니, 이름하여 iota 되시겠다!
1. iota
(※ https://www.cplusplus.com/reference/numeric/iota/ 에서 함수에 대한 정보를 확인할 수 있다.)
C의 Sequence관련 여러 함수들이 담긴 헤더 <numeric.h>에서의 iota 함수는 다음과 같은 구조를 가진다.
void iota (ForwardIterator first, ForwardIterator last, T val)
iota는 3개의 인자를 받는다.
- ForwardIterator first : 배열이나 어떤 container 자료형의 시작부 혹은 포인터
- ForwardIterator last : 배열이나 어떤 container 자료형의 끝부 혹은 포인터
- T val : 하나씩 쌓을 값의 초깃값
구체적으로 이 함수의 역할을 말하자면, 범위 [first, last) 에서 val을 채우고, 이후 ++val연산을 수행한다. 만약 이해가 안된다면, 같은 역할을 하는 코드를 작성하면 다음과 같이 작성할 수 있다.
1 2 3 4 5 6 7 8 | template <class ForwardIterator, class T> void iota (ForwardIterator first, ForwardIterator last, T val) { while (first!=last) { *first = val; ++first; ++val; } } | cs |
쉽게 말해, first부터 last까지 val이 증가하면서 들어간다고 생각하면 된다.
2. 예제 코드
iota함수의 예제 코드를 작성하여 보자.
만약 배열 nums[10]에 숫자 100부터 차례로 증가하며 넣어야 한다고 했을 때, 다음과 같이 작성할 수 있다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | #include <iostream> #include <numeric> using namespace std; int main() { int nums[10]; iota(nums, nums+10, 100); for (int i = 0; i < 10; i++) { cout << nums[i] << ' '; } return 0; } | cs |
이에 대한 실행 결과는 다음과 같다.
1 | 100 101 102 103 104 105 106 107 108 109 | cs |
int형 10개를 저장하는 배열 nums에 차례로 100부터 109까지 들어간 것을 확인할 수 있다.
이처럼 1씩 증가하면서 배열을 초기화하거나 채워야 할 경우 유용하게 사용할 수 있는 함수이다.
하나씩 배열에 접근하기에 시간복잡도는 배열의 길이인 O(n) 을 가지며, 만약 배열의 범위를 초과하여 index에 접근할 경우 undefined behavior 가 발생할 수 있다.
도움이 되었다면 지나가는 길에 하트 하나 눌러주세요, 양질의 글을 쓰는데 하나의 동기부여가 됩니다😍
지적이나 오타 수정 댓글 환영합니다!!