http://linuxspot.tistory.com/47
STL(Standard Template Library) Containers 중 vector에 대한 내용입니다. 대부분의 예제는 www.cplusplus.com을 참고하였습니다.
vector::vector
vector는 아래와 같은 다양한 생성자를 지원합니다.
#include <iostream>
#include <vector>
using namespace std;
int main(int argc, char* argv[])
{
vector<int> first;
vector<int> second(4, 100);
vector<int> third(second.begin(), second.end());
vector<int> four(third);
int myints[] = {16, 2, 77, 29};
vector<int> fifth(myints, myints + sizeof(myints) / sizeof(int));
cout << "The contents of fifth are:";
for (int i = 0; i < fifth.size(); i++) {
cout << " " << fifth[i];
}
cout << endl;
return 0;
}
first는 int형 자료형을 저장 할 수 있는 빈 벡터입니다. 자료의 갯수를 반환하는 size() 함수를 호출하면 0이 반환됩니다. second는 총 4개의 원소를 가지는데 각각의 원소는 100으로 초기화된 값을 가집니다. third는 첫번째 인수에서 두번째 인수까지 해당되는 범위의 요소들을 저장합니다. 위 소스에서는 second와 동일한 원소를 갖는 vector가 생성됩니다. four는 third와 동일한 vector를 생성할 때 사용하는 생성자입니다.
fifth는 배열의 값을 vector로 저장하는 것을 보여주는데, third를 생성할 때와 동일한 방식으로 vector를 생성합니다. myints 배열의 시작 주소와 마지막 원소의 다음 주소를 이용하여 생성하고 있습니다.
위 소스의 실행 결과는 다음과 같습니다.
vector::assign
vector에 저장되어 있던 기존 값들을 새로운 값들로 대입할 때 사용하는 함수입니다.
#include <iostream>
#include <vector>
using namespace std;
int main(int argc, char* argv[])
{
vector<int> first;
vector<int> second;
vector<int> third;
first.assign(7, 100);
vector<int>::iterator it;
it = first.begin() + 1;
second.assign(it, first.end() - 1);
int myints[] = {1776, 7, 4};
third.assign(myints, myints + 3);
cout << "size of first: " << int(first.size()) << endl;
cout << "size of second: " << int(second.size()) << endl;
cout << "size of third: " << int(third.size()) << endl;
}
assign 방법에는 두가지가 있는데 위 소스의 first와 같이 n개의 요소를 100으로 할당하는 방법과 second, third와 같이 범위를 지정하는 방법이 있습니다.
위 소스의 실행 결과는 다음과 같습니다.
Size of second: 5
Size of third: 3
vector::at
vector의 n 번째에 요소의 레퍼런스를 반환하는 함수입니다.
#include <iostream>
#include <vector>
using namespace std;
int main(int argc, char* argv[])
{
vector<int> myvector(10);
for (int i = 0; i < myvector.size(); i++)
myvector.at(i) = i;
cout << "myvector contains: ";
for (int i = 0; i < myvector.size(); i++)
cout << " " << myvector.at(i);
cout << endl;
try {
myvector.at(20) = 5;
} catch (out_of_range e) {
cout << "out of range" << endl;
}
}
위 소스와 같이 n 번째 요소의 값을 반환하거나 대입할 때 사용합니다. 유효하지 않은 요소를 참조할 경우 out_of_range 예외를 발생합니다.
위 소스의 실행 결과는 다음과 같습니다.
out of range
vector::back
vector의 마지막 요소의 레퍼런스를 반환하는 함수입니다.
#include <iostream>
#include <vector>
using namespace std;
int main(int argc, char* argv[])
{
vector<int> myvector;
myvector.push_back(10);
while (myvector.back() != 0) {
myvector.push_back(myvector.back() - 1);
}
cout << "myvector contains:";
for (unsigned int i = 0; i < myvector.size(); i++)
cout << " " << myvector[i];
cout << endl;
return 0;
}
위 소스와 같이 vector의 마지막 요소의 값을 읽어올 때 유용하게 사용할 수 있습니다. 혹은 마지막 요소의 값을 변경할 때도 사용됩니다.
위 소스의 실행 결과는 다음과 같습니다.
vector::begin
vector의 첫 번째 요소에 대한 반복자를 반환하는 함수입니다.
#include <iostream>
#include <vector>
using namespace std;
int main(int argc, char* argv[])
{
vector<int> myvector;
for (int i = 1; i <= 5; i++)
myvector.push_back(i);
vector<int>::iterator it;
cout << "myvector contains:";
for (it = myvector.begin(); it < myvector.end(); it++)
cout << " " << *it;
cout << endl;
return 0;
}
반복자를 이용하여 vector 내의 요소들을 출력하는 예제입니다.
위 소스의 실행 결과는 다음과 같습니다.
vector::capacity
vector의 각 요소들을 저장하기 위해 할당된 공간의 크기를 반환하는 함수입니다. 이 함수가 반환하는 값은 실제 요소들의 수와 같거나 클 수 있습니다.
#include <iostream>
#include <vector>
using namespace std;
int main(int argc, char* argv[])
{
vector<int> myvector(100);
for (int i = 0; i < 100; i++)
myvector.push_back(i);
cout << "size: " << (int) myvector.size() << endl;
cout << "capacity: " << (int) myvector.capacity() << endl;
cout << "max_size: " << (int) myvector.max_size() << endl;
return 0;
}
위 소스는 빈 vector를 생성한 후 push_back 함수로 100개의 요소를 만들어 size, capacity, max_size를 비교한 것입니다. size는 현재 vector에 저장된 요소들의 갯수를 반환하고, capacity는 size와 같거나 큰 값을 반환합니다. max_size는 vector에 저장할 수 있는 최대 갯수를 반환합니다.
위 소스의 실행 결과는 다음과 같습니다.
capacity: 141
max_size: 1073741823
vector::clear
vector에 저장된 요소들을 삭제하는 함수입니다. vector에 저장된 요소가 객체라면 객체의 소멸자가 먼저 호출된 후, vetctor에서 삭제 됩니다. 최종적으로 size는 0이 됩니다.
#include <iostream>
#include <vector>
using namespace std;
int main(int argc, char* argv[])
{
vector<int> myvector;
myvector.push_back(100);
myvector.push_back(200);
myvector.push_back(300);
cout << "myvector contains:";
for (int i = 0; i < myvector.size(); i++)
cout << " " << myvector[i];
cout << endl;
myvector.clear();
myvector.push_back(1101);
myvector.push_back(2202);
cout << "myvector contains:";
for (int i = 0; i < myvector.size(); i++)
cout << " " << myvector[i];
cout << endl;
return 0;
}
위 소스의 실행 결과는 다음과 같습니다.
myvector contains: 1101 2202
vector::empty
vector가 비어있는지 여부를 반환하는 함수입니다.
#include <iostream>
#include <vector>
using namespace std;
int main(int argc, char* argv[])
{
vector<int> myvector;
int sum = 0;
for (int i = 1; i <= 10; i++)
myvector.push_back(i);
while (!myvector.empty()) {
sum += myvector.back();
myvector.pop_back();
}
cout << "total: " << sum << endl;
return 0;
}
if (size == 0)을 이용하면 empty와 똑같은 결과를 얻을 수 있는데 size의 경우, 내부적으로 각 요소를 순회하므로 empty를 사용하는 것이 속도면에서 이득입니다.
위 소스의 실행 결과는 다음과 같습니다.
vector::end
vector에 저장된 마지막 요소의 다음 요소를 가리키는 반복자를 반환하는 함수입니다.
#include <iostream>
#include <vector>
using namespace std;
int main(int argc, char* argv[])
{
vector<int> myvector;
for (int i = 1; i <= 5; i++)
myvector.insert(myvector.end(), i);
cout << "myvector contains:";
vector<int>::iterator it;
for (it = myvector.begin(); it < myvector.end(); it++)
cout << " " << *it;
cout << endl;
return 0;
}
마지막 요소의 반복자가 아닌 그 다음 요소의 반복자를 반환한다는 것에 유의해야 합니다.
위 소스의 실행 결과는 다음과 같습니다.
vector::erase
vector에 저장되어 있는 요소를 삭제할 때 사용하는 함수입니다. 반복자를 인수로 받는데 하나의 요소를 삭제거나 범위를 지정해 여러개의 요소를 삭제할 수도 있습니다. 이 함수의 반환값은 삭제된 요소의 다음 요소를 가리키는 반복자입니다.
#include <iostream>
#include <vector>
using namespace std;
int main(int argc, char* argv[])
{
vector<int> myvector;
for (int i = 1; i <= 10; i++)
myvector.push_back(i);
// erase the 6
vector<int>::iterator it = myvector.erase(myvector.begin() + 5);
cout << *it << endl;
// erase the 1, 2, 3
myvector.erase(myvector.begin(), myvector.begin() + 3);
cout << "myvector contains:";
for (int i = 0; i < myvector.size(); i++)
cout << " " <<myvector[i];
cout << endl;
return 0;
}
1 ~ 10까지의 정수를 저장하는 vector을 생성한 후, 6번째에 해당하는 요소를 삭제하였습니다. 이때 erase의 반환값은 삭제된 요소의 다음 요소를 가리킨다는 것을 확인 할 수 있습니다. 범위를 지정하여 삭제를 할 경우, 두번째 인수의 요소는 삭제되지 않고 바로 앞 요소까지 삭제된다는 것을 유의해야 합니다.
위 소스의 실행 결과는 다음과 같습니다.
myvector contains: 4 5 7 8 9 10
vector::front
vector의 첫번째 요소의 레퍼런스를 반환하는 함수입니다. vector::begin과 혼돈할 수 있는데 begin은 첫번째 요소의 반복자(iterator)를 반환하는 함수입니다.
#include <iostream>
#include <vector>
using namespace std;
int main(int argc, char* argv[])
{
vector<int> myvector;
myvector.push_back(77);
myvector.push_back(16);
myvector.front() -= myvector.back();
cout << "myvector.front() is now " << myvector.front() << endl;
return 0;
}
front와 back를 이용해 첫 번째 요소에 마지막 요소를 뺀 뒤, 그 결과를 다시 첫 번째 요소에 저장하는 예제입니다.
위 소스의 실행 결과는 다음과 같습니다.
vector::get_allocator
vector 생성시 사용한 allocator 객체를 반환하는 함수입니다.
#include <iostream>
#include <vector>
using namespace std;
int main(int argc, char* argv[])
{
vector<int> myvector;
int *p;
p = myvector.get_allocator().allocate(5);
for (int i = 0; i < 5; i++)
p[i] = i;
cout << "The allocated array contains:";
for (int i = 0; i < 5; i++)
cout << " " << p[i];
cout << endl;
myvector.get_allocator().deallocate(p, 5);
return 0;
}
vector의 allocator 객체를 이용해 배열을 만들고, 이를 사용하는 예제입니다.
위 소스의 실행 결과는 다음과 같습니다.
vector::insert
vector에 새로운 요소를 삽입할 때 사용하는 함수입니다. 하나의 요소를 삽입할 수도 있고, 범위를 지정하여 여러개의 요소를 삽입 할 수도 있습니다.
#include <iostream>
#include <vector>
using namespace std;
int main(int argc, char* argv[])
{
vector<int> myvector(3, 100);
vector<int>::iterator it = myvector.begin();
it = myvector.insert(it, 200);
myvector.insert(it, 2, 300);
// "it" no longer valid, get a new one
it = myvector.begin();
vector<int> anothervector(2, 400);
myvector.insert(it + 2, anothervector.begin(), anothervector.end());
int myarray[] = {501, 502, 503};
myvector.insert(myvector.begin(), myarray, myarray + 3);
cout << "myvector contains:";
for (it = myvector.begin(); it < myvector.end(); it++)
cout << " " << *it;
cout << endl;
return 0;
}
새로운 요소를 삽입하기 위해서는 삽입 할 위치를 지정해줘야 되는데, 새로운 요소는 지정한 위치의 앞쪽에 삽입됩니다. 위 소스와 같이 "myvector.begin() + 2" 일 경우, 반복자가 가리키는 요소는 3번째 항목이고, 실제 삽입은 3번째 항목의 앞쪽에서 일어납니다.
위 소스의 실행 결과는 다음과 같습니다.
vector::max_size
vector가 저장할 수 있는 최대 요소의 갯수를 반환하는 함수입니다. 예제는 vetor::capacity를 참고하세요.
vector::operator=
일반적으로 사용하는 대입 연산자와 같은 동작을 합니다. 즉, 우변에 있는 vector를 좌변으로 대입하는 역할을 합니다. 대입 연산자는 같은 타입의 요소를 저장하고 있는 vector 끼리만 성립이 됩니다.
#include <iostream>
#include <vector>
using namespace std;
int main(int argc, char* argv[])
{
vector<int> first(3, 0);
vector<int> second(5, 0);
second = first;
first = vector<int>();
cout << "Size of first: " << int(first.size()) << endl;
cout << "Size of second: " << int(second.size()) << endl;
return 0;
}
좌변에 저장되어 있던 기존 요소들은 삭제되고 우변의 값이 복사됩니다. 위 소스가 이러한 특징을 잘 보여주는데first에는 3개의 요소를, second에는 5개의 요소를 갖는 vector를 생성했습니다. 그런 후 대입 연산자를 이용해first의 값을 second로 복사 하는데 실행 결과를 보면 5개의 요소를 갖고있던 second가 3개의 요소를 갖는 vector로 교체된 것을 알 수 있습니다.
위 소스의 실행 결과는 다음과 같습니다.
Size of second: 3
vector::operator[]
첨자에 해당하는 요소의 레퍼런스를 반환합니다. 배열처럼 첫 번째 요소는 1이 아닌 0을 참조해야 됩니다. "vector::at" 과 유사한 것을 알 수 있는데 차이점이라면 "vector::at" 은 유효하지 않은 위치를 참조할 경우 out of range 예외를 발생시킨다는 것입니다.
include <iostream>
#include <vector>
using namespace std;
int main(int argc, char* argv[])
{
vector<int> myvector(10);
vector<int>::size_type size = myvector.size();
// assign some values
for (int i = 0; i < size; i++)
myvector[i] = i;
// reverse vector using operator[]
for (int i = 0; i < size / 2; i++) {
int temp;
temp = myvector[size - 1 - i];
myvector[size - 1 - i] = myvector[i];
myvector[i] = temp;
}
cout << "myvector contains:";
for (int i = 0; i < size; i++)
cout << " " << myvector[i];
cout << endl;
return 0;
}
위 소스는 operator[] 연산자를 사용하여 0 ~ 9까지 저장된 vector의 요소를 반대로 9 ~ 0으로 저장하는 예제입니다.
위 소스의 실행 결과는 다음과 같습니다.
vector::pop_back
vector의 마지막 요소를 삭제하는 함수입니다. 더불어 마지막 요소의 반복자와 레퍼런스도 무효화 됩니다.
#include <iostream>
#include <vector>
using namespace std;
int main(int argc, char* argv[])
{
vector<int> myvector;
int sum = 0;
myvector.push_back(100);
myvector.push_back(200);
myvector.push_back(300);
while (!myvector.empty()) {
sum += myvector.back();
myvector.pop_back();
}
cout << "The elements of myvector sumed " << sum << endl;
return 0;
}
myvector 요소가 0이 될 때까지 myvector의 마지막 요소를 꺼내 sum 변수에 더하는 예제입니다.
위 소스의 실행 결과는 다음과 같습니다.
vector::push_back
vector의 마지막에 새로운 요소를 추가합니다. 새롭게 추가된 요소가 마지막 요소가 됩니다. 또한 push_back을 호출할 때마다 size가 1씩 증가하는데 만약 capacity와 size 값이 같아지면 내부적으로 저장 공간을 재할당 하게 됩니다. 이때 기존에 생성된 반복자 및 레퍼런스, 포인터들은 무효화 되니 주의 해야 합니다.
#include <iostream>
#include <vector>
using namespace std;
int main(int argc, char* argv[])
{
vector<int> myvector;
int myint;
cout << "Please enter some integers (enter 0 to end):\n";
do {
cin >> myint;
myvector.push_back(myint);
} while (myint);
cout << "myvector stores " << (int) myvector.size() << " numbers" << endl;
return 0;
}
push_back을 이용해 새로운 요소를 추가하는 예제입니다.
vector::rbegin
마지막 요소를 가리키는 reverse 반복자를 반환하는 함수입니다. reverse 반복자는 일반 반복자의 반대 방향으로 증가합니다.
#include <iostream>
#include <vector>
using namespace std;
int main(int argc, char* argv[])
{
vector<int> myvector;
for(int i = 1; i <= 5; i++)
myvector.push_back(i);
cout << "myvector contains:";
vector<int>::reverse_iterator rit;
for (rit = myvector.rbegin(); rit < myvector.rend(); ++rit)
cout << " " << *rit;
cout << endl;
return 0;
}
reverse 반복자를 이용해 마지막 요소부터 첫 번째 요소를 출력하는 예제입니다.
vector::rend
첫 번째 요소를 가리키는 reverse 반복자를 반환하는 함수입니다. reverse 반복자는 일반 반복자의 반대 방향으로 증가합니다. 예제는 vector::rbegin을 참고하세요.
vector::reserve
vactor::capacity의 값보다 더 많은 저장 공간을 확보할 때 사용하는 함수입니다. vector::insert, vector::push_back 등을 이용해 요소를 추가하다보면 vector의 size가 증가하게 되고, size가 vactor::capacity와 같아지는 경우가 발생합니다. 이때 vector는 내부적으로 저장 공간을 자동적으로 확보하는데 이런한 작업은 수행 속도에 대한 오버헤드가 될 수 있습니다. 그래서 빈번한 삽입이 일어나는 경우 automatic reallocations을 방지하기 위해 reserve로 저장 공간을 미리 확보하는 용도로 사용합니다.
vector::resize
vector의 size를 수정하는 함수입니다.
#include <iostream>
#include <vector>
using namespace std;
int main(int argc, char* argv[])
{
vector<int> myvector;
for (int i = 1; i <= 10; i++)
myvector.push_back(i);
myvector.resize(5);
myvector.resize(8, 100);
myvector.resize(12);
cout << "myvector contains:";
for (int i = 0; i < myvector.size(); i++)
cout << " " << myvecotr[i];
cout << endl;
return 0;
}
위 소스의 결과를 보면 현재 vector의 size보다 resize가 작을 경우, 나머지 요소들은 삭제 되는 것을 알 수 있습니다. 만약 현재 vector의 size보다 resize가 큰 경우는 추가된 요소가 0 또는 resize 함수의 두 번째 인수로 초기화 되는 것을 알 수 있습니다. 또한 요소가 추가될 때 내부적으로 저장 공간의 재할당이 발생합니다.
vector::size
vector에 저장되어 있는 요소의 갯수를 반환하는 함수입니다.
#include <iostream>
#include <vector>
using namespace std;
int main(int argc, char* argv[])
{
vector<int> myints;
cout << "0. size: " << (int) myints.size() << endl;
for (int i = 0; i < 10; i++) myints.push_back(i);
cout << "1. size: " << (int) myints.size() << endl;
myints.insert(myints.end(), 10, 100);
cout << "2. size: " << (int) myints.size() << endl;
myints.pop_back();
cout << "3. size: " << (int) myints.size() << endl;
return 0;
}
위 소스의 실행 결과는 다음과 같습니다.
1. size: 10
2. size: 20
3. size: 19
vector::swap
두 vector의 요소를 교환하는 함수입니다. 서로 같은 타입의 요소를 갖는 vector에서만 유효합니다.
#include <iostream>
#include <vector>
using namespace std;
int main(int argc, char* argv[])
{
vector<int> first(3, 100); // three ints with a value of 100
vector<int> second(5, 200); // five ints with a value of 200
first.swap(second);
cout << "first contains:";
for (int i = 0; i < first.size(); i++)
cout << " " << first[i];
cout << endl;
cout << "second contains:";
for (int i = 0; i < second.size(); i++)
cout << " " << second[i];
cout << endl;
return 0;
}
요소 100을 세개 갖는 vector first와 200을 다섯개 갖는 vector second를 생성한 뒤, swap을 이용하여 두 vector의 요소를 교환하는 예제입니다.
위 소스의 실행 결과는 다음과 같습니다.
second contains: 100 100 100
'차근차근 > C' 카테고리의 다른 글
std::map 사용: 차순정렬하여 상위 top ranker 만 사용하고자 할 때... (0) | 2014.08.26 |
---|---|
greater<int> (0) | 2014.08.21 |
[C++] map에서 find 를 이용해서 없는 항목 찾기 (0) | 2014.08.20 |
About STL : C++ STL 프로그래밍(6)-해시 맵(Hash Map) (0) | 2014.08.20 |
Map 클래스에 벡터를 key 나 value 로 하고 싶으면 어떻게 해야 하나요? (0) | 2014.08.19 |