3장 자바스크립트 숫자

  • 자바스크립트에서는 숫자에 대해 64비트 부동소수점 표현을 사용한다
    → 부호 1비트 + 지수 11비트 + 소수 52비트
  • 십진분수로 인해 반올림 오류를 일으킬 수 있다 0.1 + 0.2 === 0.3; // false
  • Number 객체에 내장된 속성들
    1. 정수 반올림
      1
      2
      3
      Math.floor // 내림
      Math.round // 반올림
      Math.ceil // 올림
    2. Number.EPSILON : 두 개의 표현 가능한 숫자 사이의 가장 작은 간격을 리턴함
    3. 가장 큰 정수 : Number.MAX_SAFE_INTEGER
      Number.MAX_SAFE_INTEGER + 1 === Number.MAX_SAFE_INTEGER + 2 // true
    4. 가장 작은 정수 : Number.MIN_SAFE_INTEGER
      Number.MIN_SAFE_INTEGER - 1 === Number.MIN_SAFE_INTEGER - 2 // true
    5. 양의 무한(Infinity)값은 Number.MAX_SAFE_INTEGER보다 큰 유일한 값이며 음의 무한(-Infinity)값은 Number.MIN_SAFE_INTEGER보다 작은 유일한 값이다
  • 숫자 알고리즘
    1. 소수 테스트
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      function isPrime(n) {
      if (n <= 1) return false;

      for (let i = 2 i < n; i++){
      if (n%i == 0) {
      return false
      }
      }
      return true
      }
      // 시간 복잡도 O(n)
      1-1. 개선된 소수 테스트
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      // 소수는 6k±1의 형태를 지님
      // ex) 5 = 6-1, 7 = ((1*6) + 1), 13 = ((2*6) + 1) 등

      function isPrimeAdvanced(n) {
      if (n <= 1) return false
      if (n <= 3) return true

      if (n%2 == 0 || n%3 == 0) return false;

      for (let i = 5; i * i <= n; i=i+6){
      if (n%i == 0 || n % (i+2) == 0) return false;
      }
      return true;
      }
      // 시간 복잡도 O(sqrt(n))
    2. 소인수분해
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      function primeFactors(n) {
      while (n%2 == 0) {
      console.log(2);
      n = n/2
      }
      // n%2가 0이 아닐때까지 나눠 n은 이 시점에서 홀수가 됨
      for (let i = 3; i * i <= n; i = i+2){
      // i가 n을 나눌 수 있는 한 계속해서 i가 출력되고 n을 i로 나눈다
      while (n%i == 0) {
      n = n/i
      }

      if (n > 2) {
      console.log(n);
      }
      }
      }
      primeFactors(10) // 5, 2를 출력
      // 시간 복잡도 O(sqrt(n))
    3. 무작위 수 생성
      1
      Math.random() * n + x // x부터 (n+x)까지의 랜덤한 정수를 생성한다
    4. 모듈러 제곱거듭(modular exponentiation) : 단순한 계산법
      1
      2
      3
      const modularExponentiation = (x, y, p) => {
      return Math.pow(x, y) % p
      }
      4-1. 모듈러 제곱거듭(modular exponentiation) : 큰 지수도 다룰 수 있는 함수
      → 임의의 a와 b에 대해 c % m = [(a % m)(b % m)] % m이 성립
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      const modularExponentiation = (base, exponent, modulus) => {
      if (modulus == 1) return 0;

      // 1. 값 = 1로 설정한다. 지수는 0이다
      let value = 1;

      // 2. 현재 지수를 1만큼 증가시킨다
      for (let i = 0; i < exponent; i++) {
      // 3. 현재 지수가 목표의 지수가 될 때까지
      // '값 = (값 x 기저) % 모듈러'를 반복한다
      value = (value * base) % modulus;
      }
      return value;
      }
      ```
      5. n보다 작은 소수 찾기
      ```javascript
      const allPrimesLessThanN = n => {
      for (let i = 0; i < n; i++){
      if (isPrime(i)) console.log(i);
      }
      }

      const isPrime = n => {
      if (n <= 1) return false
      if (n <= 3) return true

      if (n%2 == 0 || n%3 == 0) return false;

      for (let i = 5; i * i <= n; i=i+6){
      if (n%i == 0 || n % (i+2) == 0) return false;
      }
      return true;
      }
    5. 소인수 집합 확인
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      // 모든 소인수는 2와 3과 5로 나눠질 수 있다
      const maxDivide = (number, divisor) => {
      while (number % divisor === 0) number /= divisor;
      return number
      } // 시간 복잡도는 O(divisor를 밑으로 하는 log (number))

      const isPrimeFactor = number => {
      number = maxDivide(number, 2)
      number = maxDivide(number, 3)
      number = maxDivide(number, 5)
      return number === 1;
      } // 시간 복잡도는 O(log2(n))

      const primeFactorArr = n => {
      let count = 0, currNum = 1, primeNums = [];

      while (count != n) {
      if (isPrimeFactor(currNum)) {
      count++;
      primeNums.push(currNum)
      }
      currNum++
      }
      return primeNums;
      } // 시간 복잡도는 O(n(log2(n))) O(n번 * isPrimeFacor의 BigO 값)

      4장 자바스크립트 문자열

  • 자바스크립트의 기본 자료형인 String에는 다양한 함수가 존재
  1. 문자에 접근할 때엔 .charAt()을 사용한다 'dog'.charAt(1) // "o"
    1-1. substring(startIdx, endIdx)을 사용하면 지정된 값 사이의 문자열의 리턴이 가능하다
    1-2. 이때 endIdx를 입력하지 않는다면 자동으로 문자열 마지막까지 리턴한다
  2. 문자열을 비교할 때에는 < 나 > 기호를 통해 쉽게 비교할 수 있다
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    let a = 'a'
    let b = 'b'
    console.log(a < b) // true
    /*------------------------------*/
    // 길이가 다른 문자열을 비교한다면 문자열의 시작부터 비교하여
    // 더 짧은 길이의 문자열길이만큼만 비교한다
    a = 'add'
    b = 'b'
    console.log(a < b) // true
    /*------------------------------*/
    a = 'add'
    b = 'ab'
    console.log(a < b) // false
  3. 문자열 내 특정 문자열을 찾기 위해 .indexOf(searchValue[, fromIndex])를 사용할 수 있다
    3-1. 검색하고자하는 문자열을 매개변수로 받으며 선택적으로 검색 시작의 인덱스를 받을 수 있다
    3-2. 이 함수는 일치하는 문자열의 위치를 리턴하며 대소문자를 구분한다
    3-3. 없다면 -1을 리턴하므로 -1을 반환하는지 아닌지를 확인하면 된다
  4. 문자열을 분해할 때에는 .split(separator)를 사용할 수 있으며 분리자 매개변수를 받아 부분 문자열 배열을 생성한다
  5. .replace(string, replaceString)함수는 문자열 내 특정 문자열을 대체하는 함수이다
  6. 정규 표현식은 검색 패턴을 정의한 문자열의 집합으로 기본 객체 RegExp를 사용할 수 있다
    6-1. RegExp의 생성자는 정규 표현식과 일치 관련 설정의 두 가지 매개변수를 받는다
    6-2. i는 대소문자를 구분하지 않고 일치하는 문자열을 검색하며, g는 전역적으로 ((모든) 문자열을 검색하며, m은 다중열 문자열에 대해서도 일치하는 문자열을 검색한다
    6-3. RegExp는 search()와 match() 함수가 존재하며 search()는 찾은 문자열의 인덱스를, match()는 모든 일치하는 문자열을 리턴한다
    6-4. String 객체에서 RegExp를 매개변수로 받는 함수는 일치하는 문자열을 찾는 exec()와 문자열을 찾아 boolean값을 리턴하는 test()가 있다
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    <--- 기본 정규 표현식 --->
    ^ :문자열/줄의 시작을 나타냄
    \d : 모든 숫자를 찾는다
    [abc]/[^abc] : 괄호 내 모든 문자를 찾는다 / 제외한 문자열을 찾는다
    [0-9]/[^0-9] : 괄호 내 모든 숫자를 찾는다 / 제외한 숫자를 찾는다
    (x|y) : x나 y 문자열을 찾는다
    <--- 자주 사용되는 정규 표현식 --->
    /\d+/ : 숫자를 포함하는 문자
    /^\d+$/ : 숫자만 포함하는 문자
    /^[0-9]*.[0-9]*[1-9]+$/ : 부동 소수점 문자
    /[a-zA-Z0-9]/ : 숫자와 알파벳만 포함하는 문자
    /([^?=&])(=([^&]*))/ : 질의 문자열
  7. 자바스크립트의 base() 함수는 문자열로부터 Base64 인코딩된 ASCII 문자열을 생성하며 atob() 함수는 Base64 인코딩된 문자열을 디코딩하는 함수이다
    7-1. 단축 URL은 이 base() 함수를 응용하여 사용하는 것이다
  8. RSA 암호화는 키 생성, 암호화, 복호화의 3단계가 있으며 매우 큰 소수를 사용하여 소인수분해(4096비트 소수 곱을 사용)의 역계산을 어렵게 한다

Comment and share

1장 빅오 표기법

O(1)은 신성하다 - 하미드 티주쉬

  • 빅오 표기법 기초

    • 빅오 표기법에서 n은 입력의 개수를 나타낸다
    • “n이 무한으로 접근할 때 무슨 일이 일어날까?”
      일반적인 빅오 복잡도 그래프
  • 계수 법칙 : “상수를 제거하라”

  • *

    상수 k > 0인 경우 f(n)이 O(g(n)이면 kf(n)은 O(g(n))이다
    **

    1
    2
    3
    4
    5
    6
    function Coefficient(n) {
    let count = 0;
    for (let i = 0; i < n; i++) count += 1
    return count;
    }
    // Coefficient(n)의 복잡도는 O(n)
  • 합의 법칙 : “빅오를 더하라”

  • *

    f(n)이 O(h(n))이고 g(n)이 O(p(n))이라면 f(n)+g(n)은 O(h(n)+p(n))이다
    **

    1
    2
    3
    4
    5
    6
    7
    function SumBigO(n) {
    let count = 0;
    for (let i = 0; i < n; i++) count += 1;
    for (let i = 0; i < 5*n; i++) count += 1;
    return count;
    }
    // SumBigO(n)의 복잡도는 O(n + 5n) = O(n)이 된다
  • 곱의 법칙 : “빅오를 곱하라”

  • *

    f(n)이 O(h(n))이고 g(n)이 O(p(n))이라면 f(n)g(n)은 O(h(n)p(n))이다
    **

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    function MultipleBigO(n) {
    let count = 0;
    for (let i = 0; i < n; i++) {
    count += 1;
    for (let i = 0; i < 5*n; i++)
    count += 1;
    }
    return count;
    }
    // MultipleBigO(n)의 복잡도는 O(n^2)
  • 다항 법칙 : “빅오의 k승”

  • *

    f(n)이 k차 다항식이라면 f(n)은 O(n^k)이다
    **

    1
    2
    3
    4
    5
    6
    7
    8
    9
    function PolynomialBigO(n) {
    let count = 0;
    for (let i = 0; i < n*n; i++) {
    count += 1;

    }
    return count;
    }
    // PolynomialBigO(n)의 복잡도는 O(n^2)

    2장 자바스크립트의 독특한 특징

  • 자바스크립트는 동적 인터프리터 프로그래밍 언어이기 때문에 다른 객체지향 프로그래밍 언어들과는 구문이 다름

  • 자바스크립트의 범위(scope)

    • 전역 선언: 전역 범위
      → 전역 선언은 안좋은 방법이므로 되도록 사용하지 말 것
    • var를 사용해 선언 : 함수 범위
      → var를 사용하면 변수를 어디에 선언하더라도 함수의 맨 앞으로 이동한다
      → 이를 변수 호이스팅(variable hoisting)이라고도 한다
      1
      2
      3
      4
      5
      6
      7
      8
      9
      function scope1() {
      var top = "top"
      bottom = "bottom";
      console.log(bottom)

      var bottom;
      }
      // bottom은 맨 마지막에 선언되었지만
      // console.log() 앞으로 hoisting되며 오류 없이 실행된다
    • var로 선언된 해당 변수의 범위가 가장 가까운 함수 범위가 된다
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      function scope2(print) {
      if (print) {
      var insideIf = '12';
      }
      console.log(insideIf);
      }
      scope2(true);

      function scope2_copy(print) {
      var insideIf;
      if (print) {
      insideIf = '12';
      }
      console.log(insideIf);
      }
      scope2_copy(true);
      // scope2와 scope2_copy는 동일하게 실행된다
    • let를 사용해 선언 : 블록 범위
      → 변수가 선언된 블록 범위({})내에서 유효하다
      1
      2
      3
      4
      5
      6
      7
      8
      9
      function scope3(print) {
      if(print) {
      let insideIf = '12'
      }
      console.log(insideIf);
      }
      scope3(true);
      // 오류가 발생함 let은 블록 범위에서만 유효하기 때문에
      // if문을 벗어나면 해당 변수를 읽을 수 없다
  • 등가와 형

    • 자바스크립트에는 boolean, number, string, undefined, object, function, symbol과 같은 일곱가지의 기본 자료형이 존재함
    • 값이 선언만 되고 값이 할당되지 않으면 undefined가 됨
    • 타 언어에서 대개 if문 내 매개변수는 boolean형이어야 하지만 자바스크립트에서는 해당 변수가 비었거나 null이거나 undefined라면 false로 평가된다
    • false로 인식되는 값은 false 외에 0, ‘’(혹은 “”), NaN, undefined, null가 있고 0이 아닌 숫자, 비어있지 않은 문자열이나 객체를 true로 평가한다
    • 자바스크립트는 스크립트 언어이기 때문에 코드가 실행될 때 해당 변수의 형이 해석된다
    • ==는 값만 확인하지만 ===는 형과 값을 모두 확인 한다
      "5" == 5 // true vs "5" === 5 // false
    • 자바스크립트에서 동일한 속성과 값을 갖는 두 객체가 동일한지 확인하고자 ==를 사용한다면 변수의 메모리 주소가 다르기 때문에 false를 리턴할 것이다
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      function isEquivalent(a,b) {
      var aProps = Object.getOwnPropertyNames(a);
      var bProps = Object.getOwnPropertyNames(b);

      // 길이가 다르다면 두 객체는 다른 객체임
      if (aProps.length != bProps.length) return false
      for (var i = 0; i < aProps.length; i++) {
      var propName = aProps[i];

      // 속성값이 다른 경우 두 객체는 같지 않다
      if(a[propName] !== b[propName]) return false
      }

      return true;
      }
      isEquivalent({'hi':12},{'hi':12}); // true

Comment and share

Harry Kim

author.bio


author.job