[알고리즘 풀이]

Soozynn·2021년 11월 6일
0

- firstNonRepeat [반복하지 않는 첫 번째 문자]


첫 번째로 반복되지 않는 값을 찾아라
충족해야 하는 예시 코드

  it("should pass base cases", function () {
    expect(firstNonRepeatedCharacter("ABA")).to.eql("B");
    expect(firstNonRepeatedCharacter("AABCABD")).to.eql("C");
    expect(firstNonRepeatedCharacter("ABCDEFG")).to.eql("A");
  });

  it("should handle special characters", function () {
    expect(firstNonRepeatedCharacter(" ABCD")).to.eql(" ");
    expect(firstNonRepeatedCharacter("A!ABBCCDEF")).to.eql("!");
    expect(firstNonRepeatedCharacter("AAKIE;KIEF")).to.eql(";");

[문제]

  • 문자열에서 중복되지 않는 제일 첫 번째의 값을 가져와야 한다.
  • 특수문자도 해당 조건에 포함된다.

[풀이]

해당 메서드가 일치할 시 주어진 문자열에는 한 개의 요소만 존재함으로 이와 같이 풀이.

export default function firstNonRepeatedCharacter(str) {
  for (let i = 0; i < str.length; i++) {
    const char = str.charAt(i);

    if (str.indexOf(char) === str.lastIndexOf(char)) {
      return char;
    }
  }
 }

사용된 메서드

- indexOf() 어디서 부터 시작할지도 설정할 수 있다.

- lastindexOf() 똑같이 어디서 부터 시작할지 설정 가능




- isAnagram [주어진 문자열로 새로운 단어 만들기]


[문제]

  • 제시된 문자열을 이용하여 새로운 단어를 만든다
  • 특수문자와 띄어쓰기는 상관 없이 주어진 문자열을 빠짐 없이 이용하여 단어를 만들었을 경우 테스트가 통과된다.

충족해야하는 예시 코드

  it("should pass base cases", function () {
    expect("finder".isAnagram("friend")).to.eql(true);
    expect("solver".isAnagram("lovers")).to.eql(true);
    expect("book".isAnagram("boot")).to.eql(false);
  });

  it.only("should ignore special characters", function () {
    expect("Funeral".isAnagram("Real fun")).to.eql(true);
    expect("React DOM".isAnagram("demo")).to.eql(false);
    expect("School master".isAnagram("The classroom")).to.eql(true);
    expect("its you.".isAnagram("suit yoh!")).to.eql(false);
    //expect("Are you study?".isAnagram("your tuesday.")).to.eql(true);
  });

  // TODO: Add more test cases on your own!
});

배운 메서드

- replace(): 특수문자 치환, 제거 용도


[풀이]

 const removeSpecialChar = string.replace("!", "").replace(" ", "").replace(".", "");
    const compareRemoveSpecialChar = this.replace("?", "").replace(" ", "").replace(".", "").replace(" ", "");

    const sortStirng = removeSpecialChar.toLowerCase().split("").sort().join("");
    const sortCompareString = compareRemoveSpecialChar.toLowerCase().split("").sort().join("");

    if (sortStirng === sortCompareString) {
      return true;
    }

    return false;

모든 특수문자를 replace()를 이용하여 제거하고, toLowerCase()를 이용하여 전체 스트링을 소문자로 치환, split()을 이용하여 배열로 만든 뒤 sort() 메서드를 통해 순서대로 정렬 시킨다.
그 후 join() 메서드를 이용하여 배열의 해당 문자열을 모두 합친 뒤 일치하는지 조건문을 이용해 확인한다.

정규식을 쓰지 않기 위해 replace를 여러 번 썼더니 코드가 많이 지저분해진 것 같은데 더 좋은 방법을 찾아봐야겠다. replaceAll()?



- characterFrequency [문자열의 각 요소 빈도를 반환하여라]


[문제]

  • 주어진 문자열의 각 요소와 중복되는 갯수를 이차원 배열로 반환하여라.
충족해야하는 예시 코드

