띠오니 개발자 성장일지
article thumbnail
반응형

인프런의 "자바(Java) 알고리즘 문제풀이 : 코딩테스트 대비" 강좌를 수강했습니다.

 


 

Q1-03. 문장 속 단어

영어 알파벳으로 이루어진 한 개의 문장이 주어지면, 그 문장 중 가장 긴 단어를 출력하는 문제.
문장은 공백으로 구분되어 있다.
길이가 가장 긴 단어가 여러 개 있다면, 앞에 위치한 단어를 출력한다.

 

 

✏️ 내가 쓴 답

가장 긴 단어의 길이를 저장할 max 변수를 0으로 초기화한다.

문자열 str을 split(" ") 메소드를 이용해 공백(" ")을 기준으로 잘라준다. 문자열 배열(String[])이 return 되므로 반복문 사용 가능

한 단어 word의 길이를 나타내는 len과 max를 비교해, 더 긴 것의 크기는 max 값에 대입하고 answer 변수에 가장 긴 단어를 저장한다.

가장 큰 정수값, 가장 작은 정수값 구하는 방식과 똑같다.

이렇게 돌려보니 정답!✅😊

import java.util.Scanner;

public class Main {
	public String solution(String str) {
    	String answer = "";
        
        int max = 0;
        
        for(String word : str.split(" ")){
        	int len = word.length();
        	if(len > max){
            	max = len;
                answer = word;
            }
        }
        
        return answer;
    }

    public static void main(String[] args){
        Main main = new Main();

        Scanner sc = new Scanner(System.in);
        String str = sc.nextLine();

        System.out.println(main.solution(str));
    }
}

 

반응형

 

 

💪🏻 보완하고 싶은 점

이번에 잘 푼 것 같은데 🧐 다른 방법도 있을까 ?!!

 

 

👨🏻‍🏫 수정한 코드

첫 번째 방법

이 방법은 나랑 똑같은 방법이다!

다만 하나 달랐던 것은 단어의 길이를 저장할 m 변수의 초기값이었는데, 쌤은 Integer.MIN_VALUE 로 저장하셨다.

Integer 범위(–2,147,483,648 ~ 2,147,483,647) 중 최소값인 –2,147,483,648 로 지정하는 것이었다.

다른 분이 0과 Integer.MIN_VALUE로 초기화 하는 게 차이가 있냐는 질문이었는데, 이 문제는 음수를 다루지 않아서 0으로 초기화 해도 상관 없다고 하셨다. 아마 음수까지 다루는 문제가 있다면 이렇게 초기화 하면 좋을 듯 하다!

또 주의할 점은 10번 째 줄 len > m  부분이 len >= m 이렇게 되면 안된다. 이러면 같은 길이의 가장 긴 단어 중 뒤에 오는 단어가 저장되어 버리므로, 문제 의도와 달라져버릴 수 있음을 주의하자.

public String solution(String str){
	String answer = "";
    
    int m = Integer.MIN_VALUE;
    
    String[] s = str.split(" ");
    
    for(String x : s) {
    	int len = x.length();
        if(len > m) {
        	m = len;
            answer = x;
        }
    }
    
    return answer;
}

 

두 번째 방법

indexOf()와 substring() 을 이용하는 방법!

공백의 위치를 찾아서 문장을 잘라가는 식으로 진행한다.

substring(int n) : 0~n 번째 이후의 단어만 나타나도록 자른다.

substring(int beginIndex, int endIndex) : beginIndex 부터 endIndex 전 위치까지 자른다. 

(8째 줄) while문에서 문장에서 indexOf()로 공백의 위치를 받는다.

(9째 줄) 변수 tmp에는 0번째부터 공백이 있는 곳까지, 즉 한 단어를 저장하고

(12~15째 줄) 위 답변과 똑같이 길이비교를 통해 단어가 answer에 저장된다.

(17째 줄) 길이비교를 끝냈으면, 문자열 중에 이미 비교를 끝낸 앞의 단어를 잘라낸다. it is time to sleep 중 첫번째 비교 후 이 문장을 통해 is time to sleep, 두번 째 비교 후 time to sleep 이런식으로 앞 단어가 잘려나간다.
그래서 while문이 계속 될 때마다 (9째 줄)에서는, 이미 비교된 단어는 잘려나간 문장의 새로 비교할 단어는 0번째 인덱스부터 시작하게 된다.

(19째 줄) while문을 반복하다 보면 마지막 sleep 단어만 남았을 땐, 공백이 존재하지 않아 while 조건문은 -1이 되어 while문을 빠져나오게 된다. 그럼 sleep 단어는 길이 비교를 하지 못하기 때문에, while 문이 끝난 후 별도로 if문을 통해 길이비교를 한다. 

 

while문에 익숙하지 않은 나로서는 일단 for문부터 생각하고 보는데.. 신기한 풀이방식이었다!

public String solution(String str) {
	String answer = "";
    
    int m = Integer.MIN_VALUE;
    int pos;
    
    
    while((pos=str.indexOf(" ")) != -1){			// pos=문자열 중 공백의 포지션 ex)it is time to sleep
    	String tmp = str.substring(0, pos);			// 문자열의 처음부터 공백 이전의 알파벳까지를 한 단어로서 tmp에 저장 ex)it
        int len = tmp.length();						// tmp 단어의 길이 저장 
        
        if(len > m){
        	m = len;
            answer = tmp;
        }
        
        str = str.substring(pos+1);					// 공백 위치의 다음 위치(pos+1)부터 문자열이 다시 시작하도록 자름 ex)is time to sleep
    }
    if(str.length() > m) answer = str;				// 마지막 단어만 남았을 때 while문에서 벗어나 길이비교가 불가능해지므로 이 줄에서 한번 더 비교 함
    
    
    
    return answer;
}

 

 

 

🤓 정리

  • split(String regex) 함수로 특정문자 기준으로 자른 문자열 배열을 얻을 수 있다.
  • 정수형 변수를 정수 범위 내 최소, 최대값으로 초기화 할 수 있다. Integer.MIN_VALUE, Integer.MAX_VALUE 
  • substring()으로 문자열을 자를 수 있다.  substring(int n)은 n번째 인덱스 이후로 출력, substring(int a, int b)은 a번째 인덱스부터 b-1번째 인덱스까지 출력한다.

 

 

 


 

원래부터 알고리즘 풀이 스펙트럼이 워낙 좁은 것도 있었지만.. 쉬운 문제에서도 풀 수 있는 방법이 여러가지가 될 수 있는 게 재미있었다.

꾸준히 더 진행해보도록 하자. ^^

반응형
profile

띠오니 개발자 성장일지

@띠오니

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!