본문 바로가기

프로그래밍/Javascript 알고리즘 문제

Javascript 알고리즘 문제 - 17번부터 28번까지

17. 문자열 다루기 기본


나의 풀이(코드 실행은 되는데, 제출 후 채점하면 정확성이 87.5)

function solution(s){
    // 1. 문자열 s의 길이가 4 또는 6인지 검사
    // 2. 문자열 s에 숫자가 아닌 값이 하나라도 있는지 검사 
    
    let num = 0;
    
    /* 1. 문자열 s의 길이가 4 또는 6이면 문자열 s의 내용 확인. */
    if(s.length == 4||6){ 
        /* 2. 문자열 s에 숫자가 아닌 값이 하나라도 있는지 검사 */
        for(let i=0; i<s.length; i++){ // s[0~3] 아니면 s[0~5]일 동안
            if(s[i]==0 || s[i]==1 || s[i]==2 || s[i]==3 || s[i]==4 
               || s[i]==5 || s[i]==6 || s[i]==7 || s[i]==8 || s[i] == 9){ 
            // s의 i번째 값이 0~9 중 하나라도 있다면
                num++; // s의 값 중 숫자인 값의 개수만큼 Num 증가
            }
        }
    } else{ /* 1. 문자열 s의 길이가 4 또는 6이 아니면 문자열 s의 내용을 확인하지 않고 바로 false 리턴. */
        return false;
    }
    
    // 문자열 s 안의 전체 값 개수와 s 안에서 숫자인 값의 개수가 같으면, 즉 s의 모든 값이 숫자이면
    if(num == s.length){ 
        return true; 
    } else{ // s의 값 중 하나라도 숫자가 아닌 값이 있으면
        return false;
    }
}




다른 사람의 풀이

function solution(s){
        let answer = true;
    
        if (s.length !== 4 && s.length !== 6) {
          answer = false;
        } else {
          let arr = s.split(""); // 문자열 s를 문자 단위로 쪼개 배열 arr에 넣음.
          arr.forEach((element) => { // 배열 arr의 각 원소 element에 대하여
            if (isNaN(element)){ // 만약 어떤 원소가 숫자가 아니면 반환할 값은 false
                answer = false; 
            }
          });
        }
    
        return answer;
}

 

split 메소드는 문자열을 구분자 단위로 쪼개 배열로 변환합니다.

구문: 배열 = 문자열.split('구분자')

 

forEach 메소드는 배열에만 쓸 수 있고,
배열의 각 원소에 대해 패러미터로 주어진 함수를 실행합니다.


구문: 배열.forEach((배열의 원소) => {각 원소에 대한 함수})

 

isNan() 함수는 함수 속 인자가 "숫자가 아닌지" 판별합니다.

 

18. 서울에서 김서방 찾기

 

// 문자열형 배열 seoul = ["Jane", "Kim"]
// 배열 seoul 속 원소 Kim의 인덱스 = location_x

function solution(seoul){ 
    let location_x = '';
    
    for(let i=0; i<seoul.length; i++){
        if(seoul[i] === "Kim"){
            location_x = i;
        }
    }
    
    return "김서방은 " + location_x + "에 있다";
}

 


 

19. 수박수박수박수박수박수?

 

function solution(n){
    let arr = []; // arr은 배열이므로 선언 시 arr = ''가 아니라 arr = []이어야 함.
    let answer = ''; // answer은 문자열이므로 선언 시 answer = ''이어야 함.
    
    for(let i=0; i<n; i++){
        if(i%2 == 0){ 
            arr[i] = "수";
        } else{
            arr[i] = "박";
        }
    }
    
    answer = arr.join('');
    return answer;
}



join() 함수는 배열의 모든 원소들을 하나로 연결한 문자열을 리턴합니다.
이때 각 원소 사이에는 패러미터로 입력된 구분자(separator)가 들어가게 됩니다.
만약, separator를 입력하지 않은 경우, default로 ','가 들어갑니다.

구문: arr.join(separator)

예시
const elements = ['Fire', 'Air', 'Water'];

console.log(elements.join()); // expected output: "Fire,Air,Water"
console.log(elements.join('')); // expected output: "FireAirWater"
console.log(elements.join('-')); // expected output: "Fire-Air-Water"

 


 

20. 완주하지 못한 선수

 

function solution(participant, completion){
    let answer = "";
    
    /* 두 배열을 sort 메소드를 통해 같은 순서로 정렬 */
    participant.sort();
    completion.sort();

    for(let i=0; i<participant.length; i++){
         if(participant[i] !== completion[i]){ // 참가자 이름과 완주자 이름이 일치하지 않으면
            answer = participant[i]; // 해당 참가자 이름을 반환하고
            break; // for문을 바로 빠져나옴
         }
    }
    
    return answer;
}

 

