https://school.programmers.co.kr/learn/courses/30/lessons/160586

 

프로그래머스

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

programmers.co.kr

더보기 주의 , 코드에 관한 설명이 간략히 있지만 코드 내용 원문이 있으니 주의 할 것 

 

<나의 풀이 (비추천)>

더보기

정답처리 된 코드지만 , 가독성이 안좋게 구성이 되었다.

하나의 target을 정한뒤 keymap을 벡터를 탐색해서 해당 문자를 찾는것으로 설계를 하다보니 반복문 다중으로 많이 사용되었음. 

 

플로우차트는 

0.target의 문자열을 길이기준으로 오름차순 정렬

ex) ABCD,ABC,ABCDE -> ABC,ABCD,ABCDE

1.비교할 target 선정 

1-1.target의 char(단일문자)하나를 선정
2.target_Char 와 keymap과의 비교 시작

2-1.keymap_char_index 설정 ( keymap 리스트에 공통적으로 적용되는 인덱스)

2-2. keymap_list Roop 시작

2-3.비교 시작  

2-3-1.(같은 문자를 찾은경우) 2-1로 돌아감,roop한 횟수를 answer에 저장

2-3-2.(같은 문자를 못 찾은경우) 2-1로 돌아감,,다시 탐색

2-3-3.(roop를 다 돌렸지만 해당 target 문자를 못찾을경우) answer 벡터에 -1 대입후 반복문 탈출 및 1번으로 돌아감

#include <string>
#include <vector>
#include <algorithm>

using namespace std;

bool compare(string keymap1, string keymap2)
{
    //글자갯수로 오름차순 정렬
    return keymap1.length() < keymap2.length();
}

bool char_compare(char target_char,vector<string> keymap,int c)
{
    for (int d = 0; d < keymap.size(); d++)
    {
    	//해당 target의 문자 index가 문자열 길이 보다 크거나 같을경우, 그 반복문 본문 스킵
        //ex)ABC(문자열 길이 3) targer index (4) -> skip 
        if (keymap[d].length() <= c)
        {
            continue;
        }

        char key_char = keymap[d].at(c);

        //2-3.비교시작
        if (target_char == key_char)
        {
            //2-3-1.(같은 문자를 찾은경우) 2-1로 돌아감,roop한 횟수를 answer에 저장
            return true;
        }

    }

    return false;
}

vector<int> solution(vector<string> keymap, vector<string> targets)
{
    //keymap 문자열 길이기준으로 오름차순 정렬 
    sort(keymap.begin(), keymap.end(), compare);
    int roop_count = keymap.back().length(); // target중 제일 긴문자를 roop횟수로 설정
	
	//answer를 target벡터 갯수만큼 초기화
    vector<int> answer;
    for (int i = 0; i < targets.size(); i++)
    {
        answer.push_back(0);
    }
    bool fail_check = false;

    for (int a = 0; a < targets.size(); a++)
    {
        //1.비교할 target 선정
        string target_str = targets[a];// targets 문자열 정의
        int target_length = target_str.length();

        for (int b = 0; b < target_length; b++)
        {
            //1-1.target Char 설정
            char target_char = target_str.at(b);

            //2.target_Char vs keymap_list (비교)
            //2-1.keymap_char_index 설정( 리스트에 공통)
            
            //c : target_char_index
            for (int c = 0; c < roop_count; c++)
            {
                //2-2.keymap_list_index 루프 시작
                if (char_compare(target_char, keymap, c))
                { 
                    answer[a] += c + 1;
                    break;
                }
                
          	   //해당되는 글자를 못찾을경우 -1과 bool값 변경
                if (c == roop_count - 1)
                {
                    answer[a] = -1;
                    fail_check = true;
                }
            }
			
			//해당 문자열은 출력 못하므로 문자열 반복문 탈출 
            if (fail_check)
            {
                fail_check = false;
                break;
            }

        }
    }

    return  answer;
}

<다른사람의 풀이>

더보기

이 풀이는 target을 먼저 탐색하기 전에 , keymap을 루프를 돌려 해당 문자를 출력하기 위한 최소의 횟수를 미리 리스트화 한뒤 target에 접근 하는 방식이다.

플로우차트는

1.26개(알파벳갯수)의 사이즈의 벡터를 100000(MARKER)로 전부 초기화

1-1.keymap을 기준으로 루프를 돌려 table에 해당 문자열을 찾기위해 최소 횟수 탐색
ex) 

target = { ABACD , BECFD }

첫번째 루프 (ABACD)

table[0] = 1 // 1=min(100000 , 1) 알파벳 A

table[1] = 2 // 1=min(100000 , 2) 알파벳 B

table[0] = 1 // 1=min(1 , 1) 알파벳 A

table[2] = 4 // 4=min(100000 , 4) 알파벳 C

table[3] = 5 // 5=min(100000 , 5) 알파벳 D

 

두번째 루프 (BCEFD)

table[1] = 1 // 1=min(2 , 1) 알파벳 B

table[2] = 2 // 2=min(4 , 2) 알파벳 C

table[4] = 3 // 1=min(100000 , 3) 알파벳 E

table[5] = 4 // 4=min(100000 , 4) 알파벳 F

table[3] = 5 // 5=min(5 , 5) 알파벳 D

 

최종 결과물
table[0] = 1  // 알파벳 A를 출력하기 위한 최소 횟수

table[1] = 1 // 알파벳 B를 출력하기 위한 최소 횟수

table[2] = 2 // 알파벳 C를 출력하기 위한 최소 횟수

table[3] = 5 // 알파벳 D를 출력하기 위한 최소 횟수

table[4] = 3 // 알파벳 E를 출력하기 위한 최소 횟수

table[5] = 4 // 알파벳 F를 출력하기 위한 최소 횟수

table[6] = 100000 // 알파벳 G를 출력하지 못함
... 

 

 이런식의 roop를 통해 미리 알파벳의 최소 루트를 구해놓은뒤 작업을 한다 .

#include <string>
#include <vector>

using namespace std;

vector<int> solution(vector<string> keymap, vector<string> targets) {
    vector<int> answer;

    const int MARKER = 1000000; //  MARKER : 사용하지않는것을 표시
    vector<int> table(26, MARKER);  //26개(알파벳 갯수)의 벡터 사이즈 설정 , MARKER(100000)으로 초기화
   
   //keymap를 루프 둘려 각 단일문자를 최소의 횟수로 찾아가는지 탐색 
    for (const auto& v : keymap)
    {
        for (int i = 0; i < v.size(); ++i)
        {
            table[v[i] - 'A'] = min(table[v[i] - 'A'], i + 1);
        }
    }

    for (const auto& str : targets)
    {
        int total = 0;
        for (const auto c : str)
        {
            //MARKER와 같으면 이 문자는 출력할수 없다는 뜻
            if (table[c - 'A'] == MARKER)
            {
                //결과값 -1과 해당 문자열 탈출 
                total = -1;
                break;
            }
            else
            {
				//위에서 구한 해당 문자의 최소 출력횟수를 total에 더함
                total += table[c - 'A'];
            }
        }
		
        //push_back과 같은 의미지만 자료형이 같을경우 사용할수 있는 push_back
        answer.emplace_back(total);
    }

    return answer;
}

 

 

'코딩테스트 > 프로그래머스' 카테고리의 다른 글

LV.2 최솟값 만들기  (0) 2023.06.09
LV.1 내적  (0) 2023.06.09
LV.1 없는 숫자 더하기  (0) 2023.06.09
LV.1 공원산책  (0) 2023.06.08
[LV2] 귤 고르기  (0) 2023.05.31

+ Recent posts