출처: https://school.programmers.co.kr/learn/courses/30/lessons/70129
문제 설명
0과 1로 이루어진 어떤 문자열 x에 대한 이진 변환을 다음과 같이 정의합니다.
x의 모든 0을 제거합니다.
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 해야 합니다.
우선, 내가 작성한 코드문은 여기까지나 [2,1]이라는 결과가 똑같이 나왔다.
class Solution {
public int[] solution(String s) {
int[] answer = new int[2];
// x의 모든 0을 제거
// x의 길이를 c라고 하면, x를 "c를 2진법으로 표현한 문자열"로 바꿈
// 이진 변환 이전 = s 그대로
// 제거할 0의 갯수 반복문 돌리면서 세기
// 0 제거 후 길이 = s전체길이 - 제거할 0의 갯수
// 0 제거 후 길이 이진 변환결과
int count = 0;// 제거할 0의 개수
int wholeCount = 0;
// s가 "1"이 될때 까지
while(!s.equals("1")){
count = 0;
wholeCount = 0;
for(int i = 0; i < s.length(); i++){
char ch = s.charAt(i);
if(ch == '0'){
ch = ' ';
count++;
}
wholeCount++;
}
s = Integer.toBinaryString(s.length() - count);// s길이에서 - 0갯수 이값을 이진변환 시키기
}
// answer 배열에 저장
answer[0] = wholeCount;
answer[1] = count;
return answer;
}
}
그리고 wholeCount에서는 변환 횟수가 아닌
전체 문자열 길이가 들어가서 이 또한 틀린 계산이다.
불필요한 코드문 제거 하고, 변수명 또한 변환 갯수, 0갯수 변수를
세는 변수를 가독성있게 변수명을 변경 했다.
class Solution {
public int[] solution(String s) {
int[] answer = new int[2];
// x의 모든 0을 제거
// x의 길이를 c라고 하면, x를 "c를 2진법으로 표현한 문자열"로 바꿈
// 이진 변환 이전 = s 그대로
// 제거할 0의 갯수 반복문 돌리면서 세기
// 0 제거 후 길이 = s전체길이 - 제거할 0의 갯수
// 0 제거 후 길이 이진 변환결과
int zeroCount = 0;// 제거할 0의 개수
int transformCount = 0;
// s가 "1"이 될때 까지
while(!s.equals("1")){
int count = 0;
for(int i = 0; i < s.length(); i++){
// char ch = s.charAt(i);
if(s.charAt(i) == '0'){
// ch = ' ';// 이것도 굳이 치환할 필요 없다 함
count++;
}
// wholeCount++;
zeroCount += count;
}
s = Integer.toBinaryString(s.length() - count);// s길이에서 - 0갯수 이값을 이진변환 시키기
transformCount++;
}
// answer 배열에 저장
answer[0] = transformCount;
answer[1] = zeroCount;
return answer;
}
}
이랬더니 18.2/100점이 뜨는데..
코드 실행결과
입력값 〉 "1111111"
기댓값 〉 [4, 1]
실행 결과 〉 테스트를 통과하였습니다.
만 정답이 되었다.
zeroCount += count;가 반복문 밖에 있어야 한다. 안 그러면
반복문 돌때마다 누적이 된다. 한번만 누적되게 수정해야 하기에.
최종으로 수정 된 코드문
class Solution {
public int[] solution(String s) {
int[] answer = new int[2];
int zeroCount = 0;// 제거할 0의 개수
int transformCount = 0;
// s가 "1"이 될때 까지
while(!s.equals("1")){
int count = 0;
for(int i = 0; i < s.length(); i++){
if(s.charAt(i) == '0'){
count++;
}
}
zeroCount += count;
s = Integer.toBinaryString(s.length() - count);// s길이에서 - 0갯수 이값을 이진변환 시키기
transformCount++;
}
// answer 배열에 저장
answer[0] = transformCount;
answer[1] = zeroCount;
return answer;
}
}