60. 정규표현식! 조합재귀함수!

홍인열·2021년 11월 13일
0

못풀었던 코플릿을 다시 풀어보면서 정규표현식의 효용을 확인하고, 3중반복문순열을 재귀함수를 이용하여 풀어보았다.

⭐️ 정표현식의 효용!!

// 아래의 배열에서 0 이 3개 이상 들어있는 인자를 재거하는 배열 freshArr를 만들어야한다.

const stuffArr = [11, 1, 10, 1111111111, 10000];
//빈배열을 선언하고
let freshArr = [];

// 반복문을 이용해 모든인자를 순회한다
for (let i = 0; i < stuffArr.length; i++) {
  // 각 인자의 0만을 인자로 갖는 배열을 만든다.
  const element = String(stuffArr[i])
    .split('')
    .filter((e) => e === '0');
  // 만든배열의 길이가 2개 이하일경우만 freshArr에 넣는다.
  if (element.length <= 2) {
    freshArr.push(stuffArr[i]);   
  }
}

console.log(freshArr) // > [ 11, 1, 10, 1111111111 ]

// 😎 정규표현식을 사용해보자!!
let freshArr2 = stuffArr.filter((el) => !String(el).match(/0{3,}/g));
// 이렇게 짧게 가능하다.
// 정규표현식은 string type에 사용가능하기에 인자를 시트링으로 변화시킨후에 정규표현식을 사용한다.
// /0{3,}/g  => 해당 인자에 0 이 연속으로 3개 이상일 경우 참을 반환하기때문에 !을이용해 반대의경우만 배열로 만든다.
console.log(freshArr2) // > [ 11, 1, 10, 1111111111 ]

// 하지만 문제는 0이 3개이상이다. 연속으로 3개 이상인경우 뿐만아니라 불연속이여도 총 0이 3개일경우 배제시켜야한다.
// 다시 정규표현식을 만들면 아래와 같다.
let freshArr3 = stuffArr.filter((el) => {
    return !String(el).match(/0/g) ? true : String(el).match(/0/g).length < 3;
});
// 정규표현식 /0/g를 사용하여 인자에 있는 0만을 인자로 같는 배열을 만든다. 그리고 그 길이를 이용해 0의 개수를 확인 할 수 있다.
// 단 없을 경우 null이 반환 되기 때문에 삼항 연산자를 이용했다.
console.log(freshArr3) // > [ 11, 1, 10, 1111111111 ]

// 익숙하지 않은 정규표현식이지만 코드를 좀더 효율적으로 짤수 있다는걸 몸소 경험했다.!

⭐️ 조합재귀함수!

// 중복되지 않는 카드를 여러장 받아서 그중 3장을 뽑아 만들수 있는 소수의 개수를 반환 하는 함수!

function boringBlackjack(cards) {
  // 카드 3장씩 조합.
  // 조합된 3장의 카드 합을 구하고 소수인지확인
  // 소수일 경우 카운트 +1
  // 조합된 모든카드를 확인하면 카운트 반환

  // 소수 확인 함수
  const isPrime = (num) => {
    if (num === 1) return false;
    if (num === 2) return true;
    if (num % 2 === 0) return false;
    let sqrt = parseInt(Math.sqrt(num));
    for (let i = 3; i <= sqrt; i += 2) {
      if (num % i === 0) {
        return false;
      }
    }
    return true;
  };

  let count = 0;
  // cards = cards.sort((a, b) => a - b);
  
  // 재귀함수 부분!
  const checkPrime = (idx, basket, n) => {
    // 추가확인카드가 없으면 리턴.
    // 탈출!
    // 배열을 만드는것이 목적이아니고 소수를 카운트하는게 목적!
    if (n === 0 && isPrime(basket)) {
      count++;
      return;
    }
	// 반복문을 이용하면 3중 for문을 이용할 수 있다.
    for (let i = idx; i < cards.length; i++) {
      const select = cards[i];
      // 조합이기때문에 배열의 순서는 무관하다.
      // 때문에 재귀가 실행될때마다초기 인덱스 값을 1씩 늘려가며 중복되는 배열을 만들이 않도록 했다.!
      
      checkPrime(i + 1, basket + select, n - 1);
    }
  };
  checkPrime(0, 0, 3);
  return count;
}
profile
함께 일하고싶은 개발자

0개의 댓글