마음을 다잡고 기초부터 다시 시작하는 첫째날.
코딩테스트 Lv0 입문버전을 풀어보며, 호기심으로 찾아본 삽질을 포스팅해보려 한다.
난이도 : 입문
주어진 문자열 str2가 str1안에 포함되어 있는지 물어보는 문제다.

class Solution {
public int solution(String str1, String str2) {
int answer = 2;
int str1Len = str1.length();
int str2Len = str2.length();
for (int i = 0; i <= str1Len - str2Len; i++) {
String pwd = str1.substring(i,i+str2Len);
if(pwd.equals(str2)) {
answer=1;
break;
}
}
return answer;
}
}
Q1. contains와 indexOf의 리턴타입은 다르지만 문자열내에서 주어진 문자열이 있는지 탐색을 한다는 점에서 같다. 서로 의존적이진 않은가?
A1. 그랬다. String클래스 파일을 열어보면 리턴시 indexOf(Stirng str)을 호출하는걸 볼수 있다.
public boolean contains(CharSequence s) {
return indexOf(s.toString()) >= 0;
}
Q2. indexOf는 어떤 방식으로 탐색하는 걸까?
A2. byte단위(char)단위로 찾아야하는 문자열의 첫글짜의 위치를 찾은 후 나머지를 비교한다.
Step1. 인코딩 방식에 따른 indexOf 호출
public int indexOf(@NotNull String str) {
byte coder = coder();
if (coder == str.coder()) {
return isLatin1() ? StringLatin1.indexOf(value, str.value)
: StringUTF16.indexOf(value, str.value);
}
if (coder == LATIN1) { // str.coder == UTF16
return -1;
}
return StringUTF16.indexOfLatin1(value, str.value);
}
Step2. str(str2)가 빈 배열이거나, value(str1)보다 길이가 긴경우 포함할 수 없음으로 검사 후 indexOfUnsafe를 호출한다.
@IntrinsicCandidate
public static int indexOf(byte[] value, byte[] str) {
if (str.length == 0) {
return 0;
}
if (value.length < str.length) {
return -1;
}
return indexOfUnsafe(value, length(value), str, length(str), 0);
}
Step3. 첫번째 글자가 있는지 확인 후 나머지 문자를 비교한다.
private static int indexOfUnsafe(byte[] value, int valueCount, byte[] str, int strCount, int fromIndex) {
assert fromIndex >= 0;
assert strCount > 0;
assert strCount <= length(str);
assert valueCount >= strCount;
char first = getChar(str, 0);
int max = (valueCount - strCount);
for (int i = fromIndex; i <= max; i++) {
// Look for first character.
if (getChar(value, i) != first) {
while (++i <= max && getChar(value, i) != first);
}
// Found first character, now look at the rest of value
if (i <= max) {
int j = i + 1;
int end = j + strCount - 1;
for (int k = 1; j < end && getChar(value, j) == getChar(str, k); j++, k++);
if (j == end) {
// Found whole string.
return i;
}
}
}
return -1;
}
Q3. 나는 substring으로 같은크기로 잘라내어 equals를 사용하였는데 어떤 순서로 비교되었을까?
A3. equals는 잘라진 문자열 끼리 첫문자부터 끝까지 비교한다. 다른 문자가 보이면 false를 리턴하고 종료된다.
@IntrinsicCandidate
public static boolean equals(byte[] value, byte[] other) {
if (value.length == other.length) {
for (int i = 0; i < value.length; i++) {
if (value[i] != other[i]) {
return false;
}
}
return true;
}
return false;
}