[코딩노트] S1 Unit 3 - javascript 반복문

나현·2022년 8월 24일
0

코딩노트

목록 보기
2/11
post-thumbnail

💡 이 포스트에는 Unit 3. javascript 기초 제어문 - 반복문의 코딩문제를 풀고 몰랐던 점이나 부족했던 점을 정리했다!
(누군가에게는 너무 쉬워 하품이 나올 수 있습니다.🥲)

코딩노트 정리하기

1. 팩토리얼(factorial) 계산하기

핵심 : 팩토리얼은 n!으로 표시하며 1부터 n까지의 곱이다.
팩토리얼을 계산하기 위해서는 반복문이 필요하다.

//4! 구하기
let sum=1;
for(let i=1;i<=4;i=i+1){
  sum=sum*i;
}
console.log(sum);

2. 글자 개수 찾기

핵심 : 문자열은 배열처럼 한 글자씩 조회가 가능하다. (ex. str[0])
이를 이용하면 배열처럼 한 자씩 찾아서 활용이 가능하다.

//문자 찾기
let myStr='hello world';
let toFind='l';
for (let i = 0; i < myStr.length; i++) {
  if (myStr[i] === toFind) {
    console.log(`찾았다! ${i}번째 있네!`);
  }
}

3. 약수 구하기

핵심 : n의 약수를 구할 때 n보다 작고, n을 나눈 나머지가 0인 수는 약수이다.
반복문을 활용해 약수를 모두 구할 수 있다.

let n=12;
let str=`${n}의 약수는: `;
for(let i=1;i<=n;i++){
  if(n%i===0){
    str+=`${i},`
  }
}
str=str.slice(0, str.length-1); //마지막 쉼표 자르기
console.log(str);

4. 소수 구하기

핵심 : 소수는 1과 나 자신만을 약수로 가지는 수이다.
소수는 다음과 같은 특징을 가진다.

  • 1은 소수가 아니다.
  • 2는 소수이다.
  • 2를 제외한 짝수는 모두 소수가 아니다.
  • 어떤 수 n이 소수인지 아닌지 확인하는 방법:
    1. 1부터 n-1까지 n을 그 수로 나누었을 때, 하나라도 떨어지는 수가 있으면 n은 소수가 아니다.
    2. 즉, n나머지(1~(n-1)사이의 수)가 0인 경우가 없어야 소수다.
    3. 여기서 'n나머지(1~(n-1)사이의 수)가 0인 경우'는 약수이다.
    4. 정리하자면 약수가 없어야 한다.
  • 1부터 n까지 확인하는 방법이 정공법이지만, n의 제곱근 값까지만 구해도 값 판별이 가능하다:
    ex.16의 경우 1*16, 2*8, 4*4, 8*2, 16*1 을 약수로 갖고 있는데

예제1. 소수 판독기

소수 판독기 primeTest(prime)는 인자로 임의의 수를 입력하면 소수인지 아닌지 판독결과를 알려준다.

function primeTest(prime) {
  let isPrime=false;
  //2는 소수이고 1,2까지의 수이므로 반복문 전에 예외 처리한다.
  if(prime===2) isPrime=true;  
  //1과, 2가 아닌 짝수는 소수가 아니므로 제외한다.
  if(prime!==1 && prime%2!==0){
    //소수가 아닐 경우 반복문에서 false를 재할당하므로 일단 true를 할당한다.
    isPrime=true;
    //약수를 판별하는 반복문 설명:
    //prime보다 작은 수 중 약수가 있으면 소수가 아니다.
    //식으로 쓰면 prime%i===0 이며 i는 prime보다 작아야 한다.
    //약수는 prime의 제곱근까지만 확인해도 된다.
    //증감문에2씩 더하는 이유는 짝수를 이미 확인했기 때문이다.
    let primeSqrt=Math.sqrt(prime);
    for(let i=3; i<primeSqrt; i+=2){ 
      if(num%i===0){ //약수인 경우
        isPrime=false;
      }
    }
  }
  //결과 리턴하기
  if(isPrime){
  	return `${prime}은(는) 소수입니다.`;
  }else{
  	return `${prime}은(는) 소수가 아닙니다.`;
  }
}

예제2. 소수 찾기

findPrimes(endNum)은 1부터 인자로 입력한 수까지의 소수를 찾아서 알려준다.

function findPrimes(endNum) {
 //입력한 값이 1이하일 경우 출력
 if(endNum<=1) return '2이상의 값을 입력해야 합니다.';
 
 //소수를 기록할 변수
 let result='2'; 
  
 //첫번째 반복문: 3부터 endNum까지 소수를 모두 탐색(짝수 제외)
 for(let n=3; n<=endNum; n+=2){ 
 	//소수인지 아닌지 판별해주는 논리값이 필요하다.(1번 예제와 비슷)
    let isPrime=true;
    //n이 소수인지 아닌지 제곱근만큼 판별한다.
    let primeSqrt=Math.sqrt(n);
    for(let m=3; m<primeSqrt; m+=2){
      if(n%m===0){ //약수인지 아닌지
        isPrime=false; //약수가 하나라도 있으면 n은 소수가 아니다.
        break; //반복문에서 탈출
      }
    }
    if(isPrime===true){
      result=result+`, ${n}`;
    }
 }
 return `${endNum}까지 소수는 ${result}입니다.`;
}

5. 두자리 경우의 수 조합 찾기

핵심 : 중복이 가능한 두자리 수의 조합: 이중 반복문을 사용한다.
아래의 예제 makeStrList(code)는 임의의 문자열 코드를 인자로 받아 가능한 두자리 조합으로 출력하여준다.
만약 임의의 코드 'ABC'를 입력받았다면 'AA,AB,AC,BA,BB,BC,CA,CB,CC' 이렇게 결과를 출력한다.

