std::sort()
CPP 표준 라이브러리 <algorithm>에 정의되어 있는 함수.
기본적으로 오름차순이며 내림차순으로 지정할 수도 있다.
▼ 사용법
sort(v.begin(), v.end());
sort(v.begin(), v.end(), greater<int>());
sort(v.begin(), v.end(), compare());
▼ 예시 코드
#include <cstdio>
#include <cstdlib>
#include <algorithm>
void Print(int* arr)
{
printf("arr[] : ");
for (int i = 0; i < 10; i++)
printf("%d ", arr[i]);
printf("\n");
}
int main()
{
int arr[10] = { 3,4,2,4,5,1,2,3,5,0 };
Print(arr);
std::sort(arr, arr + 10);
Print(arr);
system("pause");
return (0);
}
std::vector
CPP 표준 라이브러리 <vector>에 정의되어 있는 기능이다.
배열에 비해 속도는 떨어지지만 메모리를 효율적으로 관리할 수 있는 장점이 있다.
링크드 리스트와 달리 vector는 연속적으로 메모리 블록을 사용한다.
원소가 추가되거나 삽입될 때 메모리 재할당이 발생하면서 메모리 부하가 생기는 단점도 존재한다.
▼ 예시 코드
#include <cstdio>
#include <cstdlib>
#include <ctime>
#include <vector>
#include <algorithm>
void Print(std::vector<int>& v)
{
printf("vector : ");
for (int i = 0; i < v.size(); i++)
printf("%d ", v[i]);
printf("\n");
}
int main()
{
srand((int)time(NULL));
std::vector<int> iv;
int max = 10;
for (int i = 0; i < max; i++)
{
iv.push_back(rand() % 10);
}
Print(iv);
std::sort(iv.begin(), iv.end(), std::greater<int>());
Print(iv);
system("pause");
return (0);
}
사용해보면 알겠지만 아주 편리하다.
그렇다고 언제나 배열 대신 vector를 사용하는 것이 좋은 것은 아니다.
같은 표준 라이브러리인 <array>가 정적 배열을 담당하고 <vector>는 동적 배열을 담당한다.
둘의 차이는 가변길이 여부일 뿐이라서 사용법 역시 크게 차이 나지 않는다.
<array>는 정적인 크기를 가진만큼 게임에서는 행렬 연산에 많이 사용된다.
편리성은 그대로인데다 vector의 단점인 메모리 부하가 발생하지 않는다.
▼ 응용 프로그램
#include <cstdio>
#include <cstdlib>
#include <ctime>
#include <vector>
#include <algorithm>
#include <windows.h>
void Print(std::vector<int>& v)
{
for (unsigned int i = 0; i < v.size(); i++)
printf("%d ", v[i]);
printf("\n");
}
int main()
{
HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
CONSOLE_SCREEN_BUFFER_INFO consoleInfo;
WORD saved_attributes;
GetConsoleScreenBufferInfo(hConsole, &consoleInfo);
saved_attributes = consoleInfo.wAttributes;
srand((int)time(NULL));
int max = 10;
std::vector<int> iv1;
for (int i = 0; i < max; i++)
{
iv1.push_back(rand() % 10);
}
printf("> VECTOR 1[10]\n");
printf("vector : ");
SetConsoleTextAttribute(hConsole, FOREGROUND_BLUE);
Print(iv1);
SetConsoleTextAttribute(hConsole, saved_attributes);
std::sort(iv1.begin(), iv1.end(), std::greater<int>());
printf("vector : ");
SetConsoleTextAttribute(hConsole, FOREGROUND_BLUE);
Print(iv1);
SetConsoleTextAttribute(hConsole, saved_attributes);
printf("\n");
std::vector<int> iv2;
max = rand() % 10 + 1;
for (int i = 0; i < max; i++)
{
iv2.push_back(rand() % 10);
}
printf("> VECTOR 2[%d]\n", max);
printf("vector : ");
SetConsoleTextAttribute(hConsole, FOREGROUND_RED);
Print(iv2);
SetConsoleTextAttribute(hConsole, saved_attributes);
std::sort(iv2.begin(), iv2.end());
printf("vector : ");
SetConsoleTextAttribute(hConsole, FOREGROUND_RED);
Print(iv2);
SetConsoleTextAttribute(hConsole, saved_attributes);
printf("\n");
printf("> VECTOR CONCATENATED[%d]\n", 10 + max);
iv1.insert(iv1.end(),iv2.begin(), iv2.end());
printf("vector : ");
SetConsoleTextAttribute(hConsole, FOREGROUND_BLUE);
for (unsigned int i = 0; i < iv1.size() - max; i++)
printf("%d ", iv1[i]);
SetConsoleTextAttribute(hConsole, saved_attributes);
SetConsoleTextAttribute(hConsole, FOREGROUND_RED);
for (unsigned int i = iv1.size() - max; i < iv1.size(); i++)
printf("%d ", iv1[i]);
printf("\n");
SetConsoleTextAttribute(hConsole, saved_attributes);
system("pause");
return (0);
}
단순히 Vector를 하나 더 생성해서 이전 Vector에 추가해주는 프로그램이다.
구분이 잘되도록 <windows.h> 라이브러리를 사용해서 부분적으로 글자색을 변경했다.
erase()
CPP 표준 라이브러리 <algorithm>에 정의된 함수다.
특정 위치의 인자를 삭제하거나 특정 범위의 인자들을 삭제한다.
unique()
CPP 표준 라이브러리 <algorithm>에 정의된 함수다.
중복되지 않는 원소들을 앞에서부터 채워나가는 함수로 중복값의 첫번째 위치 주소값을 반환한다.
단, sort() 가 완료되어야 정상적으로 작동한다.
erase()와 함께 이용해서 중복 제거할 때 많이 응용된다.
▼ 예시 코드
#include <cstdio>
#include <cstdlib>
#include <ctime>
#include <string>
#include <vector>
#include <algorithm>
void Print(std::vector<std::string>& v)
{
for (unsigned int i = 0; i < v.size(); i++)
printf("%s ", v[i].c_str());
printf("\n");
}
std::vector<std::string> sv;
int main()
{
srand((int)time(NULL));
int max = rand() % 5 + 1;
for (int i = 0; i < 5 + max; i++)
{
char c[2] = { 65 + (rand() % 5), 0 };
sv.push_back(c);
}
printf("> VECTOR ORIGIN\n");
Print(sv);
printf("\n");
printf("> VECTOR SORTED\n");
std::sort(sv.begin(), sv.end());
Print(sv);
printf("\n");
printf("> VECTOR UNIQUED\n");
auto buffer = std::unique(sv.begin(), sv.end());
Print(sv);
printf("\n");
printf("> VECTOR ERASED\n");
sv.erase(buffer, sv.end());
Print(sv);
printf("\n");
system("pause");
return (0);
}
응용 프로그램(로또 생성기)
▼ 전체 코드
#include <cstdio>
#include <cstdlib>
#include <ctime>
#include <vector>
#include <algorithm>
void Print(std::vector<int>& v)
{
for (unsigned int i = 0; i < v.size(); i++)
printf("%d ", v[i]);
printf("\n");
}
int main()
{
srand((int)time(NULL));
std::vector<int> iv;
for (; iv.size() <= 6;)
{
int number = rand() % 45 + 1;
iv.push_back(number);
auto buffer = std::unique(iv.begin(), iv.end());
iv.erase(buffer, iv.end());
}
printf("> ROTTO NUMBER : ");
Print(iv);
system("pause");
return (0);
}
단순히 겹치지 않는 숫자 6개를 생성하는 간단한 프로그램이다.
특이점으로 for문을 사용해서 무한 순환문을 돌고 있는데
그냥 for문을 이렇게도 쓸 수 있구나란 느낌으로 연습을 위해 사용한 것일 뿐이다.
find
CPP 표준 라이브러리 <algorithm>에 정의되어 있다.
데이터 중에 해당하는 값이 있는지 없는지 찾아서 주소값을 반환한다.
만약 찾는 값이 없다면 마지막 주소값을 반환한다.
▼ 사용 예시
std::find(v.begin(), v.end(), 3);
max_element / min_element
CPP 표준 라이브러리 <algorithm>에 정의되어 있다.
가장 크거나 작은 원소의 주소값을 반환한다.
▼ 사용 예시
printf("MAX : %d\n", *std::max_element(v.begin(), v.end()));
주소값을 반환하기 때문에 경우에 따라 Asterisk(*)를 붙여줘야 한다.
reverse
CPP 표준 라이브러리 <algorithm>에 정의되어 있다.
이름 그대로 원소들의 순서를 뒤집어준다.
▼ 사용 예시
std::reverse(v.begin(), v.end());
prev_permutation / next_permutation
CPP 표준 라이브러리 <algorithm>에 정의되어 있다.
오름차순 혹은 내림차순 순열을 구한다.
#include <cstdio>
#include <cstdlib>
#include <vector>
#include <algorithm>
void Print(std::vector<int>& v)
{
for (unsigned int i = 0; i < v.size(); i++)
printf("%d ", v[i]);
printf("\n");
}
int main()
{
std::vector<int> iv;
std::vector<int> iv2 = {1,2,3,4};
Print(iv2);
while (std::next_permutation(iv2.begin(), iv2.end()))
{
Print(iv2);
}
system("pause");
return (0);
}
순열은 말 그대로 순서를 나열해놓은 건데 배치 될 수 있는 경우의 수를 말한다.
예상컨데 카드 게임에서 덱의 카드를 무작위로 배열할 때 사용할 수 있지 않을까?
bitset
CPP 표준 라이브러리 <bitset>은 2진법을 이용한 문제에 유용하게 사용할 수 있다.
이걸 알았다면 비트 연산자 공부할 때 정말 편했을텐데..!
accumulate
CPP 표준 라이브러리 <numeric> 에 정의되어 있다.
배열의 모든 합을 구해주는 함수지만 실제로 사용하는 빈도 수는 매우 적다.
배열의 합이 현재 변수형의 최대값을 넘어가면 자동으로 변수형을 변경해주는 편의 기능이 추가되어있다.
Sleep
C 표준 라이브러리 <cstdlib> 에 정의되어 있다.
비주얼 스튜디오 2019에서는 <Windows.h>에 내장되어있는 Sleep()을 사용해야한다.
▼ 밀리초 단위로 작동한다.
Sleep(1000);
'<ALGORITHM> > NOTE' 카테고리의 다른 글
20210203(수) (0) | 2021.02.03 |
---|---|
20210201(월) (0) | 2021.02.01 |
20210121(목) (0) | 2021.01.21 |
20210120(수) (0) | 2021.01.20 |
20210119(화) (0) | 2021.01.19 |
댓글