알고리즘🅰/프로그래머스

[프로그래머스] 가운데 글자 가져오기

개발조각 2022. 2. 16. 17:52
728x90
반응형

2021.12.09에 푼 문제입니다.

 

이번 문제는 쉬운 편에 속하는 것 같고
쉬운 대신 어떻게 더 효율적으로 푸는지에 대한 문제인 것 같아요.

 


해결방안

function solution(s) {
    // 버전 1
    return s.length % 2 === 0 ? s.substr(s.length / 2 - 1, 2) : s.substr(parseInt(s.length / 2), 1);
    
    // 버전 2
    return s.substr(Math.ceil(s.length / 2) - 1, s.length % 2 === 0 ? 2 : 1);    
}

이번에는 해결방안 순서가 아닌 버전1,2로 설명해보겠습니다.

  • 버전1. 제가 푼 방식인데 중복되는 코드가 많아서 비추합니다...ㅠ
  • 버전2. 다른 사람 풀이에서 본 방법인데 알아가면 좋을 것 같아서 설명해보겠습니다.

버전 1,2를 설명하기 전에

이 두버전다 삼항 연산자를 사용했는데요.

삼항연산자를 알면 이곳저곳 쓰기 편하니 꼭 알기 바랍니다.!!👍

 

삼항 연산자

구문 : 조건 ? true : false

  • 조건이 true이면 true를 실행
  • 조건이 false이면 false를 실행

 

버전1

// 버전 1
return s.length % 2 === 0 ? s.substr(s.length / 2 - 1, 2) : s.substr(parseInt(s.length / 2), 1);

앞에서도 말했지만 이 방식은 중복 코드가 많아서 비추하지만

여기서 쓴 메서드를 알아가면 좋을 것 같아서 설명해보려고 합니다.

 

이 문제는 단어 s의 가운데 글자를 반환하는 값을 구해야 되는데,

만약 단어의 길이가 짝수라면 가운데 두 글자를 반환해야된다고 합니다.

 

해결방안 순서

  1. 단어 s의 길이가 짝수인지 홀수인지 구하기 -> 조건
  2. 짝수이면 가운데 두 글자 반환, 홀수이면 가운데 한 글자 반환 -> true : false

1단계. 단어 s의 길이가 짝수인지 홀수인지 구하기 -> 조건

 s.length % 2 === 0

  • s.length : 문자열 길이를 나타냅니다.
  • === : ==보다 더 엄격하게 같음을 비교할 때 사용하는 연산자
  • s.length % 2 === 0 : 문자열 길이  / 2를 했을 때 나머지 값이 0인지

 

2단계. 짝수이면 가운데 두글자 반환, 홀수이면 가운데 한글자 반환 -> true : false

s.substr(s.length / 2 - 1, 2) : 짝수
s.substr(parseInt(s.length / 2), 1) : 홀수

 

단어 s에서 가운데 문자를 반환하기 위해서 substr()를 사용하였습니다.

MDN Web Docs
substr() 메서드는 문자열에서 특정 위치에서 시작하여 특정 문자 수만큼의 문자들을 반환합니다.

구문 : str.substr(start[, length])

  • start : 추출하고자 하는 문자들의 시작 위치입니다. 만약 음수가 주어진다면, 문자열 총길이 + start의 값으로 취급합니다. 예를 들면, start에 -3을 설정하면, 자동적으로 문자열총길이 - 3으로 설정하게 됩니다. 
  • length : 옵션 값. 추출할 문자들의 총 숫자.
// substr() 메서드 예제
const str = 'Mozilla';

console.log(str.substr(1, 2)); // "oz"
console.log(str.substr(2)); // "zilla"

가운데 위치를 가져오기 위해 "s.length / 2"를 사용해주었는데요.

짝수, 홀수다 "s.length / 2"를 사용해주면 원하는 값이 안 나옵니다.

그 이유에 대한 설명은 아래 예제를 보시면 이해가 되실 텐데요.

const str1 = 'ABCDEF';
const str2 = 'ABCDE';

//짝수
console.log(str1.substr(str1.length/2, 2)); // "DE"
//홀수
console.log(str2.substr(str2.length/2, 1)); // "C"

이 예제를 보시면 얻고 싶은 답은

  • 짝수에서는 "CD"
  • 홀수에서는 "C"

인데 홀수는 괜찮은 답이 나왔지만 짝수에서는 다른 답이 나왔습니다.

 

이렇게 된 이유는 substr() 메서드의 시작 자리는 0부터 시작을 해서 그렇습니다.

그래서 짝수에서는 substr() 메서드의 시작 자리에는 "s.length / 2 - 1"을 넣어주어야 됩니다.

 

그리고 여기서 알아가면 좋은 게 홀수를 "s.length / 2"해주면 소수점이 나오잖아요?

위에 설명했던 예시로 설명하자면

  • const str2 = 'ABCDE';
  • str2.length/2 = 5/2 = 2.5

이 됩니다.

여기서 2.5에서 소수점이 빠지고 2만 적용하게 됩니다.

그래서 홀수는 s.length / 2만 써도 가능합니다.

 

그래도 나는 소수점으로 남기는 건 싫다 하면

이때 사용하는 것이 parseInt() 함수를 사용하면 됩니다.

