태그 보관물: stl

stl

std :: fill을 사용하여 증가하는 숫자로 벡터 채우기 std::fill싶지만 하나의

vector<int>using 을 채우고 std::fill싶지만 하나의 값 대신 벡터에 숫자가 오름차순으로 포함되어야합니다.

함수의 세 번째 매개 변수를 하나씩 반복하여이를 달성하려고 시도했지만 이것은 1 또는 2로 채워진 벡터 만 제공합니다 ( ++연산자 의 위치에 따라 다름 ).

예:

vector<int> ivec;
int i = 0;
std::fill(ivec.begin(), ivec.end(), i++); // elements are set to 1
std::fill(ivec.begin(), ivec.end(), ++i); // elements are set to 2



답변

다음 std::iota과 같이 사용하는 것이 좋습니다 .

std::vector<int> v(100) ; // vector with 100 ints.
std::iota (std::begin(v), std::end(v), 0); // Fill with 0, 1, ..., 99.

즉, c++11지원 이 없으면 (내가 일하는 곳에서 여전히 실제 문제) std::generate다음과 같이 사용 하십시오.

struct IncGenerator {
    int current_;
    IncGenerator (int start) : current_(start) {}
    int operator() () { return current_++; }
};

// ...

std::vector<int> v(100) ; // vector with 100 ints.
IncGenerator g (0);
std::generate( v.begin(), v.end(), g); // Fill with the result of calling g() repeatedly.


답변

std::iota알고리즘 (에서 정의 됨 <numeric>)을 사용해야 합니다 .

  std::vector<int> ivec(100);
  std::iota(ivec.begin(), ivec.end(), 0); // ivec will become: [0..99]

왜냐하면 std::fill단지 주어진 범위 내의 요소에 지정된 고정 값을 할당한다 [n1,n2). 그리고 초기 값부터 시작하여를 사용하여 순차적으로 증가하는 값으로 std::iota주어진 범위 [n1, n2)를 채 웁니다 . 대안으로 ++value사용할 수도 있습니다 std::generate.

이것이 std::iotaC ++ 11 STL 알고리즘 임을 잊지 마십시오 . 그러나 많은 최신 컴파일러 (예 : GCC, Clang 및 VS2012)가 지원합니다. http://msdn.microsoft.com/en-us/library/vstudio/jj651033.aspx

PS이 함수는 프로그래밍 언어 APL 의 정수 함수 이름을 따서 명명되었으며 그리스 문자 iota를 나타냅니다. 나는 원래 APL 에서이 이상한 이름이 “integer”(수학에서는 복소수의 허수 부분을 나타내는 데 널리 사용되지만) 유사하기 때문에 선택되었다고 추측합니다 .


답변

내 첫 번째 선택 (C ++ 11에서도)은 다음과
boost::counting_iterator같습니다.

std::vector<int> ivec( boost::counting_iterator<int>( 0 ),
                       boost::counting_iterator<int>( n ) );

또는 벡터가 이미 생성 된 경우 :

std::copy( boost::counting_iterator<int>( 0 ),
           boost::counting_iterator<int>( ivec.size() ),
           ivec.begin() );

Boost를 사용할 수 없다면 std::generate(다른 답변에서 제안한대로) 또는 counting_iterator필요한 경우 다양한 장소에서 직접 구현 하십시오. (Boost를 사용하면 transform_iterator의 a counting_iterator를 사용하여 모든 종류의 흥미로운 시퀀스를 만들 수 있습니다 . Boost 없이는에 대한 생성기 객체 유형의 형태로 std::generate또는에 연결할 수있는 방식으로이 작업을 직접 수행 할 수 있습니다. 손으로 쓴 계산 반복자.)


답변

std :: generate로 답을 봤지만 함수 외부에서 카운터를 선언하거나 생성기 클래스를 만드는 대신 람다 내부에서 정적 변수를 사용하여 “개선”할 수도 있습니다.

std::vector<int> vec;
std::generate(vec.begin(), vec.end(), [] {
    static int i = 0;
    return i++;
});

좀 더 간결하다고 생각합니다


답변

C ++ 11 기능을 사용하지 않으려면 다음을 사용할 수 있습니다 std::generate.

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

struct Generator {
    Generator() : m_value( 0 ) { }
    int operator()() { return m_value++; }
    int m_value;
};

int main()
{
    std::vector<int> ivec( 10 );

    std::generate( ivec.begin(), ivec.end(), Generator() );

    std::vector<int>::const_iterator it, end = ivec.end();
    for ( it = ivec.begin(); it != end; ++it ) {
        std::cout << *it << std::endl;
    }
}

이 프로그램은 0에서 9까지 인쇄합니다.


답변

알고리즘 헤더 파일에 존재 하는 생성 기능을 사용할 수 있습니다 .

코드 스 니펫 :

#include<bits/stdc++.h>
using namespace std;


int main()
{
    ios::sync_with_stdio(false);

    vector<int>v(10);

    int n=0;

    generate(v.begin(), v.end(), [&n] { return n++;});

    for(auto item : v)
    {
      cout<<item<<" ";
    }
    cout<<endl;

    return 0;
}


답변

std :: iota는 시퀀스 n, n + 1, n + 2, …로 제한됩니다.

하지만 일반적인 시퀀스 f (0), f (1), f (2) 등으로 배열을 채우려면 어떻게해야할까요? 종종 상태 추적 생성기를 피할 수 있습니다. 예를 들면

int a[7];
auto f = [](int x) { return x*x; };
transform(a, a+7, a, [a, f](int &x) {return f(&x - a);});

일련의 사각형을 생성합니다.

0 1 4 9 16 25 36

그러나이 트릭은 다른 컨테이너에서는 작동하지 않습니다.

C ++ 98을 고수한다면 다음과 같은 끔찍한 일을 할 수 있습니다.

int f(int &x) { int y = (int) (long) &x / sizeof(int); return y*y; }

그리고

int a[7];
transform((int *) 0, ((int *) 0) + 7, a, f);

그러나 나는 그것을 추천하지 않을 것입니다. 🙂