it("should pass base cases", function () {
    expect(characterFrequency("mississippi")).to.eql([
      ["i", 4],
      ["s", 4],
      ["p", 2],
      ["m", 1],
    ]);
    expect(characterFrequency("miaaiaaippi")).to.eql([
      ["a", 4],
      ["i", 4],
      ["p", 2],
      ["m", 1],
    ]);
  });

  it("hee's TC", function () {
    expect(characterFrequency("a")).to.eql([["a", 1]]);
    expect(characterFrequency("pppppppppp")).to.eql([["p", 10]]);
    expect(characterFrequency("abcdefghijklmnopqrstuvwxyz")).to.eql([
      ["a", 1],
      ["b", 1],
      ["c", 1],
      ["d", 1],
      ["e", 1],
      ["f", 1],
      ["g", 1],
      ["h", 1],
      ["i", 1],
      ["j", 1],
      ["k", 1],
      ["l", 1],
      ["m", 1],
      ["n", 1],
      ["o", 1],
      ["p", 1],
      ["q", 1],
      ["r", 1],
      ["s", 1],
      ["t", 1],
      ["u", 1],
      ["v", 1],
      ["w", 1],
      ["x", 1],
      ["y", 1],
      ["z", 1],
    ]);
  });

배운 메서드

  • for...in: 객체에서 사용하는 반복문
    상속된 열거 가능한 속성들을 포함하여 객체에서 문자열로 키가 지정된 모든 열거 가능한 속성에 대해 반복

[풀이]

export default function characterFrequency(string) {
    let charFreq = {};
    const result = [];

    for (let i = 0; i < string.length; i++) {
       const character = string.charAt(i);

       if (charFreq[character]) {⭐️
        charFreq[character]++;
       } else {
        charFreq[character] = 1;
       }
    }

    for (var key in charFreq) {⭐️
       result.push([key, charFreq[key]]);
    }

    result.sort(function (a, b) {🔥
       if (a[1] > b[1]) return -1;
       if (a[1] < b[1]) return 1;

       if (a[1] === b[1]) {
        if (a[0] < b[0]) return -1;
        if (a[0] > b[0]) return 1;
       }

       return 0;
    });
  
    return result;
}

객체의 개념을 제대로 파악하지 못해 처음에 접근을 못하였었는데, 빈 객체를 만들어 준 뒤에 값이 존재하지 않을 경우 value 값으로 1을 넣어주고 값이 존재할 경우 카운팅을 해주는 방식이다.
객체 안에 빈도를 계산해주고 나서 expect 값이 이차원 배열이므로 for...in문을 이용하여 result 에 이차원 배열로 값을 넣어준다. 그런 후 sort 메서드를 이용하여 빈도 값을 정렬시켜준다.

이제 배열 안의 value 값에 따라 내림차순으로 정리를 어떻게 해야하나 싶었는데 mdn에 아래와 같이 설명이 나와있었다.


설명

compareFunction이 제공되지 않으면 요소를 문자열로 변환하고 유니 코드 코드 포인트 순서로 문자열을 비교하여 정렬된다.

예를 들어 "바나나"는 "체리" 앞에 옵니다. 숫자 정렬에서는 9가 80보다 앞에 오지만 숫자는 문자열로 변환되기 때문에 "80"은 유니 코드 순서에서 "9"앞에옵니다.


compareFunction이 제공되면 배열 요소는 compare 함수의 반환 값에 따라 정렬됩니다.
a 와 b 가 비교되는 두 요소라면,

compareFunction(a, b)이 0보다 작은 경우 a를 b보다 낮은 색인으로 정렬합니다. 즉, a 가 먼저옵니다.
compareFunction(a, b)이 0을 반환하면 a 와 b 를 서로에 대해 변경하지 않고 모든 다른 요소에 대해 정렬합니다.

compareFunction(a, b)이 0보다 큰 경우, b 를 a 보다 낮은 인덱스로 소트합니다.
compareFunction(a, b)은 요소 a 와 b 의 특정 쌍이 두 개의 인수로 주어질 때 항상 동일한 값을 반환해야합니다. 일치하지 않는 결과가 반환되면 정렬 순서는 정의되지 않습니다.

따라서 compare 함수의 형식은 다음과 같습니다.
출처 - mdn

function compare(a, b) {
  if (a is less than b by some ordering criterion) { // b보다 a가 작을 경우
    return -1;
  }
  if (a is greater than b by the ordering criterion) { // b보다 클 경우
    return 1;
  }
  // a must be equal to b
  return 0;
}
Copy to Clipboard

0개의 댓글