MDN Web Docs
parseInt() 함수는 문자열 인자를 파싱 하여 특정 진수(수의 진법 체계에서 기준이 되는 값)의 정수를 반환합니다.

구문

parseInt(string)

parseInt(string, radix)

  • string : 파싱 할 값입니다. 문자열이 아닐 경우 ToString 추상 연산을 사용해 문자열로 변환합니다. 문자열의 선행 공백은 무시합니다.
  • radix Optional : string의 진수를 나타내는 2부터 36까지의 정수입니다. 주의하세요. 기본 값이 10이 아닙니다! Number 자료형이 아닌 경우 Number로 변환합니다.

그동안 프로그래머스 해결방안 설명에서는

  • parseInt() : 2~36 사이의 진법을 10진법으로 바꿀 때 사용

한다고 했었습니다.

그렇지만 이번에는 소수를 정수로 반환할 때 사용하겠습니다.

  • parseInt( str2.length/2 ) = 5/2 = 2.5 -> 2

 

 

버전 2

// 버전 2
return s.substr(Math.ceil(s.length / 2) - 1, s.length % 2 === 0 ? 2 : 1);

이 버전은 다른 사람 풀이에서 봤던 방법인데요.

앞에서 설명했던 버전1에서는 s단어의 문자열 길이가 홀수, 짝수에 따라 각각의 substr()메서드를 써주었는데요.

 

// 버전 1

return s.length % 2 === 0 ? s.substr(s.length / 2 - 1, 2) : s.substr(parseInt(s.length / 2), 1);

이렇게 버전 1에서는 substr()메서드를 두번 써주었습니다.

 

이걸 다르게 생각해보면 substr()메서드 안에

  • substr(시작자리, 추출할 문자들의 길이)

이라고 하면 

  • 시작자리 : 홀수, 짝수 위치 지정
  • 추출할 문자들의 총 숫자 : s문자열길이가 홀수이면 1, 짝수이면 2을 반환하는 조건문

을 써주면 됩니다.

 

해결방안 순서

  1. substr()메서드의 시작자리 구하기
  2. substr()메서드의 추출할 문자들의 총 숫자 구하기

 

1단계. substr()메서드의 시작자리 구하기

substr(시작자리, 추출할 문자들의 길이)

Math.ceil(s.length / 2) - 1

 

버전1에서는

  • 짝수면 s.substr(s.length / 2 - 1, 2)
  • 홀수면 s.substr(parseInt(s.length / 2), 1)

이라고 했습니다.

여기서 substr()메서드의 시작자리를 보시면

s.length / 2까지는 같은데 짝수일때만 -1를 붙입니다.

이렇게 시작자리를 다르게 쓰지 말고 똑같이 쓸 방법이 없을까?

그래서 나온 해결방법이 Math.ceil()을 사용하는 겁니다.

MDN Web Docs
Math.ceil() 함수는 주어진 숫자보다 크거나 같은 숫자 중 가장 작은 숫자를 integer 로 반환합니다.

문법 : Math.ceil(x)

  • x : 숫자
Math.ceil(.95);    // 1
Math.ceil(4);      // 4
Math.ceil(7.004);  // 8
Math.ceil(-0.95);  // -0
Math.ceil(-4);     // -4
Math.ceil(-7.004); // -7

예제를 보시면 알겠지만 Math.ceil() 함수는 반올림을 해주는 함수입니다.

 

반올림을 사용하는 이유에 대해 설명을 한다면

  • 짝수 / 2  = 정수
  • 홀수 / 2 = 정수. 5

이와같이, 홀수 / 2를 하면 무조건. 5가 나옵니다.

홀수 / 2를 반올림하면 소수점 첫째자리가 5이기 때문에 무조건 올림이 됩니다.

  • 홀수 / 2 = 정수. 5 -> 반올림하면 정수 + 1

그래서 짝수가 되든 홀수가 되든 s.length / 2를 하면 같은 수가 나오게 만들어주었습니다.

 

이 말이 이해가 잘 안 되시면 예제로 설명하자면

짝수

  • const str1 = 'ABCDEF'; -> "CD"가 나와야 됨으로 시작 자리가 2가 나와야 됨
  • substr(Math.ceil(str1.length / 2) - 1, 2);
    • Math.ceil(s.length / 2) - 1 -> Math.ceil(6 / 2) - 1 -> Math.ceil(3) - 1 -> 3 - 1 = 2

=> substr(

2

, 2); = "CD"

 

홀수

  • const str2 = 'ABCDE'; -> "C"가 나와야 됨으로 시작 자리가 2가 나와야 됨
  • substr(Math.ceil(str1.length / 2) - 1, 2);
    • Math.ceil(s.length / 2) - 1 -> Math.ceil(5 / 2) - 1 -> Math.ceil(2.5) - 1 -> 3 - 1 = 2

=> substr(2, 2); = "C"

 

 

2단계. substr()메서드의 추출할 문자들의 총 숫자 구하기

substr(시작자리, 추출할 문자들의 길이)

s.length % 2 === 0 ? 2 : 1

 

substr()메서드의 추출할 문자들의 총길이를 구해야 되는 돼요.

짝수일 경우 2, 홀수일 경우 1로 구해야 돼서 삼항 연산자를 활용해서 구해주었습니다.


여기까지 프로그래머스 가운데 글자 가져오기 해결방안에 대해 설명해보았습니다.

728x90
반응형