7

I have this code using collections Counter to find the number of common letters in two strings.

from collections import Counter

a = "abcc"
b = "bcaa"

answer = 0

ac = Counter(a)
bc = Counter(b)

for key in ac:
    answer += min(ac[key], bc[key])

print answer

The solution tries to find the number of common letters in both strings(Same letters still counted) My question is, I developped this logic but I fear it may be a wheel reinvented. Are there any introduced methods, or an easier way of doing this ?

Note: My question is different than the questions that tries to find the common letters between strings, I just need the count so I expect to find something basic.

Max Paython
  • 1,595
  • 2
  • 13
  • 25
  • 1
    can you clarify if the function should return the absolute number of common characters (as described in Ahsanul Haque's answer) or the total number of common characters (including duplicates of characters found in each string)? – lesingerouge May 04 '16 at 11:17
  • I added it in a comment in his answer. – Max Paython May 04 '16 at 11:21
  • @MaxPythone Please do not add important information in comments (only), especially not in comments below answers. Answers and comments can occasionally get deleted for various reason and then your information is lost. Also, people would have to read all answers and comments before being able to understand your problem correctly, which is bad. Please always [edit] your question to add new information and then notify the people interested in it using comments. – Byte Commander May 04 '16 at 11:23
  • 2
    I *personally don't know* any more straightforward code to achieve the same as your approach. – Byte Commander May 04 '16 at 11:27
  • can i assume the strings will be in equal length? should i do one count for one pair? – SuperNova May 04 '16 at 12:20
  • Their lengths can be different. – Max Paython May 04 '16 at 12:25
  • if strings are 'aaab' and 'accc' what is the count in this case.? – SuperNova May 04 '16 at 13:16
  • @Trying2Learn It is 1, you can say that corresponded letter is removed temporarily to countinue counting. – Max Paython May 06 '16 at 09:22

4 Answers4

2

No, as far as I know, you did not reinvent the wheel. Your solution is very concise already. You could shorten the code a bit using the sum function and then put it into a dedicated function to emphasize the simplicity:

def num_common_letters(a, b):
    ac = Counter(a)
    bc = Counter(b)
    return sum(min(ac[key], bc[key]) for key in ac)

There's not much to strip away here.

Frerich Raabe
  • 90,689
  • 19
  • 115
  • 207
0

IMHO slightly better than Frerich Raabe good answer (that I didn't see, this answer has been migrated from a duplicate question), I would count letters from both strings using the classic collections.Counter, then perform the minimum function between dictionaries (if a letter isn't in the second dict, accessing it returns 0 so no need to test for value in the second dictionary)

import collections

def common_character_count(s1,s2):
    other_counter = collections.Counter(s2)
    return (sum(min(v,other_counter[k]) for k,v in collections.Counter(s1).items()))


print(common_character_count("aabcc","adcaa"))

prints 3

the use of .items() saves one key access to the first counter dictionary.

Jean-François Fabre
  • 137,073
  • 23
  • 153
  • 219
0

This was asked to me in an interview. There is a better way of doing it. Take a count of 26 characters and then take the min. here is the complete solution :

from astropy.extern.ply.cpp import xrange


def commoncharacters(a, b):
    count1 = [0] * 26 ; count2 = [0] * 26
    for i in a: count1[ord(i) - ord('a')] += 1 ;
    for i in b: count2[ord(i) - ord('a')] += 1 ;
    res = 0
    for i in xrange(26):
        res += min(count1[i], count2[i])

    return res    


# driver function
a = "giniProtijayi"
b = "ginikhepi"

print(commoncharacters(a, b))
Soudipta Dutta
  • 1,353
  • 1
  • 12
  • 7
-1

To count occurrences of a letter in the strings, you could use a dictionary;

a = "abcc"
counter = {}


for key in a:
    if key in counter:
        counter[key]+=1
    else:
        counter[key]=1

counter

{'a': 1, 'b': 1, 'c': 2}
Daniel
  • 473
  • 4
  • 9