Language/Dart

[Exercism] Anagram #sort!!!!!

paran21 2022. 9. 21. 21:21

https://exercism.org/tracks/dart/exercises/anagram

 

Anagram in Dart on Exercism

Can you solve Anagram in Dart? Improve your Dart skills with support from our world-class team of mentors.

exercism.org

 

word와 list가 주어지고, list 안에서 word의 글자들을 바꾼 경우(즉 각 알파벳의 개수도 같아야 한다)에 해당하는 단어들만 찾는 문제이다.

대소문자를 구분하지 않고 완전히 일치하는 경우에는 답이 아니다.

 

처음에 문제를 풀었던 방식은 다음과 같다.

결국 알파벳 하나하나를 살펴봐야 하니까 for문을 돌릴 수 밖에 없다고 생각했다.

class Anagram {
  List<String> findAnagrams(String word, List<String> list) {
    List<String> answer = [];
    
    for (String element in list) {
      // 비교하지 않아도 일치하지 않는 경우
      if (word.length != element.length) continue;
      if (word.toLowerCase() == element.toLowerCase()) continue;
      
      List<String> words = word.toLowerCase().split('');
      // 일치하는 알파벳이 있으면 remove
      for (int i = 0; i < element.length; i++) {
        if (words.contains(element[i].toLowerCase())) words.remove(element[i].toLowerCase());
      }
      // lengh가 0이면 모두 일치했다는 의미이므로 답
      if (words.length == 0 ) answer.add(element);
    }
    return answer;
  }
}

 

다음 풀이는 커뮤니티 답안을 참고한 방법이다.

결국 단어를 비교하기 위해서 알파벳 배열로 만드는 부분은 word나 list안에 있는 비교 대상 element나 동일한 로직이기 때문에 makeKey라는 별도의 메서드로 만들었고, 순서를 sort해서 앞에서부터만 비교해도 되도록 하였다.

class Anagram {
  String makeKey(String word) {
    List<String> words = word.toLowerCase().split('');
    words.sort();
    return words.toString();
  }
  
  List<String> findAnagrams(String word, List<String> list) {
    return list
        .where((element) =>
            (makeKey(word) == makeKey(element)) &&
            (element.toLowerCase() != word.toLowerCase()))
        .toList();
  }
}

이런 케이스를 처음 본 것도 아닌데 계속 순서가 다른 경우는 어떻게 하지, 라고 고민을 했었는데 이럴 때는 정렬을 이용하면 된다!