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 = {10, 20, 30}; // 초깃값 설정 가능 myvec.push_back(100); myvec.push_back(200); myvec.push_back(300); //myvec에는 10, 20, 30, 100, 200, 300이 들어가있다. myvec[2] = 55; // 2번째 배열 값 바꾸기 for(int i = 0; i < myvec.size(); i++) { // myvec.size()로 원소가 몇 개 들어가는지 알 수 있다 printf("%d ", myvec[i]); // std::vector라고 하는 자료구조 stl클래스가 []을 오버로딩 했기때문에 가능 } return 0; } |
순회자 (interator)
순회자는 기본 자료구조들이 갖고있는 원소 탐색 객체이다.
이 탐색 객체를 이용하면 원소들을 차례대로 가져올 수 있고
물론 이 순회자를 이용해 for 루프를 돌 수도 있다.
순회자의 값을 가져올 때에는 포인터의 값을 가져오는 것 처럼
* (에스터리스크) 연산자를 활용한다.
for ( auto it = v.begin(); it != v.end(); it++) { ... }
순회자는 이 순회자가 하나씩 하나씩 다음 원소를 탐색하게 해주는 개체
즉, for loop 돌 듯이 돌게 해주는 개체
#define _CRT_SECURE_NO_WARNINGS #include <cstdio> #include <vector> #include <algorithm> int main() { std::vector<int> myvec = {40, 1, 5}; myvec.push_back(4); myvec.push_back(10); myvec.push_back(7); // 정렬 std::sort(myvec.begin(), myvec.end()); // 순회자 (iterator) for(std::vector<int>::const_iterator it = myvec.begin(); it!= myvec.end(); it++) { printf(" %d ", *it); } return 0; } |
auto
auto 키워드는 컴파일러가 추론 가능한 데이터 타입을
자동으로 지정해줄 수 있다.
auto를 이용해 굉장히 긴 클래스명이나 데이터타입을 짧게 줄일 수 있어 많이 사용된다.
auto 다음 쓰는 타입이 오른쪽에 assign되는 초기값에 의해서 자동으로 타입 결정
myvec.begin()이라 했을 때 리턴되는 값이 std::vector<int>에 const iterator 타입
이런식으로 순회가 가능하다.
#define _CRT_SECURE_NO_WARNINGS #include <cstdio> #include <vector> #include <algorithm> int main() { std::vector<int> myvec = {40, 1, 5}; myvec.push_back(4); myvec.push_back(10); myvec.push_back(7); // 순회자 (iterator) for(auto it = myvec.begin(); it != myvec.end(); it++) { printf(" %d ", *it); } return 0; } |
std::map< K, V >
: string을 인덱스로 갖는 배열
std::map은 map 헤더파일에 작성되어 있다.
std::map은 배열과 비슷하지만 좀 더 확장성이 있는 배열로
키와 그에 맞는 값 쌍을 저장할 수 있다
키는 배열처럼 연속적이지 않아도 되며 std::string 등
꼭 integer 가 아니더라도 키값을 가질 수 있다는 것이 가장 큰 장점이다.
map은 원소 삽입과 동시에 자동으로 값이 정렬되는 특징이 있다.
#define _CRT_SECURE_NO_WARNINGS #include <cstdio> #include <vector> #include <map> #include <string> #include <algorithm> int main() { std::map<std::string, std::string> capitals; // vector, map 둘 다 생성자 호출 필요없음 capitals["korea"] = "seoul"; // capitals라는 map의 korea라는 문자열에 seoul이 대응되어 들어가있다. capitals["usa"] = "washington"; printf("%s\n ", capitals["korea"].c_str()); // seoul이 출력됨 // erase 멤버함수 : key 값을 집어 넣어주면 해당 key 값을 지워준다. capitals.erase("korea"); // count 멤버함수 : key를 가지고 key에 해당하는 값의 존재 유무에 대한 값을 리턴 if (capitals.count("korea") == 1) { printf("korea가 존재합니다."); } else { printf("korea가 존재하지 않습니다.."); } return 0; } |
std::map의 순회
std::map은 순회를 하기 위해 일반적인 for 루프를 활용할 수 없고,
iterator (순회자)를 활용한 순회만 가능하다.
for (auto it = m.begin(); it != m.end(); it++) {
it->first; // map의 각각 키
it->second; // map의 각각 값
}
map에 들어가있는 인덱스는 넣은 순서가 아니라
tree라는 자료구조를 통해서 만들어지게 된다.
자동으로 정렬이 됨
#define _CRT_SECURE_NO_WARNINGS #include <cstdio> #include <vector> #include <map> #include <string> #include <algorithm> int main() { std::map<std::string, std::string> capitals; capitals["korea"] = "seoul"; capitals["china"] = "beijing"; capitals["usa"] = "washington"; for(auto it = capitals.begin(); it != capitals.end(); it++) { printf("first : %s\n", it->first.c_str()); // first는 key printf("second : %s\n", it->second .c_str()); // second는 value printf("capitals[ %s ] = %s\n", it->first.c_str(), it->second.c_str()); // 위와 같은 의미 } return 0; } |
연습 프로그래밍
1번 선택시 회원가입, 2번 선택시 회원의 리스트 출력, 3번 선택시 종료되는 프로그램
#define _CRT_SECURE_NO_WARNINGS #include <cstdio> #include <vector> #include <map> #include <string> #include <algorithm> int getInteger(const char* prompt) { printf("%s", prompt); int input; fseek(stdin, 0, SEEK_END); scanf("%d", &input); return input; } // std string을 리턴해주는 getString 함수 std::string getString(const char* prompt) { printf(prompt); char str[100] = { 0, }; // 초기화 fseek(stdin, 0, SEEK_END); scanf("%99[^\n]s", str); return str; // =이라는 operator가 오버로딩 되어있어 자동으로 캐스팅해서 리턴해준다. } 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"); } } 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; } else { printf("잘못된 입력 입니다..\n"); } } return 0; } |
과제형 연습 프로그래밍
Headerf.h
#ifndef __HEADERF_H__ #define __HEADERF_H__ #define _CRT_SECURE_NO_WARNINGS #include <cstdio> #include <map> #include <string> int getInt(const char* prompt); std::string getString(const char* prompt); class Dictionary { private: std::map<std::string, std::string> words; // 단어와 매칭되는 뜻 public: void insertWorld(const std::string& word, const std::string& meaning); bool exists(const std::string& word); std::string getMean(const std::string& word); }; #endif |
Source.cpp
#include "Headerf.h" int main() { Dictionary* dict = new Dictionary; for (;;) { printf("1. 단어 등록\n"); printf("2. 단어 찾기\n"); printf("3. 프로그램 종료\n"); int input = getInt("메뉴 번호를 입력하세요 : "); if (input == 1) { // 단어등록 std::string word = getString("단어를 입력하세요 : "); std::string mean = getString("뜻을 입력하세요 : "); dict->insertWorld(word, mean); printf("정상적으로 등록이 되었습니다\n\n"); } else if (input == 2) { // 단어찾기 std::string word = getString("찾을 단어 : "); if (dict->exists(word)) { printf("단어 뜻 : %s\n", dict->getMean(word).c_str()); } else { printf("없는 단어 입니다.\n"); } } else if (input == 3) { // 프로그램 종료 printf("프로그램을 종료합니다.\n"); break; } else { printf("잘못 입력하셨습니다.\n"); } } return 0; } int getInt(const char* prompt){ int input; printf(prompt); fseek(stdin, 0, SEEK_END); scanf("%d", &input); return input; } std::string getString(const char* prompt){ char input[100] = { 0, }; printf(prompt); fseek(stdin, 0, SEEK_END); scanf("%99[^\n]s", input); return input; } void Dictionary::insertWorld(const std::string& word, const std::string& meaning){ // 단어 입력 // 변수를 그대로 가져오기 때문에 값복사가 일어나지 않는다. words[word] = meaning; } bool Dictionary::exists(const std::string& word){ // 단어 존재유무 return words.count(word) == 1; } std::string Dictionary::getMean(const std::string& word){ // 단어를 통해 뜻을 가져오기 return words[word]; } |
'C++' 카테고리의 다른 글
c++ 16 ( 파일 입출력 2 ) (0) | 2022.02.25 |
---|---|
c++ 16 ( 파일 입출력 1 ) (0) | 2022.02.23 |
c++ 14 ( Generic 이라고도 불릴 수 있는 개념 ) (0) | 2022.02.22 |
c++ 13 ( const / static / extern ) (0) | 2022.02.19 |
c++ 12 (문자열과 네임스페이스 그리고 레퍼런스 타입) (0) | 2022.02.17 |