본문 바로가기

카테고리 없음

2024- 12 - 24 STL 공부

STL 은 c++ 에서 자체적으로 제공하는 표준 라이브 러리

개발 시 유용하게 사용되는 컨테이너, 알고리즘이 구현되어 있기 때문에 ,

헤더 파일을 추가하고 사용 하기만 하면 됩니다.

 

컨테이너

 

데이터를 담는 자료 구조입니다.

데이터를 담는 방식이나 제공하는 방식에 따라 여러가지 컨테이너가 있습니다.

 

  • 모든 컨테이너는 템플릿으로 구현 되어 있어 타입에 상관없이 사용 가능합니다.
  • 메모리 관리를 내부적으로 합니다 사용시 메모리 관리를 고려하지 않아도 됩니다.
  • 컨테이너는 반복자를 가지고 있습니다. 컨테이너 내부 세부적인 구현사항을 알지못해도
    모든 컨테이너를 동일한 문법으로 접근할 수 있습니다.

 

벡터(vector)

 

벡터는 배열과 유사한 컨테이너 입니다.

  • 타입에 종속되지않는 템플릿 클래스로 구현됩니다.
  • 원소 개수에 따라 내부 배열의 크기가 자동 관리됩니다. (늘어날수 있다는 뜻)
  • 임의 접근이 가능합니다. (배열 처럼 인덱스로 특정 위치 접근가능)
  • 추가/ 삭제 가능 ( 맨 뒤에 추가 삭제 하는 것이 좋음)

 

#include <vector>
#include <iostream>
using namespace std;

// 1. 기본 생성 및 초기화 없이 정의
vector<int> vec1;

// 2. 특정 크기와 초기값으로 벡터 정의
vector<int> vec2(5, 10); // 크기 5, 모든 원소가 10으로 초기화

// 3. 리스트 초기화로 벡터 정의
vector<int> vec3 = {1, 2, 3, 4, 5};

// 4. 다른 벡터를 기반으로 복사 초기화
vector<int> vec4(vec3); // vec3의 복사본 생성

// 주의!! 
//vector<int> vec4 = vec3 하면 대입이됨!!

// 5. 2차원 벡터 초기화 // 배열안에 배열 , 벡터안에 벡터 등 
// 7 7 7 7
// 7 7 7 7
// 7 7 7 7

vector<vector<int>> vec2D(3, vector<int>(4, 7)); // 3x4 행렬, 모든 원소가 7로 초기화

// 벡터 끝에 원소 추가
vector<int> vec; // 생성 
vec.push_back(10); // 뒤에 원소 추가
vec.push_back(20);
vec.push_back(30);

cout << "벡터 크기 : " << vec.size() << endl;// 3

 vec.pop_back();  // 마지막 요소(30) 제거
 
cout << "벡터 크기 : " << vec.size() << endl;// 2

// 두 번째 요소 제거 (index 1)
vec.erase(vec.begin() + 1);

vec.push_back(20);
vec.push_back(30);

// 2~4 번째 요소 제거 (index 0~2)
vec.erase(vec.begin(), vec.begin() + 2);

 

 

기본적인 사용 느낌은

크기 조절이 가능한 배열 이라는 느낌입니다.

 

push_back 
벡터의 맨 끝에 원소를 추가하는 메서
pop_back
벡터의 맨 끝에 원소를 제거하는 메서드
size
현재 벡터의 크기를 확인할 때 사용
erase
특정위치의 원소를 제거하는 함수

 

 

 

벡터는 해당 위치(인덱스 번호)의 값을 찾아줬다면

맵은 키를 사용하고 값을 줍니다.

 

이렇게 서울이라는 키에는 02이라는 값이

경기도라는 키에는 031이라는 값이 들어가게됩니다.

 

#include <iostream>
#include <map>
using namespace std;


int main() {

    // 1. 기본적인 map 선언 (키: int, 값: string)
    map<int, string> Number;

    // 2. map 선언과 동시에 초기화 (키: string, 값: int)
    map<int, string> idToName = {
        {"서울", 02},
        {"경기도", 031},
        
    };
    
    // 3. map 선언 (키: int, 값: vector<int>)
    map<int, vector<int>> studentMarks;

    // 4. map 선언 (키: pair<int, int>, 값: string)
    map<pair<int, int>, string> coordinateToName;

    return 0;
}

