반복문 코플릿 문제풀이

2022. 12. 20. 22:11코드스테이츠/코드스테이츠 : 페어프로그래밍

isPrime

문제

1 이상의 자연수를 입력받아 소수(prime number)인지 여부를 리턴해야 합니다.

입력

인자 1 : num

  • number 타입의 수

출력

  • boolean 타입을 리턴해야 합니다.
// 소수 : 1과 자신으로밖에 나누어지지 않는 고독한 숫자
// 수학에서 1과 그 수 자신 이외에는 자연수로 나눌 수 없는, 1보다 큰 자연수
// 1. 소수는 1보다 커야 한다.
// 2. 2를 제외한 짝수는 소수가 아니다 (2는 소수)
// 3. 3부터 자기 자신 '전'까지 나누어 떨어지는 수가 하나라도 있으면, 소수가 아니다.
function isPrime(num) {
  // 제곱근 Math.sqrt()
  let sqrt = Math.sqrt(num);
  // 1이면 소수가 아니다.
  if (num === 1) {
    return false;
  }
  // 짝수는 소수가 아니다 (2를 제외하고)
  if (num === 2) {
    return true;
  }
  if (num % 2 === 0) {
    return false;
  }
  // 3. 3부터 자기 자신 '전'까지 나누어 떨어지는 수가 하나라도 있으면, 소수가 아니다.
  for (let i = 3; i < sqrt; i++) {
    // num = 12
    // 1 * 12
    // 2 * 6
    // 3 * 4
    // 12의 제곱근 * 12의 제곱근
    // 4 * 3
    // 6 * 2
    // 12 * 1
    if (num % i === 0) {
      return false;
    }
  }
  return true;
}

반복문 문제를 풀면서 처음으로 난관에 봉착한 문제다.

수학이라면 머리에서 쥐가 나는 나에게는 소수가 무엇이며, 어떤식으로 접근해야 할 지 막막했다.

isPrime 문제의 키포인트는 소수를 이해하는것과 Math.sqrt 를 통해 불필요한 연산을 줄이는 것 이였다.

수학적 사고가 조금 뒤쳐지는 나는 이것을 이해하는데에 꽤나 오랜 시간을 쓴 것 같다.


listPrimes

문제

2 이상의 자연수를 입력받아 2부터 해당 수까지의 소수(prime number)들을 리턴해야 합니다.

입력

인자 1 : num

  • number 타입의 정수 (num >= 2)

출력

  • string 타입을 리턴해야 합니다.
  • 2-3-5-7의 형식으로 리턴해야 합니다.

주의 사항

  • 이중 반복문(double for loop)을 사용해야 합니다.
function listPrimes(num) {
  // 이중반복문
  // 9번 문제는 그냥 어떤 수가 소수인지 판단
  // 문자열을 리턴
  // ex) num = 12, '2-3-5-7-11'
  // 외부 반복문 : 2부터 자기자신(num)까지 반복하면서 이 수가 소수인지 판단
  // 내부 반복문 : 이 수가 소수인지 판단 (9번 문제)
  let result = '2'; //2이상의 자연수를 입력받으니 result에 2를 줘버림
  for (let i = 3; i <= num; i += 2) { // result에 2를 줬기때문에 3부터 자기자신(num)까지 반복하면서 이 수가 소수인지 판단
    let isPrime = true;
    
    for (let j = 3; j < i; j++) { // 이 수가 소수인지 판단
      if (i % j === 0) { // i 가 j로 나눴을 때 딱 떨어지는 수 라면 
        isPrime = false; // 소수가 아니다.
      }
    }
    // isPrime인 true인 경우도 있고, false인 경우도 있음
    // 조건을 다시 분기해서, 만약에 true면, (소수면) result에 더해준다.
    if (isPrime === true) {
      result = `${result}-${i}`
    }
  }
  return result; // if문에 충족하지 않는다면 바로 result를 리턴
}

바로 이전 문제인 isPrime문제를 겨우 이해하고 다음 문제로 넘왔는데 ....

무려 'listPrime'님이 기다리고 계셨습니다.

방금 소수문제를 풀어냈지만 다시봐도 쉬이 풀리지 않았다.

그래도 얼마전에 소수에대한 개념을 어렴풋이 머릿속에 넣어놨기 때문에 isPrime 문제보다는 일찍 푼 것 같다.


makePermutations

문제

문자열을 입력받아 해당 문자열에 등장하는 각 문자(letter)를 가지고 만들 수 있는 길이 2의 문자열들을 리턴해야 합니다.

입력

인자 1 : str

  • string 타입의 문자열

출력

  • string 타입을 리턴해야 합니다.
  • 입력받은 문자열의 각 문자를 0, 1, 2, ..., n이라고 할 경우, 00,01,02,...,nn 형식으로 리턴해야 합니다.

주의 사항

  • 이중 반복문(double for loop)을 사용해야 합니다.
  • 빈 문자열을 입력받은 경우에는 빈 문자열을 리턴해야 합니다.

function makePermutations(str) {
  // TODO: 여기에 코드를 작성합니다.
  //이중반복문 사용
  //빈 문자열을 받는경우 빈 문자열을 리턴 = result = ''
  //String 타입을 리턴
  let result = '';
  for(let i = 0; i < str.length; i++){ // 문자열 탐색 디폴트값
    for(let j = 0; j < str.length; j++){ // 문자열 탐색 디폴트값
      result = result +`${str[i]}${str[j]},` //i=0 j=0/ i=0 j=1/i=0 j=2/  내부 반복문 종료 => 외부 반복문 시작

      }
    }
    return result.slice(0,result.length-1);
  }

이중반복문에 대해 어느정도 이해가 생기게 된 부분이다.

내부반복문이 조건을 만족하고 종료되면 외부반복문이 한바퀴 돌고, 다시 내부반복문이 조건을 만족하고 종료되면 외부반복문이 한바퀴 돌고, 이런식으로 동작하는 것 같다.

입력이 'hat' 이라면' i=0(hh,ha,ht) i=1(ah,aa,at) i=2(th,ta,tt)  이런식으로 출력이 될 것이다.

이중반복문을 배우면서 느낀게 내부반복문은 수색견같다.

i=0이라는 섹터에 j라는 수색견을 풀어놓으면 열심히 수색하고 돌아온다.

전부 수색했으니 i=1이라는 섹터에 풀어놓으면 또 열~심히 수색하고 돌아오겠지.


hasRepeatedCharacter

문제

문자열을 입력받아 해당 문자열에 중복된 문자(letter)가 존재하는지 여부를 리턴해야 합니다.

입력

인자 1 : str

  • string 타입의 문자열

출력

  • boolean 타입을 리턴해야 합니다.

주의 사항

  • 이중 반복문(double for loop)을 사용해야 합니다.
  • 빈 문자열을 입력받은 경우에는 false을 리턴해야 합니다.

function hasRepeatedCharacter(str) {
  // TODO: 여기에 코드를 작성합니다.
  //문자열을 입력받아 해당 문자열에 중복된 문자가 존재하는지 여부를 불리언타입으로 리턴
  //입력 'abcdefg'
  //출력 false
  
  for(let i=0; i <= str.length; i++){ // 문자열 읽기 디폴트값 / 문자열을 처음부터 끝까지 싸악~ 훑겠다.
    for(let j=i+1; j<= str.length; j++){ // j=i+1 한 이유는 외부반복문처럼 0으로 줄 경우 같은위치의 문자열 인덱스를 읽게되기 때문에 계속 true가 반환됨
      if(str[i] === str[j]){ //반복문이 돌기시작하면, str에 banana가 입력됐다는 가정하에 i='b' j='a'/i='b j='n'/i='b' j='a'..... 식으로 j반복문이 다 돌면 j는 초기화 후 i반복문이 돌아간다
        return true // i와 j가 같은경우가 생긴다면 true.
      }
    }
  }return false // if문에 충족하지않는다면 바로 false를 리턴
}

