예전에 1의 개수를 비교하던것과 달리 여러 진수들이 나누어 질 수 있으므로 직접 진수를 구하는 로직을 구성해야 한다. 구성한 다음 순서에 맞춰 값들을 추가하자!
오랫만이기도 하고 해서 나머지 연산을 사용한다는건 알았는데 간단하게 또 문자를 이용하여 10진수 이상은 기억이 안나기도 해서 애를 먹었고 다른 분의 블로그를 참조하였다.
private static StringBuilder convertNum(int num, int n){ StringBuilder sb = new StringBuilder(); if(num==0) return sb.append(0); while(num != 0){ int mod = num % n; if(mod >= 10){ int idx = 'A' + (mod-10); sb.append((char)idx); } else sb.append(mod); num /= n; } //거꾸로 출력 return sb.reverse();
}
if(mod >= 10)
로 자리수가 한자리냐 두자리냐로 구분 뒤 두자리면int idx = 'A' + (mod-10);
를 이용하여 10이 넘는 수를 문자로 전환하고(-10은 앞자리 1을 제거) StringBuilder에 추가, 또 자리수가 StringBuilder내부에서 거꾸로이니 .reverse()
메소드를 호출함으로써 자리수 맞춤
StringBuilder sb = new StringBuilder(); for(int num=0; num<=t*m; num++){ //t*m개 만큼 // n진수화 StringBuilder tmp = convertNum(num,n); sb.append(tmp); }
t
는 문자갯수, m
은 참가자수이다. num은 최대한의 경우를 고려
해야 하므로, 모든 수가 자리수를 넘어가지 않을때(한 차례당 한 값 일 떄) 최대한 많은 값의 수를 가질 것이다. 따라서 t * m
1.n진법으로 변경도 시키고
2.최대한 나올 수 있는 갯수 만큼 값들도 입력하였으면
3.순서에 맞는 숫자(값들의 자리수)들만 골라내서 답에 추가시켜야 한다.
StringBuilder result = new StringBuilder(); for(int i=0;i<sb.length();i++){ if(result.length() >= t) break; if(((i+1)%m) == (p%m)){ result.append(sb.charAt(i)); } }
먼저 변수들을 정리해 보자
t = 예상해야할 숫자의 갯수
m = 참가자 수
p = 나의 순서(몇번째로 뽑는가)
다른 분의 블로그를 참조 하였을때 ((i+1) % m) == (p % m)
가 가장 헷갈렷고 이해하기 어려웠다.
p
은 몇 번째 순서인지에 대한 값이다.
(i+1)
인덱스는 0부터 시작하지만 순서는 1부터 시작한다. 즉 1번째가 0번 인덱스, 2번째가 1번 인덱스, ......n번째가 n-1번째 인덱스를 사용할 것이기에 +1을 해준다.
% m
마지막 순서 이후 다시 처음 순서로 돌아가기 위해서 필요하다.
class Solution {
public String solution(int n, int t, int m, int p) {
StringBuilder answer = new StringBuilder();
StringBuilder sb = new StringBuilder();
for(int i =0; i < t*m; i++){ //t:말해야하는 숫자갯수 , m: 참가자 수, t*m: 최대치
String temp = convertNum(i,n); //N진수로 치환
sb.append(temp);
}
//길이 만큼 구함
for(int i = 0; i < sb.length();i++){
if(answer.length() >= t) break; //튜브가 t개만큼 말하면 끝
//튜브의 차례면 추가, p%m : 튜브의 순서
if((i+1)%m == p%m) answer.append(sb.charAt(i));
}
//튜브가 말한 문자열
return answer.toString();
}
//10진수 num -> n진수 num으로 변환
private String convertNum(int num, int n){
StringBuilder sb = new StringBuilder();
if(num == 0) return "0"; //0은 그대로 0
//0일때 까지
while(num != 0){
int mod = num % n; //나머지 구하기
if(mod >= 10){ //나머지가 2자리
mod = 'A' + (mod-10); //문자로 치환
sb.append((char)mod);
}else //나머지가 1자리
sb.append(mod);
num /= n; //다음 자리 수
}
//1의 자리부터 순서대로 저장되었으므로 순서를 뒤집음
return sb.reverse().toString();
}
}
챙겨 볼 것:StringBuilder