All is well

[C++] iota()를 이용하여 연속된 값을 빠르게 채우기 (ft. transform(), generate()) 본문

C++

[C++] iota()를 이용하여 연속된 값을 빠르게 채우기 (ft. transform(), generate())

D0YUN 2025. 3. 9. 16:46

iota() 함수란?

C++에서 `iota()` 함수는 특정 범위에 연속된 값을 채우는 함수로, 시작 값을 설정하면 이후 요소들을 1씩 증가하며 채워 넣습니다.


iota() 함수 정의

`iota()` 함수의 정의는 다음과 같습니다.
void iota(ForwardIterator first, ForwardIterator last, T value);
  • first: 값을 채울 범위의 시작 (begin())
  • last: 값을 채울 범위의 끝 (end())
  • value: 채우기 시작할 값

기본적인 iota() 사용법

벡터를 1부터 N까지 자동으로 채우기

#include <iostream>
#include <vector>
#include <numeric>  // iota()를 사용하기 위한 헤더

using namespace std;

int main() {
    vector<int> v(5); // 크기가 5인 벡터 생성

    // 1부터 시작하는 연속된 값을 벡터에 채운다.
    iota(v.begin(), v.end(), 1);

    // 결과 출력
    for (int num : v) cout << num << " ";

    return 0;
}

 

실행 결과

 
1 2 3 4 5

 

동작 과정

  1. v[0] = 1 (초기 값 1 설정)
  2. v[1] = 2 (이전 값에 +1 증가)
  3. v[2] = 3
  4. v[3] = 4
  5. v[4] = 5

실행 결과를 통해 확인할 수 있듯이 각 원소는 앞의 원소보다 1씩 증가하는 값으로 채워집니다.


iota()를 활용한 다양한 예제

ex1) 0부터 시작하는 값 채우기

vector<int> v(10);
iota(v.begin(), v.end(), 0);  // 0부터 9까지 자동 채움
// 결과: 0 1 2 3 4 5 6 7 8 9

ex2) 100부터 시작하는 값 채우기

vector<int> v(5);
iota(v.begin(), v.end(), 100);  // 100부터 104까지 자동 채움
// 결과: 100 101 102 103 104

ex3) 배열을 초기화할 때 사용하기

int arr[6];
iota(arr, arr + 6, 10);  // 10부터 15까지 자동 채움
// 결과: 10 11 12 13 14 15

 


 

`iota()`를 변형하여 특정 간격(2, 5 등)으로 값 증가시키기

`iota()`는 기본적으로 1씩 증가하는 값을 채우지만,
`transform()` 또는 `generate()`를 활용하면 1 이외의 숫자만큼 증가하는 값을 저장할 수도 있습니다.

방법 1: `iota()` + `transform()` 활용

#include <iostream>
#include <vector>
#include <numeric>  // iota()
#include <algorithm> // transform()

using namespace std;

int main() {
    vector<int> v(10); // 크기가 10인 벡터 생성

    // 0부터 9까지 연속된 값 채우기
    iota(v.begin(), v.end(), 0);

    // 각 요소를 2씩 증가하도록 변환 (0, 2, 4, 6, 8, ...)
    transform(v.begin(), v.end(), v.begin(), [](int x) { return x * 2; });

    // 결과 출력
    for (int num : v) cout << num << " ";

    return 0;
}

 

`iota()`와 `transform()`을 활용한 방식의 원리는 다음과 같습니다.

  1. `iota(v.begin(), v.end(), 0);`  v를 0부터 9까지 채웁니다.
  2. `transform()`을 사용하여 각 요소를 2배로 변경합니다.
    • `[](int x) { return x * 2; }`는 람다 함수로, 기존 값 x를 2배로 변환하는 역할을 합니다.
  3. 결과적으로 0, 2, 4, 6, 8, ... 같은 수열이 생성됩니다.

 

실행 결과

 
0 2 4 6 8 10 12 14 16 18

 

 

방법 2: `generate()` 활용 (`iota()` 없이 특정 간격 설정)

`generate()`를 사용하면 `iota()` 없이 특정 간격으로 값을 채울 수 있다.

#include <iostream>
#include <vector>
#include <algorithm> // generate()

using namespace std;

int main() {
    vector<int> v(10);
    int start = 2;
    int step = 5;

    // 람다 함수로 각 요소를 채운다.
    generate(v.begin(), v.end(), [&]() { 
        int val = start; 
        start += step; 
        return val;
    });

    // 결과 출력
    for (int num : v) cout << num << " ";

    return 0;
}

 

`generate()`를 사용하는 방식의 원리는 다음과 같습니다.

 

  1. `start` 변수에 초기값을 설정하고, `step`만큼 증가시키면서
  2. 각 요소를 직접 채웁니다.

 

실행 결과

 
2 7 12 17 22 27 32 37 42 47

 

 

방법 3: for 루프 직접 사용 (기본적인 방법)

가장 기본적인 방법으로, `iota()`보다 코드가 길어지는 단점이 있습니다.

#include <iostream>
#include <vector>

using namespace std;

int main() {
    vector<int> v(10);

    // 2부터 시작해서 5씩 증가하는 수열 생성
    for (int i = 0; i < v.size(); i++) {
        v[i] = 2 + i * 5;
    }

    // 결과 출력
    for (int num : v) cout << num << " ";

    return 0;
}

실행 결과

 
2 7 12 17 22 27 32 37 42 47