본문 바로가기
알고리즘

자바 - 프로그래머스 - 숫자 문자열과 영단어

by Won's log 2024. 4. 4.

숫자 문자열과 영단어 

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

 

문제와 예시

 

🤨 구현한 코드 (복잡한 로그 주의⛔️)

처음 문제를 보았을 때, 먼저 떠오른 생각은 영문자를 숫자로 인식해서 바꿔주면 되겠지였다. 분명 자바의 내장 함수가 있었는데 기억이 안 나서 20분 정도 이것저것 끙끙 시도해 보다가 string의 replace()를 깨달았다. 나란 사람.. 기본 함수는 외우자 😂

 

그렇게 해서 완성된 코드..

class Solution {
    public int solution(String s) {
    
        s = s.replace("zero", "0");
        s = s.replace("one", "1");
        s = s.replace("two", "2");
        s = s.replace("three", "3");
        s = s.replace("four", "4");
        s = s.replace("five", "5");
        s = s.replace("six", "6");
        s = s.replace("seven", "7");
        s = s.replace("eight", "8");
        s = s.replace("nine", "9");
        
        return Integer.parseInt(s);
    }
}

이 얼마나 부끄러운 코드인가! 최종의 노가다로 완성한.. 누가 봐도 생각 안 하고 만든 코드! 그래서 리팩토링을 바로 들어갔다.

 

😎 수정된 코드

class Solution {
    public int solution(String s) {
    
        String[] numArr = {"zero","one","two","three","four","five","six","seven","eight","nine"};
        for (int i=0; i<numArr.length; i++) {
            if(s.contains(numArr[i])) {
                s = s.replace(numArr[i], String.valueOf(i));
            }
        }
        return Integer.parseInt(s);
    }
}

 

영문자는 내장함수로 담겨있는 것이 없는 듯하여 아쉽지만 직접 0-9까지 배열에 담았다. -> 효율적인 방법이 필요하다.

if문을 사용하여 s가 숫자만 구성되어있는 문자인지 우선 확인 후, 문자가 들어있다면 for문을 돌려 처음 작성한 코드와 동일하게 replace해주는 방식을 선택했다. 

 

😳 다른 사람의 풀이

class Solution {
    public int solution(String s) {
        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() 함수를 사용한 것이 차이가 있다. 

 

찾아보니, Java에서 `replaceAll()`과 `replace()`는 문자열 내에서 특정 패턴을 다른 패턴으로 대체하는 데 사용되는 메서드이지만 두 메서드 간에는 몇 가지 중요한 차이가 있다고 한다.

1. 정규 표현식 사용 여부:
    - `replaceAll()`: 정규 표현식을 사용하여 문자열 내의 모든 일치 항목을 대체한다.
    - `replace()`: 일반적인 문자열 대체를 수행하며, 정규 표현식을 사용하지 않는다.

2. 대체 범위:
    - `replaceAll()`: 문자열 내의 모든 일치 항목을 대체한다.
    - `replace()`: 첫 번째로 발견된 일치 항목만 대체한다.

3. 성능:
    - `replace()`: 정규 표현식을 사용하지 않으므로 일반적으로 더 빠르다.
    - `replaceAll()`: 정규 표현식을 사용하므로 처리 속도가 느릴 수 있다.

 

예를 들자면, 

String text = "apple, banana, orange, BaNaNa";
이 문자열에서 banana를 grape로 대체하고 싶다고 가정해보자.

replace()를 사용한 경우:
String result = text.replace("banana", "grape");
System.out.println(result); // 출력: apple, grape, orange, BaNaNa

replaceAll()을 사용한 경우:
String result = text.replaceAll("banana", "grape");
System.out.println(result); // 출력: apple, grape, orange, grape
위의 예시에서 replace() 메소드는 대소문자를 구분하여 대체하지 않는다. 하지만 replaceAll() 메소드는 정규 표현식을 사용하므로 대소문자를 구분하여 대체한다.

 

배운 점

1. 노가다 코드를 만들 거면 한 번 더 생각하고 만들자. 시간 아깝다. 실무에서는 노가다 코드 만들면 눈총 받을 거다. 정신 차리자^^..

2. `replaceAll()`을 사용할 때는 정규 표현식이 적용되므로 특수한 경우에는 조심해야 하니 만약 일반 문자열 대체가 필요하다면 `replace()`를 사용하는 것이 좋을 것 같다.