본문 바로가기
카테고리 없음

삽질 ep.1 (feat. compareTo)

by 수수남매 2023. 10. 22.
  • 프로그래머스 문제 풀다가 제한 사항을 착각하고 2시간 동안 삽질한 썰임...

  • 문제는 "크기가 작은 부분문자열"이고 제한 사항으로 "p의 길이 < t의 길이 < 10,000"가 있었음
  • 여기서... 함수 매개변수의 순서 "(String t, String p)"와 제한사항의 순서 "p < t < 10,000"를 보면 t, p 순서가 다름
  • 그래서 나는 p의 길이가 10,000이하(10의 10,000승??)인 것으로 착각하고 Long.parseLong은 생각도 안 했음...
  • 결국 .charAt() 메서드로 숫자 하나씩 비교해 가면서 매우 무식하게....... 풀긴 풀었음!!
int count = 0;
int pLen = p.length();

for (int i = 0; i <= t.length() - pLen; i++) {
    int j = 0;
    if (t.charAt(i) < p.charAt(j)) {
        count++;
    } else if (t.charAt(i) == p.charAt(j)) {
        if (pLen == 1) {
            count++;
        } else {
            while (true) {
                j++;
                if (t.charAt(i + j) < p.charAt(j)) {
                    count++;
                    break;
                } else if (t.charAt(i + j) == p.charAt(j)) {
                    if (j == pLen - 1) {
                        count++;
                        break;
                    } else {
                        continue;
                    }
                } else {
                    break;
                }
            }
        }
    }
}
return count;
  • 그런데 chatGPT한테 물어봤더니 그냥 String 메서드 하나로 끝내 버렸음... 하... 내 2시간...
int count = 0;
for (int i = 0; i <= t.length() - p.length(); i++) {
    String subStr = t.substring(i, i + pLen);
    if (subStr.compareTo(p) <= 0) { // 오늘 이후로 절대 잊지 말아야 할 .compareTo()!!
        count++;
    }
}
return count;
  • compareTo 메서드를 구경하러 가 봤더니... 음.. 완벽하게 이해는 안 되지만 String의 값을 byte[]로 받고 getChar메서드를 써서 바이트연산으로 다시 char를 반환한 후 비교하는 것으로 보임. 나중에 더 공부해 봐야 할 듯!
// String class의 compareTo 메서드 정의
public int compareTo(String anotherString) {
    byte v1[] = value;
    byte v2[] = anotherString.value;
    byte coder = coder();
    if (coder == anotherString.coder()) {
        return coder == LATIN1 ? StringLatin1.compareTo(v1, v2)
                               : StringUTF16.compareTo(v1, v2);
    }
    return coder == LATIN1 ? StringLatin1.compareToUTF16(v1, v2)
                           : StringUTF16.compareToLatin1(v1, v2);
}

// StringUTF16 class의 compareTo 정의
@IntrinsicCandidate
public static int compareTo(byte[] value, byte[] other) {
    int len1 = length(value);
    int len2 = length(other);
    return compareValues(value, other, len1, len2);
}
// StringUTF16 class의 compareValues 정의
private static int compareValues(byte[] value, byte[] other, int len1, int len2) {
    int lim = Math.min(len1, len2);
    for (int k = 0; k < lim; k++) {
        char c1 = getChar(value, k);
        char c2 = getChar(other, k);
        if (c1 != c2) {
            return c1 - c2;
        }
    }
    return len1 - len2;
}
// StringUTF16 class의 getChar 정의
@IntrinsicCandidate  // intrinsic performs no bounds checks <- java의 주석
static char getChar(byte[] val, int index) {
    assert index >= 0 && index < length(val) : "Trusted caller missed bounds check";
    index <<= 1;
    return (char)(((val[index++] & 0xff) << HI_BYTE_SHIFT) |
                  ((val[index]   & 0xff) << LO_BYTE_SHIFT));
}