
링크: https://school.programmers.co.kr/learn/courses/30/lessons/70129
문제분류 : 문자열
난이도 : Level 2
풀이시간 : 30분 안쪽
결과: 성공
크게 어려운 부분은 없었다. 답도 한 번에 찾았다.
다만 메서드들을 좀 외울 필요가 있을거 같기도 하고,
모범 답안에서 얻을 수 있는 교훈이 하나있어서 기억하고자 작성한다.
1. String 클래스가 가지고 있는 메서드의 대부분은 CharSequence 인터페이스에 정의되어 있는 메서드이다.
String 클래스를 다룰 때와 CharSequence를 다룰 때 동일한 메서드로 작업할 수 있다는 점을 기억하자.
2. Integer(Long).parseInt(String s, int radix)
Integer, Long 클래스가 가지고 있는 static 메서드이다.
특정 진법(radix)으로 표현된 문자열을 정수(십진수)로 변환하는 것이다.
int decimalNumber = Integer.parseInt("100", 10); => 정수 100으로 변환
int binaryNumber = Integer.parseInt("1010", 2); => 정수 10으로 변환
참고 : parseInt 대신 valueOf를 사용하여도 된다. 사용법은 동일하다.
3. Integer(Long).toString(int(long) v, int radix)
정수 v를 radix 진법의 문자열로 변환하는 static 메서드이다.
String decimalStr = Integer.toString(100, 10); => 문자열 "100"으로 변환
String binaryStr = Integer.parseInt(10, 2); => 문자열 "1010"으로 변환
4. StringBuilder(String str).reverse()
StirngBuilder 클래스를 이용해 문자열을 쉽게 뒤집을 수 있다.
StringBuilder 또한 CharSequence 인터페이스를 구현하고 있기 때문에
문자열에서 사용하던 메서드를 그대로 사용할 수 있으니 참고하자.

풀이 과정은 아래와 같이 진행된다.
- 문자열에서 0을 제거하고 제거한 0의 개수를 업데이트한다.
- 0이 제거된 문자열의 길이를 구하고 문자열 이진수로 변환한다.
- 문자열 이진수가 "1"과 일치하는지 체크한다. 만일 일치하면 변환 횟수를 업데이트하고 끝낸다.
- 일치하지 않는다면 변환횟수를 업데이트하고 taget에 변환된 문자열 이진수를 넣은 뒤 변환을 반복한다.
removeZero에서는 실제로 0을 제거하여 새로운 문자열을 구성하여 반환했다.
convertToBinaryNumber에서는 파라미터로 받은 문자열의 길이를 구했다.
그 다음 Integer.toString()으로 숫자를 2진수 문자열로 반환했다.
isAnswer에서 target.equals("1");으로 답인지 아닌지 체크했다.
딱히 문제가 되는 풀이는 아니다.
다만, 내 코드는 문제에서 요구하는 과정을 있는 그대로 코드로 옮긴 것에 불과하지만
모범 답안은 좀 더 논리적인 방식으로 바꾼 코드이다.

주석을 주목하자.
우리가 원하는 최종형태는 문자열이 이진수로 1일 때이다.
그런데 생각해보면, 십진수가 1일때와 이진수가 1일 때는 동일하다.
따라서 우리가 구해야하는건 문자열의 길이가 1일때인 것이다.
그렇다면 일일이 0을 제거할 필요가 없다!
그래서 모범답안의 풀이 과정을 보면
- countZero 메서드를 통해 문자열에서 0의 개수를 구한다.
- loop(변환과정)에 1을 더하여 업데이트한다.
- removed(제거한 0의 개수)에 문자열에 포함된 0의 개수를 업데이트 한다.
- 전체 길이에서 0의 개수를 빼서 0을 제외했을 때의 길이를 구한다.
- 이진수로 변환(1이 아닐 경우에는 과정을 반복해야 하므로 변환해야함)하고 1인지 아닌지 체크한다.
논리적으로 좀 더 쉽게 문제를 변환하니 풀이가 한 순간에 짧아졌다.
있는 그대로 조건을 반영해서 코드를 작성하는 것도 좋지만,
논리적으로 변환할 수 있는 부분은 변환하는 연습도 해보도록 하자!