차근차근/C

[C++] vector

예쁜꽃이피었으면 2014. 8. 20. 13:26

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 배열의 시작 주소와 마지막 원소의 다음 주소를 이용하여 생성하고 있습니다. 

위 소스의 실행 결과는 다음과 같습니다. 

The contents of fifth are: 16 2 77 29


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으로 할당하는 방법과 secondthird와 같이 범위를 지정하는 방법이 있습니다.

위 소스의 실행 결과는 다음과 같습니다. 

Size of first: 7
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 예외를 발생합니다. 

위 소스의 실행 결과는 다음과 같습니다. 

myvector contains: 0 1 2 3 4 5 6 7 8 9
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의 마지막 요소의 값을 읽어올 때 유용하게 사용할 수 있습니다. 혹은 마지막 요소의 값을 변경할 때도 사용됩니다. 

위 소스의 실행 결과는 다음과 같습니다. 

myvector contains: 10 9 8 7 6 5 4 3 2 1 0


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 내의 요소들을 출력하는 예제입니다. 

위 소스의 실행 결과는 다음과 같습니다. 

 myvector contains: 1 2 3 4 5


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에 저장할 수 있는 최대 갯수를 반환합니다.

위 소스의 실행 결과는 다음과 같습니다.

size: 100
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: 100 200 300
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를 사용하는 것이 속도면에서 이득입니다. 

위 소스의 실행 결과는 다음과 같습니다.

total: 55


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;
}

 
마지막 요소의 반복자가 아닌 그 다음 요소의 반복자를 반환한다는 것에 유의해야 합니다. 

위 소스의 실행 결과는 다음과 같습니다.

myvector contains: 1 2 3 4 5


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의 반환값은 삭제된 요소의 다음 요소를 가리킨다는 것을 확인 할 수 있습니다. 범위를 지정하여 삭제를 할 경우, 두번째 인수의 요소는 삭제되지 않고 바로 앞 요소까지 삭제된다는 것을 유의해야 합니다. 

위 소스의 실행 결과는 다음과 같습니다.

7
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를 이용해 첫 번째 요소에 마지막 요소를 뺀 뒤, 그 결과를 다시 첫 번째 요소에 저장하는 예제입니다.

위 소스의 실행 결과는 다음과 같습니다.

myvector.front() is now 61


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 객체를 이용해 배열을 만들고, 이를 사용하는 예제입니다.

위 소스의 실행 결과는 다음과 같습니다.

The allocated array contains: 0 1 2 3 4


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번째 항목의 앞쪽에서 일어납니다.

위 소스의 실행 결과는 다음과 같습니다.

myvector contains: 501 502 503 300 300 400 400 200 100 100 100


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 first: 0
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으로 저장하는 예제입니다. 

위 소스의 실행 결과는 다음과 같습니다.

myvector contains: 9 8 7 6 5 4 3 2 1 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 변수에 더하는 예제입니다. 

위 소스의 실행 결과는 다음과 같습니다.

The elements of myvector summed 600


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 함수의 두 번째 인수로 초기화 되는 것을 알 수 있습니다. 또한 요소가 추가될 때 내부적으로 저장 공간의 재할당이 발생합니다. 

myvector contains: 1 2 3 4 5 100 100 100 0 0 0 0


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;
}

 

위 소스의 실행 결과는 다음과 같습니다.

0. size: 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의 요소를 교환하는 예제입니다. 

위 소스의 실행 결과는 다음과 같습니다.

first contains: 200 200 200 200 200 
second contains: 100 100 100


반응형