Reputation: 716
I am trying to solve the above interview question to check if string are anagram of each other. The implementation is as follows:
NO_OF_CHARS = 256
def areAnagram(str1, str2):
count = [0] * NO_OF_CHARS
i = 0
while (i in str1) and (i in str2):
count[ord(i)]+=1
i += 1
if len(str1) != len(str2):
return 0
for i in xrange(NO_OF_CHARS):
if count[i]:
return 0
return 1
str1 = "geeksforgeeks"
str2 = "forgeeksgeeks"
if areAnagram(str1, str2):
print "The two strings are anagram of each other"
else:
print "The two strings are not anagram of each other"
I am getting the following error while running the code:
TypeError: 'In <string> requires string as left operand
Am I doing something wrong in the while loop? Also, how can I avoid to use i = 0 statement? Thanks.
Upvotes: 1
Views: 746
Reputation: 1547
An easy way to see if strings are comprised of the same characters is to compare them as sorted lists:
def is_anagram(src, trgt):
"""
Determine if trgt is an anagram of src
:param src: (str)
:param trgt: (str)
:returns: (bool) True if trgt is an anagram of src; else False
"""
return sorted(src) == sorted(trgt)
Upvotes: 4
Reputation: 104702
The canonical way to do this in Python is to use collections.Counter
:
from collections import Counter
def areAnagram(str1, str2):
return Counter(str1) == Counter(str2)
This should take O(N)
space and time (where N
is max(len(str1), len(str2))
). But do be aware that even though this code's asymptotic performance is better, it may still be slower for short strings than a version using sorted
. Python's sort
code is very fast!
If you're likely to be using the function to compare very-unlike strings, you could perhaps it up a little bit with a special case checking the string lengths before counting:
def areAnagram(str1, str2):
return len(str1) == len(str2) and Counter(str1) == Counter(str2)
Upvotes: 2
Reputation: 89
If you want to go for counting the characters, you need to make counts for both strings and compare them
NO_OF_CHARS = 256
def areAnagram(str1, str2):
if len(str1) != len(str2):
return 0
count = [0] * NO_OF_CHARS
for c1,c2 in zip(str1,str2):
count[ord(c1)] +=1
count[ord(c2)] -=1
return all(not c for c in count)
I moved checking the length of strings to the beginning of the method for efficiency and clarity
EDIT: Updated my answer according to Blckknght's comment
Upvotes: 2