본문 바로가기

Algorithm/문자열

c++ 특정 문자열까지 잘라서 사용해야 되는 경우(find, rfind, substr) + Kakao 신고 결과 받기 풀이

이번에는 특정 문자열을 잘라서 사용해야 되는 경우에 사용할 수 있는 명령어를 알아보도록 하겠습니다.


먼저 문자열의 위치 검색을 할 수 있는 함수가 있습니다. find와 rfind입니다.

find(찾을 문자열) 문자열 검색을 앞에서부터 하여 발견되는 위치에 인덱스를 반환합니다.
rfind(찾을 문자열) 문자열 검색을 뒤에서부터 하여 발견되는 위치에 인덱스를 반환

이 두 명령어의 차이가 느껴지시나요? 잘 모르시는 분들을 위해 예시 코드를 하나 준비했습니다.

#include <iostream>
using namespace std;

int main() {
	string s = "abba";

	cout << "find:" << s.find('a') << endl;
	cout << "rfind: " << s.rfind('a') << endl;
}
find: 0
rfind: 3

위 코드의 결과를 보면 알 수 있듯이 find는 앞에서부터 시작하기 때문에 0번 인덱스에 있는 a를 먼저 발견하여 0을 반환하게 되고 rfind는 뒤에서부터 찾기 시작하여 3번 Index에 있는 a를 먼저 발견하여 3을 반환하게 됩니다.


자 그럼 위치는 찾아냈습니다. 하지만 프로젝트 또는 알고리즘 문제를 풀 때는 이 반환한 인덱스를 통해 문자열을 잘라야 되는 경우가 생깁니다. 그럼 어떠한 명령어로 자를 수 있을까요? 그건 바로 substr입니다.

#include <string.h> // 사용하는 헤더파일
substr() 문자열의 일부를 추출해줍니다.
substr(시작할 순서) -> 시작할 순서부터 문자열 끝까지 반환
substr(시작할 순서, 개수) -> 시작할 순서에서 개수만큼의 문자열을 반환

자 그럼 위 배운 명령어를 이용하여 2022 KAKAO Blind recruitment의 문제인 신고 결과 받기를 풀어보도록 하겠습니다.

https://programmers.co.kr/learn/courses/30/lessons/92334

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

#include <string>
#include <vector>

using namespace std;

vector<int> solution(vector<string> id_list, vector<string> report, int k) {
    vector<int> answer;
    
    //초기화
    for(int i = 0; i < id_list.size(); i++) answer.push_back(0);
    
    for(int i = 0; i < id_list.size(); i++) {
        int* arr = new int[id_list.size()];
        int count = 0;
        for(int j = 0; j < report.size(); j++) {
            
            // 문자열 자르기
            size_t pos = report[j].rfind(' ');
            string user = report[j].substr(0, pos);
            string reportU = report[j].substr(pos + 1);
            
            //체크
            if(reportU == id_list[i]) 
            {
                //신고한 유저 탐색
                for(int y = 0; y < id_list.size(); y++) {
                    if(id_list[y] == user && arr[y] != 1) {
                        arr[y] = 1;
                        count++;
                    }
                }
            }
        }
        
        if(count >= k) {
            
            for(int j = 0; j < id_list.size(); j++) 
            {
                if(arr[j] == 1)
                    answer[j] += 1;
            }
        }
    }
    

    return answer;
}

이 문제의 핵심은 report에 들어오는 문자열을 자를 수 있나?가 핵심이었습니다. 그리고 이것을 나누는 판단이 공백이었습니다. 그래서 rfind를 통해 공백의 위치를 알아내고 substr를 통해 신고한 사람의 문자열과 신고당한 사람의 문자열을 각각 다른 string 변수에 넣어서 체크를 하였습니다.


이렇게 위 명령어를 잘 활용한다면 문자열에 대한 알고리즘을 쉽게 접근 할 수 있을 것입니다.