1- # *-coding:utf8-*
1+ from typing import Dict
22from functools import reduce
33from string import ascii_letters
44
55from pymath .primes .is_prime import is_prime_with_re
66
77
8+ def is_anagram (s1 : str , s2 : str ) -> bool :
9+ """
10+ Check if s1 is an anagram of s2.
11+ Args:
12+ s1 (str): first string to check
13+ s2 (str): second string to check
14+ Return:
15+ bool: Whether the strings are anagrams of each other. If they are True is returned, False otherwise
16+ """
17+ # first normalize the strings by removing white spaces which might result in uneven lengths if s1 and s2 are anagrams
18+ # of each other
19+ s1 = s1 .replace (" " , "" ).lower ()
20+ s2 = s2 .replace (" " , "" ).lower ()
21+
22+ # check the length of the strings. If the strings are not of the same length, then it's not possible for them to be
23+ # anagrams of each other
24+ if len (s1 ) != len (s2 ):
25+ return False
26+
27+ # This dictionary is used to keep track of the character count in the strings to check if the strings are anagrams
28+ # of each other, the character count must be equal in both strings. This enables the algorithm to keep track of this
29+ # count.
30+ ht : Dict [str , int ] = dict ()
31+
32+ # Loop through each character in the first string to count the number of characters and store them in the dictionary
33+ # this is linear, so, O(n) where n is the number of characters in the string as the loop has to iterate over each
34+ # character
35+ for char in s1 :
36+ if char in ht :
37+ ht [char ] += 1
38+ else :
39+ ht [char ] = 1
40+
41+ # Loops through each character in the second string checking for the existence of that character in the already
42+ # populated dictionary. If a character, exists, the count is decremented, if not, the count is incremented. This
43+ # will be used to show the discrepancy in character count between the two strings
44+ for char in s2 :
45+ if char in ht :
46+ ht [char ] -= 1
47+ else :
48+ ht [char ] = 1
49+
50+ # Finally, check each key in the dictionary. If a given key's count is not equal to 0, then the algorithm exits
51+ # early as it's not possible to have a character count of more than 0 for strings that are anagrams, since the above
52+ # loop should have reduced the character count to 0. This shows a discrepancy, meaning there is an extra character
53+ # in a string that is not in another string
54+ for key in ht :
55+ if ht [key ] != 0 :
56+ return False
57+
58+ # return true if all the checks above check out.
59+ return True
60+
61+
862class Anagrams :
963 """
1064 Anagram class to detect anagrams for letters
@@ -25,43 +79,10 @@ def detect_anagrams(self, word, word_list):
2579 res , word = [], word .lower ()
2680 for x in word_list :
2781 if len (word ) == len (x .lower ()) and word != x .lower ():
28- if self . is_anagram (word , x .lower ()):
82+ if is_anagram (word , x .lower ()):
2983 res .append (x )
3084 return res
3185
32- @staticmethod
33- def is_anagram (s1 , s2 ):
34- """
35- Check if s1 is an anagram of s2
36- :param s1: String to check
37- :param s2: string to compare to
38- :return: Whether the strings are anagrams
39- :rtype: bool
40- """
41- if len (s1 .lower ()) != len (s2 .lower ()):
42- return False
43-
44- a_list = list (s2 )
45- pos1 = 0
46- flag = True
47-
48- while pos1 < len (s1 ) and flag :
49- pos2 = 0
50- found = False
51- while pos2 < len (a_list ) and not found :
52- if s1 [pos1 ] == a_list [pos2 ]:
53- found = True
54- else :
55- pos2 += 1
56-
57- if found :
58- a_list [pos2 ] = None
59- else :
60- flag = False
61-
62- pos1 += 1
63-
64- return flag
6586
6687 def anagram_count (self , parent , child ):
6788 """
@@ -87,7 +108,7 @@ def anagram_count(self, parent, child):
87108 # if the child's length is the same as the parent length AND the child and parent are not the same
88109 # check if it is an anagram
89110 if len (child ) == len (parent ) and child != parent :
90- if self . is_anagram (child , parent ):
111+ if is_anagram (child , parent ):
91112 return 1
92113 else :
93114 return 0
0 commit comments