Using Python, find anagrams for a list of words

前端 未结 22 902
失恋的感觉
失恋的感觉 2020-12-13 01:11

If I have a list of strings for example:

[\"car\", \"tree\", \"boy\", \"girl\", \"arc\"...]

What should I do in order to find anagrams in t

22条回答
  •  谎友^
    谎友^ (楼主)
    2020-12-13 01:33

    There are multiple solutions to this problem:

    1. Classic approach

      First, let's consider what defines an anagram: two words are anagrams of each other if they consist of the same set of letters and each letter appears exactly the same number or time in both words. This is basically a histogram of letters count of each word. This is a perfect use case for collections.Counter data structure (see docs). The algorithms is as follows:

      • Build a dictionary where keys would be histograms and values would be lists of words that have this histogram.
      • For each word build it's histogram and add it to the list that corresponds to this histogram.
      • Output list of dictionary values.

      Here is the code:

      from collections import Counter, defaultdict
      
      def anagram(words):
          anagrams = defaultdict(list)
          for word in words:
              histogram = tuple(Counter(word).items()) # build a hashable histogram
              anagrams[histogram].append(word)
          return list(anagrams.values())
      
      keywords = ("hi", "hello", "bye", "helol", "abc", "cab", 
                      "bac", "silenced", "licensed", "declines")
      
      print(anagram(keywords))
      

      Note that constructing Counter is O(l), while sorting each word is O(n*log(l)) where l is the length of the word.

    2. Solving anagrams using prime numbers

      This is a more advanced solution, that relies on the "multiplicative uniqueness" of prime numbers. You can refer to this SO post: Comparing anagrams using prime numbers, and here is a sample python implementation.

提交回复
热议问题