std::vector<T>
std::vector<T> 는 vector 헤더파일에 작성되어있다.
이 std::vector를 활용하게 되면 유동적인 배열을 편안하게 활용할 수 있다.
std::vector<T>는 윌가 일반적으로 배열을 사용하듯 사용할 수 있으며 std::vector는 iterator(순회자)를 통해
각각의 원소를 순회할 수 있고 이 순회자를 이용해 algorithm에 작성되어 있는 sort(..)함수를 이용해 값을 정렬 할 수 있다.
선언은 이렇게 한다.
코드 예시
#define _CRT_SECURE_NO_WARNINGS
#include <cstdio>
#include <vector>
int main() {
std::vector<int> myvec;
return 0;
}
전체적으로는 이렇게 사용한다.
#define _CRT_SECURE_NO_WARNINGS
#include <cstdio>
#include <vector>
int main() {
std::vector<int> myvec;
myvec.push_back(100);
myvec.push_back(200);
myvec.push_back(300);
for (int i = 0; i < 3; i++) {
printf("%d\n", myvec[i]);
}
return 0;
}
for문을 이렇게 말고, myvec.size()를 이용해 백터에 몇개의 변수가 들어가 있는지 확인이 가능하다.
for (int i = 0; i < myvec.size(); i++) {
printf("%d\n", myvec[i]);
}
이렇게 바꿔서 하면 사용이 가능하다.
기존에 배열처럼 기본 값을 설정해 줄 수 있다.
std::vector<int> myvec = { 10, 20, 30 };
이렇게 넣고 출력하면 10 20 30 다음에 100 200 300이 출력이 된다.
또 3번째 숫자를 바꾸고 싶다면 배열처럼
myvec[2] = 55;
를 하면 된다.
vector는 정말정말 편리하지만, 성능 저하가 생긴다. 그래서 일반 배열도 사용하자.
#include <algorithm>
#include <algorithm>을 사용해 백터 안에 있는 내용이 정렬이 가능하다.
std::sort(변수명.begin(), 변수명.end());
만드는건 이렇게 만든다.
코드 예시
#define _CRT_SECURE_NO_WARNINGS
#include <cstdio>
#include <vector>
#include <algorithm>
int main() {
std::vector<int> myvec = { 60, 9, 21 };
myvec.push_back(16);
myvec.push_back(39);
myvec.push_back(50);
std::sort(myvec.begin(), myvec.end());
for (int i = 0; i < myvec.size(); i++) {
printf("%d\n", myvec[i]);
}
return 0;
}
myvec.begin, mybec.end 이 2개는 순회자라고 한다.
순회자(iterator)
순회자는 기본 자료구조들이 갖고있는 원소 탐색 객체이다.
이 탐색 객체를 이용하면 원소들을 차례대로 가져올 수 있고, 물론 이 순회자를 이용해 for 루프를 돌릴 수 도 있다.
순회자의 ㄱ밧을 가져올 때에는 포인터의 값을 가져오는것 처럼*(애스터리스크)연산자를 활용한다.
for(auto it = v.begin(); it != v.end(); it++{
...
}
사용은 이렇게 한다
코드 예시
#define _CRT_SECURE_NO_WARNINGS
#include <cstdio>
#include <vector>
#include <algorithm>
int main() {
std::vector<int> myvec = { 60, 9, 21 };
myvec.push_back(16);
myvec.push_back(39);
myvec.push_back(50);
std::sort(myvec.begin(), myvec.end());
for (std::vector<int>::const_iterator it = myvec.begin(); it != myvec.end(); it++) {
printf("%d ", *it);
}
return 0;
}
상당히 빡시게 적었다. 물론 이걸 안다고 프로그래밍 능력이 오르는건 아니다.
상당히 빡세서 auto 라는 키워드를 사용한다
auto
auto 키워드는 컴파일러가 추론 가능한 데이터 타입을 자동으로 지정해줄 수 있다.
auto를 이용해 굉장히 긴 클래스명이나 데이터타입을 짧게 줄일 수 있어 많이 사용된다.
for (auto it = myvec.begin(); it != myvec.end(); it++) {
printf("%d ", *it);
}
이렇게 사용하면 된다.
다음 알아볼 것은 map이다.
std::map(K,V)
std::map은 map 헤더파일에 작성되어 있다.
std::map은 배열과 비슷하지만 좀 더 확장성이 있는 배열로 키와 그에 맞는 값 쌍을 저장할 수 있다.
키는 배열처럼 연속적이지 않아도 되며, std::string 등 꼭 interger가 아니더라도 키갑슬 가질 수 있다는 것이 가장 큰 장점이다.
map은 원소 삽입과 동시에 자동으로 값이 정렬되는 특징이 있다.
map은 문자열도 가능하다.
이렇게 만든다.
코드 예시
#define _CRT_SECURE_NO_WARNINGS
#include <cstdio>
#include <vector>
#include <algorithm>
#include <map>
#include <string>
int main() {
std::map<std::string, std::string> capitals;
return 0;
}
std::map<std::string, std::string> 변수명; 으로 사용하면 된다.
가장 많이 사용하는 것들을 알아보자.
count
변수명.count이다. 해당 키에 값이 존재하는지 안하는지 리턴해준다.
코드 예시
#define _CRT_SECURE_NO_WARNINGS
#include <cstdio>
#include <vector>
#include <algorithm>
#include <map>
#include <string>
int main() {
std::map<std::string, std::string> capitals;
capitals["korea"] = "seoul";
capitals["usa"] = "washington";
capitals.count("korea");
return 0;
}
출력 예시를 보자.
코드 예시
#define _CRT_SECURE_NO_WARNINGS
#include <cstdio>
#include <vector>
#include <algorithm>
#include <map>
#include <string>
int main() {
std::map<std::string, std::string> capitals;
capitals["korea"] = "seoul";
capitals["usa"] = "washington";
capitals.count("korea");
if (capitals.count("korea") == 1) {
printf("korea가 존재합니다");
}
else {
printf("korea가 존재하지 않는다");
}
return 0;
}
이러면 korea가 존재합니다 라고 나온다.
capitals["korea"\ = "seoul";
이거를
capitals["china"] = "beijing"; 으로 바꾸면 else 가 나온다.
다음으로 많이 사용하는 것은
erase
변수명.erase()이다.
이는 키 값을 넣어주면 키 값을 지워주는 역할이다.
코드 예시
#define _CRT_SECURE_NO_WARNINGS
#include <cstdio>
#include <vector>
#include <algorithm>
#include <map>
#include <string>
int main() {
std::map<std::string, std::string> capitals;
capitals["china"] = "beijing";
capitals["korea"] = "seoul";
capitals["usa"] = "washington";
capitals.erase("korea");
if (capitals.count("korea") == 1) {
printf("korea가 존재합니다");
}
else {
printf("korea가 존재하지 않는다");
}
return 0;
}
이렇게 사용하면 korea가 존재하지 않는다가 출력된다.
std::map의 순회
std::map은 순회를 하기 위해 일반적인 for 루프를 활용할 수 없고, iterator(순회자)를 활용한 순회만 가능하다.
for(auto it = m.begin(); it !=m.end(); it++){
it->first; // map의 각각 키
it->second; // map의 각각 값
}
코드 예시
#define _CRT_SECURE_NO_WARNINGS
#include <cstdio>
#include <vector>
#include <algorithm>
#include <map>
#include <string>
int main() {
std::map<std::string, std::string> capitals;
capitals["china"] = "beijing";
capitals["korea"] = "seoul";
capitals["usa"] = "washington";
capitals.erase("korea");
for (auto it = capitals.begin(); it != capitals.end(); it++) {
printf("first: %s\n", it->first.c_str());
printf("second: %s\n", it->second.c_str());
}
return 0;
}
실행하면 나라 -> 수도 순으로 나온다.
erase에 있는 korea를 지우면 korea도 나온다.
아마 실행하면 순서가 바뀌어 있을것이다.
map의 함수는 tree 라는 자료구조를 알아서 사용하게 된다.
간단하게 1~10, a~z순으로 정렬한다고 하면 된다.
오랜만에 연습프로그래밍이 있다.
연습
std::map을 이용해서 회원가입 프로그램을 만들어보자.
std::map의
key로 사용자 id
value로 사용자 비밀번호를 저장하고
동일한 사용자의 가입을 막아야 한다.
특정 방법으로 사용자의 리스트를 출력할 수 있어야 한다.
출력하는 방법은 자유이다.
코드 예시
#define _CRT_SECURE_NO_WARNINGS
#include <cstdio>
#include <vector>
#include <algorithm>
#include <map>
#include <string>
int getinteger(const char* prompt) {
printf("%s", prompt);
int input;
fseek(stdin, 0, SEEK_END);
scanf("%d", &input);
return input;
}
std::string getstring(const char* prompt) {
printf(prompt);
char str[100];
fseek(stdin, 0, SEEK_END);
scanf("%99[^\n]s", str);
return str;
}
int main() {
std::map<std::string, std::string> member;
for (;;) {
printf("1. 회원가입\n");
printf("2. 회원출력\n");
printf("3. 프로그램 종료\n");
int menu = getinteger("번호를 입력하세요:");
if (menu == 1) {
std::string id = getstring("아이디를 입력해주세요:");
std::string pwd = getstring("비밀번호를 입력해주세요:");
if(member.count(id)){
printf("중복된 아이디 입니다\n");
}
else {
member[id] = pwd;
printf("회원가입이 완료되었습니다\n");
}
member[id] = pwd;
}
else if (menu == 2) {
for (auto it = member.begin(); it != member.end(); it++) {
printf("%s\n", it->first.c_str());
}
}
else if (menu == 3) {
printf("프로그램을 종료합니다");
break;
}
}
return 0;
}
'C언어 공부' 카테고리의 다른 글
C++ 심화 - 8 파일 입출력2 (0) | 2025.03.22 |
---|---|
C++ 심화 - 7 파일 입출력 (0) | 2025.03.21 |
C++ 심화 - 5 STL 핵심 / Generic 이라고 불릴 수 있는 개념 (0) | 2025.03.20 |
C++ 언어 심화 - 4 const / static / extern (0) | 2025.03.20 |
C++ 심화 - 3 문자열과 네임스페이스 그리고 레퍼런스 타입 (0) | 2025.03.20 |