function makeStrList(code) {
  //조합을 추가해줄 빈 문자열을 할당할 변수
  let result='';
  
  //이중 반복문
  //첫번째 반복문은 첫번째 자리, 두번째 반복문은 두번째 자리를 조합한다.
  //두번째 자리를 차례로 조합할 동안 첫번째 자리는 바뀌지 않는다.
  //ex. AA,AB,AC
  for(let i=0; i<code.length; i++){
    for(let m=0; m<code.length; m++){
      result=result+`${code[i]}${code[m]},`
    }
  }
  //조합한 문자열은 콤마가 붙은 상태로, 제거가 필요하다.
  //result.length-1 대신 -1을 써도 결과는 같다.
  return `가능합 조합의 코드는 ${result.slice(0, result.length-1)}입니다.`; 

}

6. 문자열 중복 찾기

핵심 : 길이가 n인 문자열에서 중복을 찾아야 할 경우 다음과 같이 비교한다-str[0]과str[1]~str[n], str[1]과str[2]~str[n], ... ,str[n-1]과str[n] 이렇게 반복하며 비교해야 한다.
길이가 n인 문자열에서 중복을 찾으려면 두개를 한쌍으로 서로 같은지 하나하나 비교해야 한다.

예시)
"hello world"
여기서 첫번째 글자는 'h', 두번째 글자는 'e'
글자의 길이는 11(띄어쓰기 포함)
비교할 때는 'h'와 'e'가 같은지 비교
'h'와 'l'이 같은지 비교
...

과정을 자세히 살펴보면 아래와 같다.

  • 첫번째 글자, 두번째 글자 비교
  • 첫번째 글자, 세번째 글자 비교
    ...
  • 첫번째 글자, n번째 글자 비교

여기까지 첫번째 글자부터 두번째~마지막 n번째 글자까지 비교하였다.
그 다음부터는 두번째 글자부터 마찬가지로 나머지 글자까지 일일이 비교한다.

  • 두번째 글자, 세번째 글자 비교
  • 두번째 글자, 네번째 글자 비교
    ...
  • 두번째 글자, n번째 글자 비교

이런 식으로 반복하면 마지막은 아래와 같다.

  • n-1번째 글자, n번째 글자가 비교

이 패턴을 정리해보면 비교시 왼쪽자리의 글자의 순서는 고정되있고, 오른쪽자리의 글자의 순서는 왼쪽자리+1 부터 마지막 n까지 반복한다.
이를 활용하면 왼쪽 자리 반복문 안에 오른쪽 자리 반복문을 넣어 하나하나 비교가 가능하다.

아래의 예제는 이 내용을 반영했다. 문자를 하나씩 비교하여 중복된 문자열이 있을 경우 중복 여부를 알려준다.

function findSameLetter(str) {
  //문자열에 중복되는 같은 단어가 있는 경우 true, 없으면 false
  let result=false;
  //이중반복문
  //첫번째 반복문
  for(let i=0; i<str.length; i++){
    //두번째 반복문: i에서 비교한 문자 다음 문자부터 시작해 비교한다
    //즉 j는 i+1이여야 한다.
    for(let j=i+1;j<str.length;j++){
      if(str[i]===str[j]){
        result=true;
        break; //중복여부만 알면 더 이상 찾을 필요는 없다.
      }
    }
  }
  //알림 출력
  if(result){
  	return '중복된 문자열이 있네요!';
  }else{
  	return '중복된 문자열이 없습니다:)';
  }
}

노트 정리 후 느낀점

개념 자체는 학습하는 데 오랜 시간이 걸리지 않았지만 알고리즘을 공부하면 할수록 어려움을 느꼈다. 아무래도 기존에 배웠던 내용들이 모두 섞이고, 따로 노하우도 필요하기 때문에 그랬던 것 같다.
내가 학습을 하며 부족했던 점은 아래와 같았다.

  • 문자열을 조회하거나 자르고 비교할 때 적절한 메서드 사용이 익숙하지 않았다.
  • 수학의 개념-정의와 구하는 방법에 대해 잘 몰랐다.(소수, 약수 등등)
  • 무언가를 비교할 때의 원리와, 비교시 문제에 따라 어디부터 어디까지 비교해야 하는지 반복문에 바로바로 적용하기 어려웠다.

그래서 위의 부족한 점을 보완하기 위해 아래와 같이 공부했다.

  • 자주쓰는 문자열 메서드를 벨로그에 확실하게 정리했고, 비슷한 메서드는 차이점을 확실하게 알아본 뒤 직접 실습하였다.
  • 구글링하여 각 수학적 용어와, 특징을 확실하게 정리하였다. 정리한 내용에 따라 차근차근 알고리즘 문제를 풀어보았다. 적어도 이번에 공부한 수학개념은 앞으로 까먹거나 크게 틀리진 않을 것 같다.
  • 비교할 때의 원리와 이를 반복문에 연결시켜 틀린 알고리즘 문제를 분석했다. 이제 두 문자를 비교하는 알고리즘은 잘 만들 수 있을 것 같다.

그리고 내용을 정리하며 의사코드를 잘 짜는 것이 정말정말 중요함을 또 느낄 수 있었다.
이렇게 코딩노트가 차근차근 쌓여서 나중엔 알고리즘을 좀 더 빠르게 풀 수 있었으면 한다!

profile
프론트엔드 개발자 NH입니다. 시리즈로 보시면 더 쉽게 여러 글들을 볼 수 있습니다!

0개의 댓글