[TIL] 약수, 최대공약수 알고리즘

이재훈·2020년 10월 16일
0

문법 및 코드

목록 보기
1/5

0.5라는 숫자가 주어졌다면 1/2로 리턴하는 fractionConverter 알고리즘을 구현하다가
최대공약수가 필요하다는 것을 깨닫고 최대공약수 helper function을 만들어봤다.

최대 공약수를 구하려면 약수부터 우선 구해야했었기에
이 포스트에서는 공약수 구현 코드 및 최대공약수 구현 코드를 기록해보겠다.

약수 알고리즘

약수란,
어떠한 수나 식을 나머지 없이 나눌 수 있는 수라 정의가 된다.

10의 약수
1, 2, 5, 10

위의 예제처럼 10의 약수를 구현한 코드는 아래와 같다.

  • 의사코드
    함수의 파라미터를 'number'라고 할 때,

    1. number의 타입이 "number"가 아니면 그대로 종결
      -> if(typeof value !==0) return;
    2. 숫자가 맞다면 반복문을 1부터 해당 숫자까지 돌고, & 나머지가 0일때 새로운 배열에 push
      -> else { for(i=1; 1< 10); i++ ( if(해당숫자 % i === 0 ) {[].push(i)} )}
    3. 담은 배열을 리턴

  • 구현

[약수 알고리즘]

const divisor = function (number) {

  let result = [];

  if (typeof number !== 'number') {
    return;
  }
  else {
    for (let i = 1; i <= number; i++) {
      if (number % i === 0) {
        result.push(i);
      }
    }
    return result;
  }
}

// divisor(10) -->  [1, 2, 5, 10]
// divisor(8)  -->  [1, 2, 4, 8]
// divisor(100) ->  [1, 2, 4, 5, 10, 20, 25, 50, 100]

공약수, 최대공약수 알고리즘

공약수 알고리즘은 위의 코드의 연장선이라고 볼 수 있다.
위의 약수 알고리즘에 업그레이드만 해주면 공약수를 구할 수 있다는 뜻이다.

또한 최대공약수는 공약수를 구하고 난 뒤 가장 큰 수를 리턴하면 되는데, 아래에서 살펴보자.

  • 의사코드
    파라미터를 (숫자1, 숫자2)로 설정한다.

    1. typeof 해당숫자가 'number'가 아니라면 그대로 종결
      -> if(typeof 해당숫자 !== 'number') return;

    2. 해당 숫자가 맞다면 숫자 1의 공약수를 구한다.
      -> else { for(i = 1; i < 해당숫자; i++){ if(해당숫자 % 1 === 0){ [].push(i) } } }


      2-1 숫자 2도 위와 동일

    3. 숫자1 배열과 숫자2의 배열에서 공통되는 숫자를 새로운 배열에 담자. filter와 indexOf를 사용해보자 (즉, -1이 아니라면(찾고자 하는 인덱스의 값이 없으면 '-1'을 리턴) filter로 걸러내자.)

      -> 숫자1.filter(el => { return 숫자2.indexOf(el) !== -1 })

    4. 새로 만들어진 배열 안에서 최대값을 리턴하자.

  
const getGCD = function (num1, num2) {

  let num1Arr = [];
  let num2Arr = [];

  if (typeof num1 !== 'number' || typeof num2 !== 'number') {
    return;
  }
  else {
    for (let i = 2; i <= Math.abs(num1); i++) {
      if (num1 % i === 0) {
        num1Arr.push(i)
      }
    }
    for (let j = 2; j <= Math.abs(num2); j++) {
      if (num2 % j === 0) {
        num2Arr.push(j)
      }
    }
    let result = num1Arr.filter(el => { // result는 각각의 배열의 공통 인자를 뽑아 담아낸 새로운 배열이다.
      return num2Arr.indexOf(el) !== -1    // 이 리턴값이 true면 살리고 false면 죽인다.
    })
    let GCD = Math.max.apply(null, result) // 최대공약수를 추출하는 부분
    // console.log('num1', num1Arr)
    // console.log('num2', num2Arr)
    // console.log(result)
    // console.log(GCD)
    return GCD;
  }
}

/*
 ! getGCD(10, 15)  --> 5   (최대공약수)
    - console.log('num1', num1Arr) --->  [1, 2, 5, 10]
    - console.log('num2', num2Arr) --->  [1, 3, 5, 15]
    - console.log(result)  ----------->  [1, 5]
    - console.log(GCD)  -------------->  5
 */

다시 fractionConverter 구현하러 가야지...!!

profile
코딩에서 인생을 배우다.

0개의 댓글