본문 바로가기
프로그래머스 코딩테스트 문제/Level 1

[프로그래머스] - 숫자 짝꿍(C#)

by jyppro 2023. 9. 13.

숫자 짝꿍

오늘 풀어볼 문제는 "숫자 짝꿍" 입니다. 제목만 보고는 어떤 문제가 나올지 잘 예상이 안갑니다. 문제를 살펴보겠습니다.

 

문제 설명

두 정수 X, Y의 임의의 자리에서 공통으로 나타나는 정수 k(0 ≤ k ≤ 9)들을 이용하여 만들 수 있는 가장 큰 정수를 두 수의 짝꿍이라 합니다(단, 공통으로 나타나는 정수 중 서로 짝지을 수 있는 숫자만 사용합니다). X, Y의 짝꿍이 존재하지 않으면, 짝꿍은 -1입니다. X, Y의 짝꿍이 0으로만 구성되어 있다면, 짝꿍은 0입니다.

예를 들어, X = 3403이고 Y = 13203이라면, X와 Y의 짝꿍은 X와 Y에서 공통으로 나타나는 3, 0, 3으로 만들 수 있는 가장 큰 정수인 330입니다. 다른 예시로 X = 5525이고 Y = 1255이면 X와 Y의 짝꿍은 X와 Y에서 공통으로 나타나는 2, 5, 5로 만들 수 있는 가장 큰 정수인 552입니다(X에는 5가 3개, Y에는 5가 2개 나타나므로 남는 5 한 개는 짝 지을 수 없습니다.)
두 정수 X, Y가 주어졌을 때, X, Y의 짝꿍을 return하는 solution 함수를 완성해주세요.

 

제한사항

3 ≤ X, Y의 길이(자릿수) ≤ 3,000,000입니다.
X, Y는 0으로 시작하지 않습니다.
X, Y의 짝꿍은 상당히 큰 정수일 수 있으므로, 문자열로 반환합니다.

 

입출력 예

X Y result
"100" "2345" "-1"
"100" "203045" "0"
"100" "123450" "10"
"12321" "42531" "321"
"5525" "1255" "552"

 

입출력 예 설명

입출력 예 #1
X, Y의 짝꿍은 존재하지 않습니다. 따라서 "-1"을 return합니다.


입출력 예 #2
X, Y의 공통된 숫자는 0으로만 구성되어 있기 때문에, 두 수의 짝꿍은 정수 0입니다. 따라서 "0"을 return합니다.


입출력 예 #3
X, Y의 짝꿍은 10이므로, "10"을 return합니다.


입출력 예 #4
X, Y의 짝꿍은 321입니다. 따라서 "321"을 return합니다.


입출력 예 #5
지문에 설명된 예시와 같습니다.

 

시작 코드

using System;

public class Solution {
    public string solution(string X, string Y) {
        string answer = "";
        return answer;
    }
}

 

나의 풀이

using System;
using System.Text;

public class Solution {
    public string solution(string X, string Y) {
        string answer = "";
        int[] a = new int[10];
        int[] b = new int[10];

        for(int i = 0; i < X.Length; i++) { a[(int)(X[i] - 48)]++; }
        for(int i = 0; i < Y.Length; i++) { b[(int)(Y[i] - 48)]++; }
        StringBuilder sb = new StringBuilder();

        for(int i = 9; i >= 0; i--)
        {
            while(a[i] > 0 && b[i] > 0){
                sb.Append(i);
                a[i]--;
                b[i]--;
            }
        }
        if("".Equals(sb.ToString())) { answer = "-1"; }
        else if("0".Equals(sb.ToString().Substring(0, 1))) { answer = "0"; }
        else { answer = sb.ToString(); }
        return answer;
    }
}

 

코드 분석

string타입의 문자열 X, Y가 주어지며 코드가 시작됩니다. int형 배열로 a, b를 선언하고 각각 10의 크기로 지정해줍니다.

for문을 i = 0부터 X, Y의 길이까지 두번을 따로 돌려서 a[(int)(X[i] - 48)]++ 와 a[(int)(Y[i] - 48)]++ 를 실행해줍니다.

StringBuilder를 sb로 만들어 주고, for문을 9부터 0까지 돌려줍니다. 이 for문 안에서는 while문으로 a[i]와 b[i]가 둘 다 0보다 크다는 조건 하에 sb에 Append로 i를 붙여주고, a[i]와 b[i]를 감소시켜주는 작업을 합니다. 이후 반복문을 빠져나온 뒤에 if elseif 문에서 sb를 string으로 바꾼 것이 공백이라면 answer값을 -1로, Substring을 통해 0부터 1까지 자른 것이 0이라면 0을, 둘 다 아니라면 answer에 sb를 string으로 바꾼 값을 그대로 넣어 리턴해줍니다.

 

풀이 설명

문제에서 원하는 것은 의외로 간단합니다. 두 수 X, Y가 주어질 때, 두 수에 공존하는 수를 뽑아 합쳐서 가장 큰 수를 만든 것을 짝꿍이라 하고, 그것을 구하는 것입니다. 하지만 짝꿍이 없으면 -1, 짝꿍이 0밖에 없다면 0을 리턴합니다.

 

처음에 나오는 for문 2개는 X, Y의 문자열에 접근해 - 48로 빼주고 int형으로 바꿔준 인덱스의 값을 더해주는 데,

해당 작업은 아스키코드를 활용하는 방식입니다. 숫자형태의 문자열은 아스키코드에서 10진수로 표현하면 0이 48로 시작하여 9까지 1씩 커집니다. 그러니 X[i] - 48은 예시1번의 첫 시행이라면 "1" - 48로 아스키코드로 본다면 49 - 48입니다. 즉 1입니다. 그러니 a[1]을 증가시켜주는 것이 됩니다. 이후 for문과 while문으로 a[i]와 b[i]가 0이 될때까지 감소시켜주고 sb에 i를 붙여줍니다. 이후 sb가 공백인지, 0인지 혹은 그 외인지 판단하여 -1, 0, sb를 answer에 string타입으로 넣어 리턴해줍니다. 

 

<NEXT>

오늘은 "숫자 짝꿍" 문제를 풀어보았습니다. 다음에는 탐욕법(Greedy) 카테고리에 속하는 "체육복" 문제를 다뤄보도록 하겠습니다. 감사합니다.