简体   繁体   中英

Finding anagrams in Python

I solved this problem the following way in Python:

s1,s2 = raw_input().split()
set1 = set(s1)
set2 = set(s2)
diff = len(set1.intersection(s2))
if(diff == 0)
    print "Anagram!" 
else:
    print "Not Anagram!" 

It seemed fine to me. But my professor's program said I'm missing some edge cases. Can you think of any edge cases I might have missed?

The correct way to solve this would be to count the number of characters in both the strings and comparing each of them to see if all the characters are the same and their counts are the same.

Python has a collections.Counter to do this job for you. So, you can simply do

from collections import Counter

if Counter(s1) == Counter(s2):
    print "Anagram!" 
else:
    print "Not Anagram!"

If you don't want to use Counter , you can roll your own version of it, with normal dictionaries and then compare them.

def get_frequency(input_string):
    result = {}
    for char in input_string:
        result[char] = result.get(char, 0) + 1
    return result

if get_frequency(s1) == get_frequency(s2):
    print "Anagram!" 
else:
    print "Not Anagram!"

use sorted :

>>> def using_sorted(s1,s2):
...     return sorted(s1)==sorted(s2)
... 
>>> using_sorted("hello","llho")
False
>>> using_sorted("hello","llhoe")
True

you can also use count :

>>> def using_count(s1,s2):
...     if len(s1)==len(s2):
...         for x in s1:
...             if s1.count(x)!=s2.count(x):
...                 return False
...         return True
...     else: return False
... 
>>> using_count("abb","ab")
False
>>> using_count("abb","bab")
True
>>> using_count("hello","llohe")
True
>>> using_count("hello","llohe")

sorted solution runs in O(n lg n) complexity and the count solution runs in O(n ^ 2) complexity, whereas the Counter solution in runs in O(N).

Note collections.Counter is better to use
check @fourtheye solution

Another way without sorting considering all are alphabets:

>>> def anagram(s1, s2):
...     return sum([ord(x)**2 for x in s1]) == sum([ord(x)**2 for x in s2])
...
>>> anagram('ark', 'day')
False
>>> anagram('abcdef', 'bdefa')
False
>>> anagram('abcdef', 'bcdefa')
True
>>>

Don't do it with set Theory:

Code:

a='aaab'
b='aab'

def anagram(a,b):
        setA=list(a)
        setB=list(b)
        print setA, setB
        if len(setA) !=len(setB):
                print "no anagram"
        diff1 =''.join(sorted(setA))
        diff2= ''.join(sorted(setB))
        if (diff1 == diff2 ):
                print "matched"
        else:
                print "Mismatched"
anagram(a,b)

the anagram check with two strings

def anagrams (s1, s2): 
  
    # the sorted strings are checked  
    if(sorted(s1.lower())== sorted(s2.lower())): 
        return True  
    else: 
        return False

check anagram in one liner

def anagram_checker(str1, str2):
    """
    Check if the input strings are anagrams of each other
    Args:
       str1(string),str2(string): Strings to be checked
    Returns:
       bool: Indicates whether strings are anagrams
    """
    return sorted(str1.replace(" ", "").lower()) == sorted(str2.replace(" ", "").lower())

print(anagram_checker(" XYZ","zyx"))

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM