본문 바로가기
코딩 테스트 (C#)/프로그래머스 (Lv2)

[C#][프로그래머스] 이진 변환 반복하기

by 스누누피 2024. 11. 4.

프로그래머스 > 코딩테스트 연습 > 월간 코드 챌린지 시즌1 > 이진 변환 반복하기

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

 

📒 문제

0과 1로 이루어진 어떤 문자열 x에 대한 이진 변환을 다음과 같이 정의합니다.

  1. x의 모든 0을 제거합니다.
  2. x의 길이를 c라고 하면, x를 "c를 2진법으로 표현한 문자열"로 바꿉니다.

예를 들어, x = "0111010"이라면, x에 이진 변환을 가하면 x = "0111010" -> "1111" -> "100" 이 됩니다.

0과 1로 이루어진 문자열 s가 매개변수로 주어집니다. s가 "1"이 될 때까지 계속해서 s에 이진 변환을 가했을 때, 이진 변환의 횟수와 변환 과정에서 제거된 모든 0의 개수를 각각 배열에 담아 return 하도록 solution 함수를 완성해주세요.

 

제한사항

  • s의 길이는 1 이상 150,000 이하입니다.
  • s에는 '1'이 최소 하나 이상 포함되어 있습니다.

 

입출력 예

s result
"110010101001" [3,8]
"01110" [3,3]
"1111111" [4,1]

 

입출력 예 설명

 

입출력 예 #1

  • "110010101001"이 "1"이 될 때까지 이진 변환을 가하는 과정은 다음과 같습니다.
회차 이진 변환 이전 제거할 0의 개수 0 제거 후 길이 이진 변환 결과
1 "110010101001" 6 6 "110"
2 "110" 1 2 "10"
3 "10" 1 1 "1"
  • 3번의 이진 변환을 하는 동안 8개의 0을 제거했으므로, [3,8]을 return 해야 합니다.

입출력 예 #2

  • "01110"이 "1"이 될 때까지 이진 변환을 가하는 과정은 다음과 같습니다.
회차 이진 변환 이전 제거할 0의 개수 0 제거 후 길이 이진 변환 결과
1 "01110" 2 3 "11"
2 "11" 0 2 "10"
3 "10" 1 1 "1"
  • 3번의 이진 변환을 하는 동안 3개의 0을 제거했으므로, [3,3]을 return 해야 합니다.

입출력 예 #3

  • "1111111"이 "1"이 될 때까지 이진 변환을 가하는 과정은 다음과 같습니다.
회차 이진 변환 이전 제거할 0의 개수 0 제거 후 길이 이진 변환 결과
1 "1111111" 0 7 "111"
2 "111" 0 3 "11"
3 "11" 0 2 "10"
4 "10" 1 1 "1"
  • 4번의 이진 변환을 하는 동안 1개의 0을 제거했으므로, [4,1]을 return 해야 합니다.

💻 소스코드 1

using System;
using System.Linq;

public class Solution {
    public int[] solution(string s) {
        int[] answer = { 0, 0 };
        return removeZero(s, new int[] {0, 0});
    }
    
    public int[] removeZero(string s, int[] answer)
    {
        if (s == "1") return answer;
        answer[0]++;
        int zero = 0;
        int one = 0;
        foreach(char c in s)
        {
            if (c == '0') zero++;
            else one++;
        }
        answer[1] += zero;
        return removeZero(ToBinary(one), answer);
    }
    
    public string ToBinary(int n)
    {
        string s = "";
        while (n >= 1)
        {
            s += n % 2;
            n /= 2;
        }
        return s == "" ? "1" : string.Concat(s.Reverse());
    }
}

📝 풀이 1

재귀함수를 이용해서 문제를 해결했다.

0을 제거해주는 함수 zeroRemove를 만들어 0을 제거해준 뒤 2진법으로 만드는 함수에 넣어 나온 결과를 다시 zeroRemove에 넣어주었다. zeroRemove에서 받는 매개변수 s가 "1"이면 return해 재귀함수를 빠져나오게 설계했다.

 

💻 소스코드 2

using System;
using System.Linq;

public class Solution {
    public int[] solution(string s) {
            int[] answer = new int[] { 0, 0 };

            while (!s.Equals("1"))
            {
                answer[0]++;
                var OneCharCount = s.Where(x => x.Equals('1')).Count();
                answer[1] += s.Length - OneCharCount;

                s = Convert.ToString(OneCharCount, 2);
            }

            return answer;
    }
}

📝 풀이 2

다른 풀이를 찾아보다 ToString에 이진법으로 만드는 기능이 있다는 걸 처음 알게되서 가져오게 되었다.

재귀함수는 가독성이 떨어진다는 단점이 있기 때문에 위 코드처럼 while문으로 해결하는 코드가 더 좋은 코드라고 생각된다.

 


관련 포스팅

 

[C#] int에서 string로 변환 (int to string)

1. 단순 변환int의 ToString() 메서드를 사용하면 string으로 변환할 수 있다.int i = 3;string str = i.ToString();Console.WriteLine(str); // 3 2. 진법을 변환하면서 string으로 변환하기Covert클래스의 ToString 메서드를

twd0622.tistory.com