sort 메소드는 배열의 원소를 정렬한 후 그 배열을 반환합니다.
이때 정렬되는 방식은 꼭 알파벳 순이나 오름차순 또는 내림차순이 아닙니다.
그러나 동일한 함수 내에 여러 개의 배열이 있고, 그 배열들에 sort 메소드를 사용할 시
각 배열의 원소들은 서로 같은 방식으로 정렬됩니다.

 


 

21. 이상한 문자 만들기

 

function solution(s){
    // 1. 주어진 문자열 s를 단어 단위로 나눔.
    // 2. 각 단어를 구성하는 문자를 대문자 또는 소문자로 바꿈.
    // 3. 바꾼 단어를 다시 하나의 문자열로 합치는데, 이때 각 단어 뒤에 공백을 붙임. 
    // 4. 마지막 단어 뒤에 공백이 하나 남으므로 해당 공백을 삭제.
    
    let answer = []; // 최종적으로 리턴할 배열을 선언.
    
    /* 1. 주어진 문자열 s를 공백 기준으로 나누어 얻은 단어들을 배열 arr의 원소로 각각 넣음. */
    let arr = s.split(' '); // ex) arr = ['try', 'hello', 'world']

    for(let i=0; i<arr.length; i++){ // arr.length = 단어의 개수, i = 단어의 인덱스
        
        /* 2. 각 단어를 구성하는 문자를 대문자 또는 소문자로 바꿈. */
        let changed_arr = []; // 대문자 또는 소문자로 바꾼 단어들을 넣을 배열 선언.
        
        for(let j=0; j < arr[i].length; j++){ 
            // arr[i].length = 각 단어의 길이
            // j = 단어 내 문자의 인덱스, arr[i][j] = i번째 단어의 j번째 문자
            // ex) arr[0][2] = 'y'
            
            if(j%2 == 0){ // 각 단어의 짝수번째 알파벳은 대문자로 바꾸고,
                changed_arr += arr[i][j].toUpperCase();
            }
            else{ // 홀수번째 알파벳은 소문자로 바꿈.
                changed_arr += arr[i][j].toLowerCase();
            }
            // ex) changed_arr = ['TrY', 'HeLlO', 'WoRlD']
        }
        
        /* 3. 바꾼 단어를 다시 공백과 함께 하나의 문자열로 합침. */
        answer += changed_arr + ' '; // ex) answer = [TrY HeLlO WoRlD ]
    }
    
    /* 4. 배열 answer의 첫번째 원소부터 마지막 원소 바로 전까지의 원소만 리턴.
       즉, 마지막에 있는 공백 삭제. */
    return answer.slice(0, -1); // ex) answer = [TrY HeLlO WoRlD]     
}

 


 

22. 자릿수 더하기

 

function solution(n)
{
    let str = String(n); // 숫자 n을 문자열 str로 변환. 즉, str = "n"
    
    let arr = []; 
    arr = str.split(''); // 문자열 str을 배열 arr로 변환. 즉, arr = [n의 각 문자가 원소로 들어감]
    
    let sum = 0; 
    sum = arr.reduce((acc, cur) => acc += Number(cur), 0);
    // reduce 메소드를 통해 하나씩 더하되, Number()를 통해 더할 때 숫자로 바꾸어서 더함.
    
    return sum;
}

 

[로직]
1. 자연수 n을 문자열로 바꾸고, 문자열을 다시 배열로 바꿈.
2. 이때 배열의 각 원소는 문자 처리가 되어 있으므로, 문자를 숫자로 바꿈.
3. 배열의 각 원소를 더함.

String() 메소드는 숫자를 문자열로 변환합니다.
let num = 5;
let str = String(num);
console.log(num); // "5"​


split() 메소드는 문자열을 배열로 변환합니다. 

reduce() 메소드는 배열 내의 원소들을 더한 값을 반환할 수 있습니다.
currentValue.x 부분을 원하는 방식으로 변경할 수 있고,
초기값 intialValue를 설정하여 누산기를 통해 얻은 합에 초기값을 더한 값을 반환할 수 있습니다.
let initialValue = 0; 

let sum = [{x: 1}, {x:2}, {x:3}]
.reduce( (accumulator, currentValue) => 
accumulator + currentValue.x, initialValue ); 

console.log(sum) // 6 출력

 

23. 자연수 뒤집어 배열로 만들기


나의 풀이(코드 실행은 되는데, 정확성이 15.4)

function solution(n){
    let arr1 = String(n).split(''); // 숫자 n을 문자열로 바꾼 후, 문자열을 다시 배열로 바꿈
    let arr2 = [];
    
    arr1.sort(function(a, b){ // 배열을 내림차순으로 재정렬하여 반환
        return b - a;
    });
    
    for(let i=0; i<arr1.length; i++){ // 재정렬된 배열의 원소는 문자형이므로 숫자로 바꾸어 또 다른 배열에 넣음
        arr2[i] = Number(arr1[i]);
    }
    
    return arr2;
}


