본문 바로가기

별걸다하는 IT/알고리즘 문제풀이

[프로그래머스 알고리즘 1단계 문제] 수박수박수박수? 풀이 해설

오늘도 어김없이 가장 낮은 Level 1단계부터 끝단계까지 언젠가 다 포스팅을 차곡차곡하리라 다짐하면서..

 

[프로그래머스 알고리즘 - Level 1]

수박수박수박수박수? 풀이 및 설명

문제

길이가 n이고, "수박수박수박수...."와 같은 패턴을 유지하는 문자열을 리턴하는 함수, solution을 완성하세요. 예를 들어 n이 4이면 "수박수박"을 리턴하고 3이라면 "수박수"를 리턴하면 됩니다.

제한조건

n은 길이 10,000이하인 자연수입니다.

입출력 예

n return
3 "수박수"
4 "수박수박"

기본 제공 틀

[Java]

class Solution{
    public String solution(int n){
        String answer="";
        return answer;
    }
}

[C++]

#include <string>
#include <vector>
using namespace std;
string solution(int n){
    string answer ="";
    return answer;
}

 

문제 풀이

문제만 봐도 풀 수 있는 방법이 많을 거라는 느낌을 퐝퐝 풍기네요 ㅎㅎ

 

규칙을 먼저 보면 "수박"이 반복된다는 것을 알 수 있어요

"수" & "박" 이 반복된다고 생각하면 "수" "박" "수" "박" 번갈아가며 찍어주면 되니까 반복문을 이용해서 푸는 가장 간단한 방법이 먼저 있겠네요 

 

그 다음으로 

"수박"이 반복적으로 나타난다고 판단할 수 있어요. 이럴 경우 n이 홀수라면 "수박수" 처럼 뒤에 짝지어지지 않은 "수"가 하나 오니까 if문을 사용해서 짝순지 아닌지 판별해서 문제를 해결할 수도 있겠네요!

 

[Java]

맨날 C, C++먼저 풀이 했으니까 오늘은 Java로 먼저 풀이해볼까요?!

수, 박, 수, 박 번갈아 일어나니까 홀수 자리일 때는 "수", 짝수 자리일 때는 "박"

class Solution{
    public String solution(int n){
        String answer="";
        for(int i=1; i<=n; i++){
            if(i%2!=0)
                answer+="수";
            else
                answer+="박";
        }
        return answer;
    }
}

얘를 삼항 연산자로 정리해 코드길이를 줄일 수 있겠죠? 사실 저는 코드길이 짧은걸 좋아해서 삼항연산자를 좋아해요 ㅎㅎ

class Solution{
    public String solution(int n){
        String answer="";
        for(int i=1; i<=n; i++)
            answer += (i%2!=0)? "수": "박";
        return answer;
    }
}

그 다음은 "수박"을 기준으로 가봅시다. 짝수일 때는 "수박"의 반복만 이루어지니까 신경쓸 필요 없지만 홀수일 경우는 "수"를 추가해줘야겠죠?

public String solution(int n) {
      String answer = "";
      for(int i = 0; i<(n/2); i++)
          answer += "수박";
      if(n %2 != 0)
        answer += "수";
      return answer;
}

이렇게 문자를 추가해줄 수도 있고 마지막에서 "박"을 빼줄수도 있는데 JAVA의 String 클래스의 경우 마지막 문자만 제거해주는 메소드는 없어요 ㅎㅎ 구현할 때는 substring(0, answer.length()-1)을 사용해서 맨 마지막 문자를 제외한 문자열을 추출하는 식으로 해결해주면 됩니다. ㅎㅎ 

 

항상 맞추고 다른 풀이에서 배울점이 있나 보는 편인데 매번 볼때마다 감탄하는 ㅋㅋㅋㅋㅋㅋㅋㅎㅎㅎ

정말 대단해요..ㅎㅎ 이렇게 노가다(?) 도 하나의 방법이 될 수는 있지만 그래도 지양하도록 합시다 ㅎㅎ 

그래도 시간들여서 맞추고자 하는 열정은 짝짝

이렇게 풀 생각은 못했는데 ㅎㅎ 이런 풀이도 있네요! 

사실 +=로 문자열을 채우는 것은 딱 코드만 봐도 어떤 의민지 이해하기 쉽기 때문에 좋지만

문자열을 결합할 때마다 새로운 문자열을 가진 String 인스턴스가 생성되어 메모리 공간을 차지해서 반복이 많을 수록 좋은 방법은 아닙니다. ㅎㅎ 아래는 replace로 대체함으로써 반복문을 싹 없앴네요 ㅎㅎ

하지만 가독성이 좋지 않아서 매우 좋은 풀이다라고는 음... 적절히 혼용하는게 좋을듯? (개인적인 생각)

class Solution{
    public String solution(int n){
        return new String(new char [n/2+1]).replace("\0", "수박").substring(0,n);
    }
}

 

풀이를 좀 해드리자면

new String(new char [n/2+1])은 먼저

char [] cArr = new char[n/2+1]; --> 길이가 n/2+1인 문자 배열을 생성

String s = new String(cArr); -->cArr을 갖는 String 인스턴스 생성

이 두 문장을 합친거라 생각하시면 이해하기가 좀 더 편해요 

 

또 자바는 char 의 default 값이 '\u0000'이라고 되어있는데 '\u0000'은 유니코드의 첫 번째 문자로 아무런 문자도 지정되지 않은 빈 문자 NULL이라는 뜻입니다. (== '\0')

String 초기화를 char배열로 해줘서 각각 자리에 널이 들어가요 

그래서 replace("\0", "수박")하면

매 자리를 "수박"이라는 걸로 바꿔라! 가 되는거죠 

 

즉 만약 3자리 문자열이면 "수박수박수박"으로 바뀌는거~!

"수박수"가 될 수도 있으니 일단 "수박"의 반복문 형태로 맞춰놓고 substring 메소드로 잘라내서 리턴하고 있네요 ㅎㅎ 다 이해되셨나요? 

 

 

[C++]

이제 C++로 넘어가볼게요. C는 자바랑 다르게 마지막 문자열을 지울 수 있어요. '[]'를 사용해서 index로 값에 접근할 수도 있고요. ㅎㅎ C++ 클래스 특성을 살려서 append함수를 사용해 작성해봅시다.

 

일단 자바에서 했던 것처럼 똑같이 이렇게 삼항연산자를 해도 됩니다. 

string solution(int n)
{
    string answer="";
    for(int i=1; i<=n; i++)
        answer += i%2!=0? "수":"박";
    return answer;
}

글치만 이번엔 좀 더 다른 코드로 바꿔볼까요? 핵심은 짝수인지 홀수인지 가리는 거잖아요 

짝수 홀수 구별하는 방법을 좀 더 Low level로 내려가서 풀어봅시다. ㅎㅎ

논리회로에서 배웠던 and랑 or, xor 기억나나요? and는 둘 다 1일 경우만 1이기 때문에 짝수홀수 구별에 사용할 수 있습니다. 1, 3,5,7..등등 홀수는 2진법으로 나타내면 맨 뒤에가 1이 되기 때문이예요. 001, 011, 111.... & 001 -->무조건 1 !

즉 이렇게 풀어서 사용할 수도 있습니다.

string solution(int n)
{
    string answer="";
    for(int i=1; i<=n; i++)
        answer += i&1? "박": "수"; 
    return answer;
}

참고로 xor은 두 수를 교환할 때 자주 사용합니다. 

 

더 좋은 풀이가 있다면 공유해주세요 :)