본문 바로가기

Algorithm

[알고리즘] #21 이상한 문자 만들기 | 프로그래머스 | 테스트 실패 원인 (공백)

728x90

프로그래머스 이상한 문자 만들기 알고리즘 문제이다.

 

https://programmers.co.kr/learn/courses/30/lessons/12930

 

코딩테스트 연습 - 이상한 문자 만들기

문자열 s는 한 개 이상의 단어로 구성되어 있습니다. 각 단어는 하나 이상의 공백문자로 구분되어 있습니다. 각 단어의 짝수번째 알파벳은 대문자로, 홀수번째 알파벳은 소문자로 바꾼 문자열을

programmers.co.kr

 

 

 

 


 

 

문제 설명

 

문자열 s는 한 개 이상의 단어로 구성되어 있습니다. 각 단어는 하나 이상의 공백문자로 구분되어 있습니다. 각 단어의 짝수번째 알파벳은 대문자로, 홀수번째 알파벳은 소문자로 바꾼 문자열을 리턴하는 함수, solution을 완성하세요.

 

 

제한 사항
 
  • 문자열 전체의 짝/홀수 인덱스가 아니라, 단어(공백을 기준)별로 짝/홀수 인덱스를 판단해야합니다.
  • 첫 번째 글자는 0번째 인덱스로 보아 짝수번째 알파벳으로 처리해야 합니다.

 

입출력 예

 

 

 

 


 

테스트 케이스 실패

코드 실행까지는 통과하는데 채점하기에서 테스트 통과를 못한다.

 

let s = "try hello world";

solution(s);

function solution(s) {
  let answer = '';
  let arr = s.split(' ');

  for(let i = 0; i < arr.length; i++){
    let newarr = arr[i].split('');
    newarr.push(' ');
    
    let prac = newarr.reduce((acc, cur, index, arr) => {
      if (index % 2 === 0){
        cur = cur.toUpperCase();
      } else {
        cur = cur.toLowerCase();
      }
      answer += (cur);
    }, 0);
  };
  answer = answer.trim();
  return "" + answer + ""
}

 

 

 

 

 

 

 


 

 

 

< 문제 풀이 >

 

코드 한 줄 수정하니까 갑자기 모든 테스트를 통과했다. 이 한 줄로 하루가 갔지만 해결하게 되어 기쁘다.

 

문자열 s는 한 개 이상의 단어로 구성되어 있습니다. 각 단어는 하나 이상의 공백문자로 구분되어 있습니다. 각 단어의 짝수번째 알파벳은 대문자로, 홀수번째 알파벳은 소문자로 바꾼 문자열을 리턴하는 함수, solution을 완성하세요.
function solution(s) {

	// 답 저장 변수
    let answer = '';
    
    // s파라미터로 가져온 문자는 "try hello world" 
    // 문자를 공백을 기준으로 나눠서 배열에 담는다.
    // [] [] [] 담긴 모양
    // 배열로 담아서 인덱스로 홀짝을 검사하려고 한다.
    let arr = s.split(' ');

    for(let i = 0; i < arr.length; i++){
    	// [] [] [] 안에서도 ['t,' 'r', 'y']로 나눠준다.
        let newarr = arr[i].split('');
        // 나중에 더할 떄 try hello로 중간에 공백이 필요함으로 공백을 배열에 넣어준다.
        newarr.push(' ');

		// index 값을 이용하려고 reduce를 사용했다.
        let prac = newarr.reduce((acc, cur, index, arr) => {
       		//index가 짝수면 대문자, 홀수면 소문자
            if ( index % 2 === 0){
            	// 해당 조건에 맞는 배열의 현재 엘리먼트를 바꿔준다.
                cur = cur.toUpperCase();
            } else {
                cur = cur.toLowerCase();
            }
            // 문자로 선언해놓은 answer변수에 반복적으로 넣어준다.
            answer += (cur);
        }, 0);
    };
	
    // 아까 공백을 추가했었는데 맨 마지막 자리는 필요없으니까 빼준다.
    answer = answer.slice(0, -1);
    // ""를 앞뒤로 추가해준다.
    return "" + answer + "";
}

 

위에서 문제는 공백이 문제였다. 마지막에 공백을 삭제할 때 answer = answer.trim(); 를 사용했는데, trim()은 맨 앞과 맨 뒤의 공백을 없애주는 메소드이다. 그런데 여기 코드에서쓴 slice(0, -1)은 맨 뒤에서부터 한 개의 공백만 없애준다. 애초에 trim()을 썼던 것도 맨 뒤만 없애고는 싶은데 맨 앞과 맨 뒤의 공백 둘다 없어도 될 것 같다는 생각이어서 사용했던 것인데 이게 문제일 줄은 몰랐다. 이게 테스트 실패로 오류났던게 몇몇 테스트에서는 맨 앞 공백 삭제 문제로 무슨 다른 일이 벌어지는 것 같다. 앞으로 slice를 떠올리고 잘 사용해야겠다.

 

 

 


 

 

다른 사람들은 어떻게 풀었을까?

 

https://programmers.co.kr/learn/courses/30/lessons/12930/solution_groups?language=javascript&type=all 

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

 

 

 

array.map( function(currentValue, index, arr), thisValue)
Parameter Description
function() Required.
A function to be run for each array element.
currentValue Required.
The value of the current element.
index Optional.
The index of the current element.
arr Optional.
The array of the current element.
thisValue Optional.
Default value undefined.
A value passed to the function to be used as its this value.

 

function toWeirdCase(s){
  return s.split(' ').map(i => i.split('').map((j, key) => key % 2 === 0 ? j.toUpperCase() : j).join('')).join(' ')
}

console.log("결과 : " + toWeirdCase("try hello world"));

 

문자열 [] [] []로 나누기. map으로 문자열 엘리먼트 전체를 훑는다. []안에 있는 문자열 까지도 다 나눠준다. 그 다음 또 map을 사용한다. 이때는 파라미터값으로 현재 엘리먼트 값과, index값을 가져온다. 그리고 index가 짝수일 경우에는 엘리먼트를 대문자로 바꿔주고 홀수인 경우에는 소문자로 바꿔준다. 그리고 나서 완성된 s 배열을 join()을 사용해 배열안의 모든 문자열을 연결해준다.

 

 

 

 

 

 

참고

https://www.w3schools.com/jsref/jsref_map.asp

728x90