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

삽질 ep.2 (feat. replaceAll)

by 수수남매 2023. 10. 23.
  • 이번엔 입력 String의 부분 문자열 중에 "one", "two", ...이 있으면 "1", "2"...로 변환하는 문제였음
    - ex) input : "2three45sixseven" -> output : "234567"

  • 키, 밸류가 있으니 map을 쓰기로 결정함
  • 정규식으로 숫자와 문자를 구분함
  • 어제 투포인터 알고리즘을 공부했으니 비슷하게 써먹어 보기로 함 (feat. 커피 2잔...)
// 정규식을 이용하여 숫자와 문자를 구분
String[] listS = s.split("(?<=\\D)(?=\\d)|(?<=\\d)(?=\\D)");

// 각 substring이 HashMap의 key와 일치하는지 확인 후 value를 반환
StringBuilder result = new StringBuilder();
for (String str : listS) {
    if (Character.isDigit(str.charAt(0))) {
        result.append(str);
    }
    int sIndex = 0;
    int eIndex = 3; // 모든 키값의 길이가 3이상이므로 초기값을 3으로 설정
    while (eIndex <= str.length()) {
        String substring = str.substring(sIndex, eIndex);
        if (dict.containsKey(substring)) {
            result.append(dict.get(substring));
            sIndex = eIndex;
        } else {
            eIndex++;
        }
    }
}
return Integer.parseInt(result.toString());
  • 분명히 먼가 좋은 방법이 있겠지 하고 다른 사람의 풀이를 봤더니 어제와 비슷하게 str.replaceAll() 메서드를 쓰면 되는 거였음
  • Map도 필요 없었음...
String[] strArr = {"zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine"};
for(int i = 0; i < strArr.length; i++) {
    s = s.replaceAll(strArr[i], Integer.toString(i));
}
return Integer.parseInt(s);
  • replaceAll 공부나 하자!
    - replace vs replaceAll
    - replace는 String을 매개변수로 받아 일치하는 단어를 모두 변환
    - repalceAll은 정규식을 매개변수로 받아 일치하는 패턴의 단어를 모두 변환 (자매품 replaceFirst)
// java.lang.String class의 replace 정의
public String replace(CharSequence target, CharSequence replacement) {
    // 머가 많지만 일반적으로 StringUTF16.replace 호출
    StringUTF16.replace(value, oldChar, newChar);
}
// java.lang.StringUTF16 class의 replace 정의
public static String replace(byte[] value, char oldChar, char newChar) {
    int len = value.length >> 1;
    int i = -1;
    while (++i < len) {
        if (getChar(value, i) == oldChar) {
            break;
        }
    }
    if (i < len) {
        byte[] buf = new byte[value.length];
        for (int j = 0; j < i; j++) {
            putChar(buf, j, getChar(value, j)); // TBD:arraycopy?
        }
        while (i < len) {
            char c = getChar(value, i);
            putChar(buf, i, c == oldChar ? newChar : c);
            i++;
        }
        return new String(buf, UTF16);
    }
    return null;
}
// java.lang.String class의 replaceAll 정의
public String replaceAll(String regex, String replacement) {
    return Pattern.compile(regex).matcher(this).replaceAll(replacement);
}
// java.util.regex.Pattern class의 compile 정의
public static Pattern compile(String regex) {
    return new Pattern(regex, 0);
}
// Pattern 생성자 - 구현 부분만
private Pattern(String p, int f) {
    if (!pattern.isEmpty()) {
        try {
            compile();
        } 
    }
}
// compile 메서드는 너무 길고 어려워서 생략
private void compile() { ~~~ }
// Patten.matcher (Matcher 객체를 생성하기 위해 넣어준 듯)
public Matcher matcher(CharSequence input) {
    Matcher m = new Matcher(this, input);
    return m;
}
// Matcher class 생성자 
Matcher(Pattern parent, CharSequence text) {
    this.parentPattern = parent;
    this.text = text;
    // ~~~ //
}
// Matcher class의 replaceAll 정의
public String replaceAll(String replacement) {
    reset();
    boolean result = find();
    if (result) {
        StringBuilder sb = new StringBuilder();
        do {
            appendReplacement(sb, replacement);
            result = find();
        } while (result);
        appendTail(sb);
        return sb.toString();
    }
    return text.toString();
}