선언 하는 방식들입니다.

 

 

복사 방법

#include <iostream>
#include <map>

using namespace std;

int main() {
    
    map<int, string> fruit;
    fruit[1] = "Apple";
    fruit[2] = "Banana";
    fruit[3] = "Cherry";

    // 1. 복사 생성자 사용
    map<int, string> copydMap1(fruit);

    // 2. 대입 연산자 사용
    map<int, string> copydMap2;
    copiedMap2 = fruit;

    // 3. insert 사용
    
    //키값은 중복이 안되지만 값은 상관이없습니다.
    //키에 값이 들어있기때문 예 ㅁ [ ㅇ ( ㅁ)];
    //make_pair를 통해 키- 값 쌍을 만들어주고 이를 instrt를 만들어서 추가합니다.
    copydMap2.insert(make_pair(4, " Apple")
    
    map<int, string> copyMap3;
    copiedMap3.insert(fruit.begin(), fruit.end());


	
    
    return 0;
}


 insert 

키를 삽입할 수 있습니다.

 

 

 

 

 find 함수를 통해 특정 키 값 존재여부를 확인할 수 있습니다.

map<int, string> myMap;
myMap[1] = "Apple";

 // 요소 검색
map<int, string>::iterator it = myMap.find(1);

 

 

myMap.size();

키 - 값 쌍의 개수 확인

 

myMap.clear();

모든 요소 삭제 

 

 


STL

 

컨테이너 에서 할 수 있는 대부분의 동작들을 이미 알고리즘으로 제공하고 있습니다.

 

 

 

sort

 

컨테이너 내부의 데이터를 정렬해주는 함수입니다.

 

 

정렬기준을 정해주지 않을 경우 오름차순으로 정렬되며, 사용자가 정렬기준을 정의해서 사용할 수 있습니다.

 

 

bool compare(int a, int b) {
    return a > b; // 내림차순
}



//배열 정렬정렬
int arr[] = { 5, 2, 9, 1, 5, 6 };
int size = sizeof(arr) / sizeof(arr[0]);
// 오름차순 정렬
sort(arr, arr + size);
// 내림차순 정렬
sort(arr, arr + size, compare);

//벡터정렬
vector<int> asdf = { 1,2,3 };
// 오름차순 정렬
sort(asdf.begin(), asdf.end());
// 내림차순 정렬
sort(asdf.begin(), asdf.end(), compare);

 

 

find

 

컨터이너 내부에서 특정 원소를 찾아주는 함수

해당 원소가 위치하는 특정 원소의 위치를 알려주고

찾지 못한 경우 컨테이너의 맨 마지막 다음 위치를 반환

 

int arr[] = {1, 2, 3, 4, 5};

vector<int> vec = {10, 20, 30, 40, 50};

 

//auto : 특정 타입을 찾아서 적용  예 ) int 면 int ,float 이면 float

 

 

// 특정 값 30을

찾음 auto it = find(vec.begin(), vec.end(), 30);

// 특정 값 3을 찾음

auto it = find(arr, arr + size, 3);

 

 

순방향 반복자

vector<int> numbers = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
    
// it 이 end()가 아닐경우 반복
for (auto it = numbers.begin(); it != numbers.end(); ++it) {

        cout << *it << " ";

}

 

역방향 반복자

vector<int> numbers = {10, 15, 20, 25, 30};

//맨 마지막 위치는 rbegin(), 맨 처음 이전위치는 rend()
//begin 과 end로 확인 해볼 것
for (auto it = numbers.rbegin(); it != numbers.rend(); ++it) {

        cout << *it << " ";
}

 

 

자주 사용하는 걸로 익숙해지는게 좋을 것 같습니다.

그리고 컨테이너가 이더있을 것이고 왜 배열을 사용하고 왜 벡터를 사용하는 지

보통 나누는 걸 보면 속도 , 데이터 용량 등 으로 나뉠 꺼라 예상하고 있습니다.