[Java] 프로그래머스 2021 카카오 채용연계형 인턴십 > 숫자 문자열과 영단어 with 자바

: ) YOUNG·2022년 4월 25일
2

알고리즘

목록 보기
112/422
post-thumbnail

문제

https://programmers.co.kr/learn/courses/30/lessons/81301?language=java


네오와 프로도가 숫자놀이를 하고 있습니다. 네오가 프로도에게 숫자를 건넬 때 일부 자릿수를 영단어로 바꾼 카드를 건네주면 프로도는 원래 숫자를 찾는 게임입니다.

다음은 숫자의 일부 자릿수를 영단어로 바꾸는 예시입니다.

  • 1478 → "one4seveneight"
  • 234567 → "23four5six7"
  • 10203 → "1zerotwozero3"

이렇게 숫자의 일부 자릿수가 영단어로 바뀌어졌거나, 혹은 바뀌지 않고 그대로인 문자열 s가 매개변수로 주어집니다. s가 의미하는 원래 숫자를 return 하도록 solution 함수를 완성해주세요.

참고로 각 숫자에 대응되는 영단어는 다음 표와 같습니다.

숫자영단어
0zero
1one
2two
3three
4four
5five
6six
7seven
8eight
9nine

생각하기

오랜만에 프로그래머스 문제를 풀었다.
시간과 메모리가 제공되지 않기때문에 테스트케이스를 통해서 파악해야 한다.

하지만 난이도1의 문제니까 당연히 어렵지 않을꺼라고 판단.
또한 문자열을 하나하나 구분해야 하므로 부르트포스 방법을 사용하기로 했다.

동작

	StringBuilder number = new StringBuilder();
    	int len = s.length();

    	for(int i=0; i<len; i++) {
    		char ch = s.charAt(i);
            
    		if(ch >= 48 && ch <= 57) {
    			sb.append(ch);
    		}
    		// 문자가 숫자가 아니라 알파벳일 경우  
    		else {
    			number.append(ch);
    		}

    		if(number.length() >= 3) {
    			String str = number.toString();
    			if(check(str)) {
    				find(str);
    				number = new StringBuilder();
    			}
    			else {
    				continue;
    			}

    		}

동작은 아스키코드만 떠 올린다면 간단하다.
먼저 문자열을 하나로 분리해서 검사한다 첫번째 검사는 문자열을 아스키코드와 비교해서

if(ch >= 48 && ch <= 57) { 해당 범위에 들어가는지 체크한다.
이 범위에 들어간다는 것은 숫자를 의미하므로 해당 범위에 들어가면 결과문자열을 만들어줄 StringBuilder sb 에 바로 append해주고,

숫자가 아닐경우, 숫자 영어로 비교하기위해 문자열로 만들어줄 StringBuilder number에 append해준다.

여기서 StrinBuilder를 쓰는 이유는
문자열연산은 기본적으로 Immutability(불변성)의 특성을 가지고 있기때문에 BufferedWriter나 StringBuilder를 사용해서 문자열 연산을 하는게 좋다

그리고 number의 길이기 3이상이 되면 다시 검사를 한다.

우리가 찾는 숫자영어의 길이들이 3 ~ 5 크기 이기 때문이다.
길이가 3이상이되면 check 메소드를 실행시켜서

숫자영어 배열에 포함되어 있는지 검사하고 만약 들어가 있을경우는 true를 반환하고, 아니면 false를 반환한다.

여기서 true일 경우, 결과값에 연결해주면되고,
false일 경우, 다시 number에 문자를 연결시켜서 계속 찾아주면된다.

이번 문제는 아스키코드와 길이가 힌트지 않을까 생각해본다.



코드


import java.util.*;

class Solution {
	static StringBuilder sb = new StringBuilder();
	static List<Character> list = new ArrayList<>();
	static String num[] = {"zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine"};

   public int solution(String s) {
    	StringBuilder number = new StringBuilder();
    	int len = s.length();

    	for(int i=0; i<len; i++) {
    		char ch = s.charAt(i);

    		// 문자가 숫자일 경우 그대로 StringBuilder에 연결
    		if(ch >= 48 && ch <= 57) {
    			sb.append(ch);
    		}
    		// 문자가 숫자가 아니라 알파벳일 경우  
    		else {
    			number.append(ch);
    		}

    		// 숫자를 의미하는 문자의 최소길이는 3이고 최대길이는 5이다.
    		// 그러므로 숫자의 문자길이가 3이상일 경우, 검사를 함.
    		// 검사결과가 false일 경우, 다시 문자열에 요소를 하나 넣고 또 검사를 하면서 
    		// 반복해서 계속 문자열이 숫자영어와 일치하는지 검사를 함
    		if(number.length() >= 3) {
    			String str = number.toString();
    			if(check(str)) {
    				find(str);
    				number = new StringBuilder();
    			}
    			else {
    				continue;
    			}

    		}

    	}

    	int result = Integer.parseInt(sb.toString());
        return result;
    } // End of solution

    static boolean check(String str) {

    	for(int i=0; i<10; i++) {
    		String number = num[i];

    		if(str.contains(number)) {
    			return true;
    		}

    	}

    	return false;
    } // End of check

    static void find(String str) {

    	switch(str) {
    		case "zero": sb.append("0");
    		break;
    		case "one": sb.append("1");
    		break;
    		case "two": sb.append("2");
    		break;
    		case "three": sb.append("3");
    		break;
    		case "four": sb.append("4");
    		break;
    		case "five": sb.append("5");
    		break;
    		case "six": sb.append("6");
    		break;
    		case "seven": sb.append("7");
    		break;
    		case "eight": sb.append("8");
    		break;
    		case "nine": sb.append("9");
    		break;
    	}

    } // End of find;
} // End of Main class

0개의 댓글