다른 사람의 풀이

function solution(n){
    let answer = String(n).split('').map(element => Number(element)).reverse();
    
    // String()을 통해 숫자 n을 문자열로 바꾼 후
    // split()을 통해 문자열을 다시 배열로 바꿈.
    // 이때 배열의 원소는 문자형이므로 map() 속의 Number()을 통해 숫자형으로 바꾼 후
    // reverse()을 통해 내림차순으로 재정렬.
    
    return answer;
}

 

map(): 배열 내의 모든 요소 각각에 대하여 주어진 함수를 호출한 결과를 모아 새로운 배열을 반환
const array1 = [1, 4, 9, 16];

const map1 = array1.map(x => x * 2); // pass a function to map

console.log(map1); // expected output: Array [2, 8, 18, 32]


reverse()
: sort()를 통해 바뀌었던 배열의 정렬을 다시 원본 순서로 바꾸어 정렬해줍니다.

 

24. 정수 내림차순으로 배치하기


풀이 1

function solution(n){
        return Number(String(n).split('').sort((a, b) => b-a).join(""));
}


풀이 2

function solution(n){
        return Number(String(n).split('').sort().reverse().join(""));
} // 1자리 수씩 비교하므로 그냥 sort()를 쓴 후, reverse 해줌.

 

String(n): 숫자 n을 문자열로 바꿈.

배열.split('구분자'): 문자열을 배열로 바꿈.

sort(): 알파벳으로 이루어진 원소들은 오름차순으로 잘 정렬되지만,
숫자로 이루어진 원소들은 뒤죽박죽으로 섞입니다.
숫자로 이루어진 원소들을 잘 정렬하려면
다음과 같이 해야 합니다.
arr.sort((a, b) => a-b); // 오름차순 정렬
arr.sort((a, b) => b-a); // 내림차순 정렬


join(): 배열을 문자열로 바꿈.

Number(): 숫자로 이루어진 문자열 또는 배열을 숫자로 변환해줍니다.

 


문제 25번) 정수 제곱근 판별

 

// n = 양의 정수 = 자연수, x = n의 제곱근 = 자연수
// 자연수 n이 다른 자연수 x의 제곱이면 x+1의 제곱을 리턴
// 자연수 n이 다른 자연수 x의 제곱이 아니면 -1을 리턴

function solution(n){
    let x = Math.sqrt(n); // x는 n의 제곱근
    
    if((x >= 0) && (Math.floor(x) === +x)){ // x가 0 이상이고 [x]이 양수이면 x는 자연수이므로
        return (x+1)*(x+1); // x+1의 제곱을 리턴
    } else{ // x가 자연수가 아니면 n은 어떤 자연수의 제곱이 아니므로
        return -1; // -1을 리턴
    }
}

 

root를 반환: Math.sqrt(n)
x와 같거나 작은 정수 중 가장 큰 값, x에 즉 가우스 기호를 붙인 값 [x]을 반환: Math.floor(x)

 


26. 제일 작은 수 제거하기

 

function solution(arr) {
    var answer = [];
    
    if (arr.length <= 1) {
        return [-1];
    } else {
        arr.splice(arr.indexOf(Math.min(arr)),1);
        answer = arr;
    }
    
    return answer;
}
# 부분 배열 반환
array.slice(start, end)

slice() 메서드는 전달 인자를 2개 받는데, 각 인자는 반환될 부분의 처음과 끝.

전달 인자가 2개: 첫 번째 전달인자가 지정하는 위치부터 두 번째 전달인자 바로 전까지의 원소를 반환.

전달 인자가 1개: 그 위치에서 배열 끝까지의 원소를 반환.

전달 인자가 음수: 배열의 마지막 원소에서 상대적인 위치로 배열 원소를 지정.
ex) 전달 인자 -1은 배열의 마지막 원소,
전달인자 -3은 배열의 마지막 원소부터 앞쪽으로 세 번째 원소.

 


 

27. 콜라츠 추측

 

function solution(num) {
    let count = 0;
    
    while(num !== 1 && count < 500){
        if(num%2 == 0){
        num = num/2;
        } else{
            num = num*3+1;
        }
        
        count++;
    }
    
    if(count < 500){
        return count;
    } else{
        return -1;
    }
}

 


 

28. 하샤드 수

 

function solution(x) {
    let result = '';
    
    result = String(x).split('').reduce((acc, cur) => acc += Number(cur), 0); // 자릿수 합
    
    if(x%result == 0){
        return true;
    } else{
        return false;
    }
}
대문자로 변환
.toUpperCase();
ex) var a = "ABC abc" ;
a.toUpperCase();
> 결과 : ABC ABC

소문자로 변환
.toLowerCase();
ex) var a = "ABC abc";
a.toLowerCase() ;
> 결과 : abc abc