(n진법)
- 오답 원인
- 진법 변환 메서드 로직이 틀린게 주요 원인
- 보완
- 진법 변환 로직은 코드로 바꿀때 잘 안됨. 연습해놓으면 앞으로 틀릴 가능성이 낮아질것으로 보임
틀린거
import java.util.*;
class Solution {
public String solution(long n, String[] bans) {
/*
주문서모음집의 주문은 11자 이하로 쓰여있다. 소문자.
n이 엄청 크다 long n번째 주문을 찾는게 관건
브루트포스하면 시초 발생 뻔함.
금지된 주문을 딱 넣으면 원래 몇번째인지 알 수 있으면 좋을거같은데.
알파벳은 26자 a(1) b c d e, f g h i j, k l m n o, p q r s t, u v w x y, z(26)
2자리수: aa(27) ab(28/26+2) ac ... az(52/26+26) , ba(53), bb ....
ae(26+5. = 31)
3자리수: aaa(일단 이까지오는데...)
*/
//n보다 크면 무시
//n보다 작으면 ++하고 이후에 n-x해주고 이 n-x가 어떤주문인지 파악하면된다.
//1. bans들의 순서 찾는다.
//System.out.println((int)'a');//97이니까 -96계혹해주면됨
List<Long> ints = new ArrayList<>();
for(String ban : bans){
ints.add(getNumber(ban));
}
ints.sort(Comparator.naturalOrder());
long myN = n;
Arrays.sort(bans);
for(long i : ints){
if(i < myN){
myN++;
}
}
return getString(myN+1);
}
public long getNumber(String str){
long number = 0;
for(int i = 0 ; i < str.length() ; i++ ){
number += (int)Math.pow(26, i) * ((int)(str.charAt(i)) - 96);
}
return number;
}
public String getString(long number){
System.out.println(number);
//21을 어케 2진수로 1101
/*
2|5
2|2--1
2|1--0
2|6
2|3--0
2|1--1
*/
StringBuilder sb = new StringBuilder();
while(26 <= number){
sb.append((char)(number%26+96));
//System.out.println("!"+(char)(number%26+96));
number = number/26;
}
sb.append((char)(number + 96));
sb.reverse();
return sb.toString();
}
}정답 코드
import java.util.*;
class Solution {
public String solution(long n, String[] bans) {
/*
주문서모음집의 주문은 11자 이하로 쓰여있다. 소문자.
n이 엄청 크다 long n번째 주문을 찾는게 관건
브루트포스하면 시초 발생 뻔함.
금지된 주문을 딱 넣으면 원래 몇번째인지 알 수 있으면 좋을거같은데.
알파벳은 26자 a(1) b c d e, f g h i j, k l m n o, p q r s t, u v w x y, z(26)
2자리수: aa(27) ab(28/26+2) ac ... az(52/26+26) , ba(53), bb ....
ae(26+5. = 31)
3자리수: aaa(일단 이까지오는데...)
*/
//n보다 크면 무시
//n보다 작으면 ++하고 이후에 n-x해주고 이 n-x가 어떤주문인지 파악하면된다.
//1. bans들의 순서 찾는다.
//System.out.println((int)'a');//97이니까 -96계혹해주면됨
List<Long> ints = new ArrayList<>();
for(String ban : bans){
ints.add(getNumber(ban));
}
ints.sort(Comparator.naturalOrder());
long myN = n;
for(long i : ints){
if(i <= myN){
myN++;
}else{
break;
}
}
return getString(myN);
}
/**
* 문자열을 1-26 기반의 26진법 숫자로 변환합니다.
* 예: "a" -> 1, "z" -> 26, "aa" -> 27, "ab" -> 28
*/
public long getNumber(String str) {
long number = 0;
long powerOf26 = 1; // 26^0, 26^1, 26^2, ...
// 문자열의 오른쪽부터 왼쪽으로 순회하며 계산해야 합니다.
for (int i = str.length() - 1; i >= 0; i--) {
// 'a'는 1, 'b'는 2, ..., 'z'는 26
long charValue = str.charAt(i) - 'a' + 1;
number += charValue * powerOf26;
powerOf26 *= 26;
}
return number;
}
/*
* 1-26 기반의 26진법 숫자를 문자열로 변환합니다.
* 예: 1 -> "a", 26 -> "z", 27 -> "aa", 28 -> "ab"
*/
public String getString(long number) {
StringBuilder sb = new StringBuilder();
// number가 0보다 클 때까지 반복합니다.
while (number > 0) {
// 0-25 범위의 나머지를 얻기 위해 (number - 1)을 합니다.
// 이렇게 하면 1~26이 0~25에 매핑됩니다. (1->0, 26->25)
long remainder = (number - 1) % 26;
sb.append((char) ('a' + remainder));
// 다음 자릿수 계산을 위해 (number - 1)을 26으로 나눕니다.
number = (number - 1) / 26;
}
// 결과는 역순으로 만들어지므로 뒤집어서 반환합니다.
return sb.reverse().toString();
}
}