내가봐도 웃긴데...

편하자고 반복문을 써놓고 , 주석으로 열심히 노가다를 했다. 머리에 넣어보겠다고 ㅠㅠㅠ

미련하긴 했지만 좋게 말하면 반복문 코드의 실행과정에 대해 어느정도 이해와 설명이 가능해졌다고 생각한다.

부디 내 머릿속에 오래 남아줬으면 해..


makeMarginalString

문제

문자열을 입력받아 해당 문자열을 처음부터 한 글자(letter)씩 다시 작성하려고 합니다. 이 때, 한 글자를 추가할 때마다 부분적으로 완성된 문자열을 전부 이어붙인 문자열을 리턴해야 합니다.

입력

인자 1 : str

  • string 타입의 문자열

출력

  • string 타입을 리턴해야 합니다.

주의 사항

  • 이중 반복문(double for loop)을 사용해야 합니다.
  • str.slice, str.substr, str.substring 사용은 금지됩니다.
  • 빈 문자열을 입력받은 경우에는 빈 문자열을 리턴해야 합니다.
function makeMarginalString(str) {
  // TODO: 여기에 코드를 작성합니다.
  //입력 : 'abc'
  //출력 : 'aababc'
  //이중반복문 사용
  //str.slic / str.substr / str.substring 사용 금지
  //maybe .concat사용?
  //------------------------------------------------------
 let result = ''
 for(let i = 0; i < str.length; i++){
   for(let j = 0; j <= i; j++ ){
     result = result + str[j]
     // i = 0, j = 0 => str[j] 'f'
      // i = 0, j = 1 => 내부 반복문 종료
      // i = 1, j = 0 => str[j] 'f'  'ff'
      // i = 1, j = 1 => str[j] 'l'  'ffl'
      // i = 1, j = 2 => 내부 반복문 종료
      // i = 2, j = 0 => str[j] 'f'  'fflf
      // i = 2, j = 1 => str[j] 'l'  'fflfl'
      // i = 2, j = 2 => str[j] 'o'  'fflflo'
      // i = 2, j = 3 => 내부 반복문 종료
      // i = 3, j = 0 => str[j] 'f'  'fflflof
      // i = 3, j = 1 => str[j] 'l'  'fflflofl
      // i = 3, j = 2 => str[j] 'o'  'fflfloflo
      // i = 3, j = 3 => str[j] 'w'  'fflfloflow'
      // ...
      // i = 5, j = 5 => str[j] 'r' 'fflfloflowfloweflower'
   }
 }return result
}

반복문을 이해하기 위한 마지막 발악이였던 문제다.

'문자열을 입력받아 해당 문자열을 처음부터 한 글자(letter)씩 다시 작성하려고 합니다. 이 때, 한 글자를 추가할 때마다 부분적으로 완성된 문자열을 전부 이어붙인 문자열을 리턴해야 합니다.' 를 보고 .concat을 떠올렸는데  전~혀 쓸 일이 없었다.

이미 이전 문제들에서 반복문을 단련했기때문에 수월하게 풀어냈지만! 역시 주석노가다를 통해 과정을 눈으로 봐야 머리에 남기때문에 열심히 끄적여 줬다. (생각해보니 고등학교 때 블록쌓기문제도 열심히 그렸던,,)


반복문 코플릿 배운 점

1. 내부 반복문의 조건식을 외부조건식으로 바꾸면 수색견 같던 내부반복문이 i주변을 멤도는 강아지가 된다.

ex. for(let i = 0; i < str.length; i++)  

             for(let j = 0; j<= i; i++)  이렇게 반복문을 돌리면 내부반복문이 외부반복문을 따라다니며 수색한다.ㅋㅋ


 

2. Math 메소드를 이용하면 불필요한 연산을 줄일 수 있다! (Math 연산자의 적용 사례들을 간간히 찾아보자)


3. ~~문자열을 입력받아 무엇을 찾아서 무엇을한다?  for(let i = 0; i < str.length; i++) 거의 디폴트 값