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::iota
C ++ 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);
그러나 나는 그것을 추천하지 않을 것입니다. 🙂