[프로그래머스] 가운데 글자 가져오기
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의 가운데 글자를 반환하는 값을 구해야 되는데,
만약 단어의 길이가 짝수라면 가운데 두 글자를 반환해야된다고 합니다.
해결방안 순서
- 단어 s의 길이가 짝수인지 홀수인지 구하기 -> 조건
- 짝수이면 가운데 두 글자 반환, 홀수이면 가운데 한 글자 반환 -> 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을 반환하는 조건문
을 써주면 됩니다.
해결방안 순서
- substr()메서드의 시작자리 구하기
- 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로 구해야 돼서 삼항 연산자를 활용해서 구해주었습니다.
여기까지 프로그래머스 가운데 글자 가져오기 해결방안에 대해 설명해보았습니다.