코딩 59일차 C/C++

마스터피스·2024년 1월 11일
0

C/ C++ 

목록 보기
31/35
post-thumbnail

기본 자료구조 - STL 기초 자료구조 활용

  1. STL 자료구조에 대하여
  • C++은 다양한 기본 자료구조를 제공합니다.이 자료구조는 프로그래머가 직접 프로그래밍할 필요 없이 C++ 안에서 기본적인 내용들을 구현한 STL 형태의 자료구조를 제공하여 이것을 잘 사용할 수만 있으면 프로그래밍하는 데는 일단 문제가 없습니다. 일반적으로 대학에서 자료구조 등을 배우는 이유는 이 자료구조를 통해 코딩 실력을 향상시키고 어떤 자료구조를 어떤 상황에 적재적소에 사용해야 하는지를 배우기 위해 자료구조를 공부하게 됩니다.이에 대한 흥미가 있으신 분은 따로 자료구조에 관한 전문 서적이나 강의를 찾아보시길 정말정말 추천드립니다.
  1. 벡터

    std::vector<T>

  • 편하지만 성능 저하가 있다.

예제코드)

#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[2] = 55;

    for (int i = 0; i < myvec.size(); i++) {
        printf("%d ", myvec[i]);
    }


    return 0;
}

추가내용) 알고리즘 헤더파일 에 관한 설명 : 단순히 vector 안에있는 내용들을 정렬 할 수 있다. std::sort(myvec.begin(), myvec.end()) sort 함수를 사용해 정렬되지 않은 내용을 정렬 가능하다.
예제코드)

#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());

    for (int i = 0; i < myvec.size(); i++) {
        printf("%d ", myvec[i]);
    }


    return 0;
}
  1. 각종 멤버 함수 및 활용

3-1) push_back( ... ) : 파라미터의 값을 벡터의 배열의 마지막에 집어넣습니다.

3-2) [ ], at( ... ) : 대괄호 연산자가 연산자 오버로딩 되어 마치 배열을 쓰는것 처럼 사용할 수 있습니다. at 함수를 이용해 동일한 동작을 할 수 있습니다.

3-3) size() : size() 멤버함수를 이용해 현재 벡터 내부의 원소가 몇개가 있는지 알 수 있습니다.

3-4) { ... } : 배열을 선언하며 값을 초기화하듯이 브라켓을 이용하여 초기에 원소 값을 지정해 줄 수 있습니다.

  1. 순회자 (iterator)

  1. auto

  • auto라는 키워드는 컴파일러 입장에서 추론 가능한 (대부분 선언과 동시에 할당되는 경우)에 사용 가능한 키워드 입니다. 이 auto 라는 키워드는 필요없는 타이핑을 줄여줄 수 있어서 많은 경우에 사용되고 있습니다.

예제코드)

  #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());

      //순회자 활용
      /*for (std::vector<int>::const_iterator it = myvec.begin(); it != myvec.end(); it++) {
          //printf("%d ", *it);
       }*/
      // 순회자는 너무 길기 때문에 AUTO를 사용한다.

      for (auto it = myvec.begin(); it != myvec.end(); it++) {
          printf("%d ", *it);
      }

      return 0;
  }
  1. MAP

    std::map<K, V>

  • map 자료구조는 우리가 배열을 사용하듯 사용할 수 있다는 장점이 있습니다.

*더 알아보기

map 자료구조는 내부적으로 std::set이라는 집합 자료구조를 활용해서 구현되었으며, std::set은 내부적으로 Tree 라는 자료구조를활용해서 만들어졌습니다.

때문에 값을 집어넣을때 자동으로 정렬이 된다는 특징이 있습니다.

Tree 자료구조는 원소를 집어넣을 때 자동으로 정렬이 되는 자료구조 입니다.

  1. 각종 멤버 함수및 활용

7-1) [ ] : 대괄호에 가 연산자 오버로딩 되어 배열처럼 사용할 수 있다.

7-2) count( ... ) : 현재 map에 지정된 키의 개수를 리턴한다. 키가 존재하는지 확인하는 용도로 많이 사용된다.

7-3) erase( ... ) : 현재 map에 지정된 키를 삭제합니다. 키를 삭제하면 키와 함께 존재하는 값도 삭제됩니다.

예제코드)

#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";

    // 배열 사용하는 것 처럼 사용 가능하다.
    //printf("%s", capitals["korea"].c_str());

    //count 사용

    capitals.erase("korea");

    if (capitals.count("korea") == 1) {
        printf("korea가 존재합니다.");
    }
    else {
        printf("korea가 존재하지 않습니다.");
    }





    return 0;
}
  1. std::map의 순회

  • std::map은 순회를 하기 위해 일반적인 for 루프를 사용할 수 없으며 순회를 위해 순회자(iterator)를 사용하여 순회를 해야 합니다. std::map은 순회할때마다 iterator에 지정되어있는 first, second 라는 멤버를 이용해 키 값 쌍에 접근할 수 있습니다.

예제코드)

#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";

    // 배열 사용하는 것 처럼 사용 가능하다.
    //printf("%s", capitals["korea"].c_str());

    //count 사용


    for (auto it = capitals.begin(); it != capitals.end(); it++) {
        printf("capitals[%s] = %s\n", it->first.c_str(), it->second.c_str());
    }




    return 0;
}

실습형 문제)

sol)

#define _CRT_SECURE_NO_WARNINGS

#include <cstdio>
#include <vector>
#include <map>
#include <string>
#include <algorithm>

int getInteger(const char* prompt) {

    printf(prompt);

    int input;
    fseek(stdin, 0, SEEK_END);
    scanf("%d", &input);

    return input;

}

std::string getString(const char* prompt) {
    printf(prompt);
    char str[100] = { 0, };
    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("아이디를 입력해 주세요: \n");
            std::string password = getString("비밀번호를 입력해주세요: \n");
            // 중복된 아이디 체크
            if (member.count(id)) {
                printf("중복된 아이디 입니다.\n");
            }
            else {
                member[id] = password;
                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("프로그램이 종료됩니다. \n");
            break;

        }
        else {

            printf("잘못된 입력입니다.\n");
        }

    }


    return 0;
}

과제형 문제)

sol)

해더파일)

#ifndef __HEADER_H__
#define __HEADER_H__


#define _CRT_SECURE_NO_WARNINGS

#include <cstdio>
#include <string>
#include <algorithm>
#include <map>
#include <vector>

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

소스파일)

#include "Header.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");

        }
        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];
}
profile
코딩 일지

0개의 댓글