기록

99클럽 코테 스터디 6일차 TIL C++ vector, getline : 한줄로 입력받기 본문

코딩테스트/cpp

99클럽 코테 스터디 6일차 TIL C++ vector, getline : 한줄로 입력받기

youngyin 2024. 11. 3. 18:34

오늘의 학습 키워드

문제1 : vector, 한줄로 입력받기(getline)

 

https://www.acmicpc.net/problem/31562

공부한 내용 본인의 언어로 정리하기

문제1 : 문자열

 

(1) vector
STL(Standard Template Library)에서 제공하는 동적 배열로, 문자열을 저장하는 데 사용됩니다. 크기를 동적으로 조절할 수 있습니다. 

메서드/기능 코드 예시 설명
vector 선언 vector<string> myVector; vector를 선언하여 문자열을 저장할 동적 배열을 생성합니다.
vector::push_back myVector.push_back("Hello"); push_back 메서드는 vector의 끝에 새로운 요소를 추가하는 데 사용됩니다.
vector::pop_back myVector.pop_back(); pop_back 메서드는 vector의 마지막 요소를 제거하는 데 사용됩니다. 이 메서드를 호출하면 마지막 요소가 삭제되고, vector의 크기가 하나 줄어듭니다.
vector::begin auto it = myVector.begin(); begin 메서드는 vector의 첫 번째 요소에 대한 반복자를 반환합니다. 이 반복자를 사용하여 요소를 탐색할 수 있습니다.
vector::erase myVector.erase(myVector.begin() + 1); erase 메서드는 지정한 위치의 요소를 제거합니다. 인덱스를 통해 특정 요소를 삭제할 수 있습니다.
vector[idx] string firstElement = myVector[0]; 대괄호 연산자를 사용하여 특정 인덱스의 요소에 접근합니다. 인덱스는 0부터 시작합니다.

 

(2) 문자열 split

C++ 표준 라이브러리는 문자열을 직접적으로 분할(split)하는 함수는 제공하지 않습니다. 하지만, 문자열을 공백이나 특정 구분자를 기준으로 나누는 작업은 std::istringstream과 같은 클래스를 사용하여 구현할 수 있습니다.

아래 문제 풀이에서는 istringstream을 사용하지 않고, ' '를 발견할 때마다 vector에 값을 넣는 방법을 선택했습니다.

 

[Delimiter = ' ']

// 문자열을 공백으로 나누는 함수
vector<string> split(const string& str) {
    vector<string> result;
    istringstream iss(str);
    string word;

    while (iss >> word) {
        result.push_back(word);
    }

    return result;
}

 

[Delimiter = ',']

// 문자열을 쉼표로 나누는 함수
vector<string> split(const string& str) {
    vector<string> result;
    istringstream iss(str);
    string item;

    // 쉼표를 기준으로 문자열을 읽어옴
    while (getline(iss, item, ',')) {
        result.push_back(item);
    }

    return result;
}

 

(3) getline : 한줄 단위로 입력 값 받기

getline 함수는 C++에서 표준 입력 스트림(std::cin)이나 파일 스트림(std::ifstream, std::ofstream)으로부터 한 줄 전체를 읽어오는 데 사용되는 함수입니다. 이 함수는 공백이나 특정 구분자를 포함한 문자열을 처리할 수 있어, 사용자 입력이나 파일 내용을 한 줄 단위로 읽을 수 있습니다.

(주의) getline이 호출되기 전 받는입력이 있다면, 버퍼에 개행문자가 남아있어 '\n'이 getline에 바로 입력되어버리는 현상이 발생합니다. 이 때 cin.ignore을 이용한다면 버퍼를 비울 수 있습니다.

string line;
cin.ignore(); // 남아있는 개행 문자를 무시
getline(cin, line);

 

(4) 전체 풀이

#include <iostream>
#include <map>
#include <vector>

using namespace std;

static map<string, vector<string>> m_mapMusic; 

// 주어진 문자열을 공백 기준으로 나누어 단어를 벡터에 저장하는 함수
vector<string> split(string strOrg){
    int prev=0, cur;
    vector<string> result;
    cur = strOrg.find(' '); // 첫 번째 공백의 위치 찾기

    // 공백이 없으면 원본 문자열을 결과에 추가
    if (cur == string::npos){
        result.push_back(strOrg);
        return result;
    }

    // 문자열을 공백 기준으로 나누기
    while (cur != string::npos){
        string word = strOrg.substr(prev, cur-prev); // 공백 이전의 단어 추출
        result.push_back(word);
        prev = cur + 1; // 다음 단어의 시작 위치
        cur = strOrg.find(' ', prev); // 다음 공백 찾기
    }

    return result; // 결과 벡터 반환
}

int main()
{   
    int N, M;
    string line;
    vector<string> data;
    cin >> N >> M; // N과 M 입력 받기
    cin.ignore(); // 남아있는 개행 문자를 무시

    // N번 만큼 입력을 받고 처리
    while (N-- > 0){
        getline(cin, line); // 한 줄 전체를 입력 받음
        data = split(line); // 입력된 줄을 공백 기준으로 나누기

        string title = data[1]; // 제목
        string um1 = data[2]; // 첫 번째 키
        string um2 = data[3]; // 두 번째 키
        string um3 = data[4]; // 세 번째 키

        string key = um1 + " " + um2 + " " + um3; // 키 생성
        m_mapMusic[key].push_back(title); // 키에 제목 추가
    }

    // M번 만큼 입력을 받고 처리
    while (M-- > 0){
        getline(cin, line); // 한 줄 전체를 입력 받음

        vector<string> vecTitle = m_mapMusic[line]; // 입력된 키에 해당하는 제목 가져오기
        if (vecTitle.size() == 0){
            cout << '!' << endl; // 제목이 없으면 '!' 출력
        } else if (vecTitle.size() > 1){
            cout << '?' << endl; // 제목이 여러 개이면 '?' 출력
        } else {
            cout << vecTitle[0] << endl; // 제목이 하나이면 출력
        }
    }

    return 0;
}

오늘의 회고

오늘 학습한 내용을 통해 C++의 기본적인 자료형인 vector, map, string을 다루는 방법에 대해 이해할 수 있었습니다. 앞으로는 이러한 기본적인 자료형과 STL을 바탕으로 더 복잡한 알고리즘 문제를 풀 수 있도록 연습을 계속하고, 다양한 문제에 적용해보는 것이 중요하다고 생각합니다. 기본 자료형과 같은 기초를 다지면서, 점차 난이도를 높여가는 연습을 해야겠습니다.

Comments