Checking if two strings are permutations of each other in Python

前端 未结 22 2298
旧时难觅i
旧时难觅i 2020-12-08 16:04

I\'m checking if two strings a and b are permutations of each other, and I\'m wondering what the ideal way to do this is in Python. From the Zen of

相关标签:
22条回答
  • 2020-12-08 16:21

    I think the first one is the "obvious" way. It is shorter, clearer, and likely to be faster in many cases because Python's built-in sort is highly optimized.

    0 讨论(0)
  • 2020-12-08 16:22

    In Python 3.1/2.7 you can just use collections.Counter(a) == collections.Counter(b).

    But sorted(a) == sorted(b) is still the most obvious IMHO. You are talking about permutations - changing order - so sorting is the obvious operation to erase that difference.

    0 讨论(0)
  • 2020-12-08 16:23

    "but the first one is slower when (for example) the first char of a is nowhere in b".

    This kind of degenerate-case performance analysis is not a good idea. It's a rat-hole of lost time thinking up all kinds of obscure special cases.

    Only do the O-style "overall" analysis.

    Overall, the sorts are O( n log( n ) ).

    The a.count(char) for char in a solution is O( n 2 ). Each count pass is a full examination of the string.

    If some obscure special case happens to be faster -- or slower, that's possibly interesting. But it only matters when you know the frequency of your obscure special cases. When analyzing sort algorithms, it's important to note that a fair number of sorts involve data that's already in the proper order (either by luck or by a clever design), so sort performance on pre-sorted data matters.

    In your obscure special case ("the first char of a is nowhere in b") is this frequent enough to matter? If it's just a special case you thought of, set it aside. If it's a fact about your data, then consider it.

    0 讨论(0)
  • 2020-12-08 16:23
    from collections import defaultdict
    def permutation(s1,s2):
        h = defaultdict(int)
        for ch in s1:
            h[ch]+=1
        for ch in s2:
            h[ch]-=1
        for key in h.keys():
            if h[key]!=0 or len(s1)!= len(s2):
                return False
            return True
    print(permutation("tictac","tactic"))
    
    0 讨论(0)
  • 2020-12-08 16:25

    Here is a way which is O(n), asymptotically better than the two ways you suggest.

    import collections
    
    def same_permutation(a, b):
        d = collections.defaultdict(int)
        for x in a:
            d[x] += 1
        for x in b:
            d[x] -= 1
        return not any(d.itervalues())
    
    ## same_permutation([1,2,3],[2,3,1])
    #. True
    
    ## same_permutation([1,2,3],[2,3,1,1])
    #. False
    
    0 讨论(0)
  • 2020-12-08 16:25

    In Swift (or another languages implementation), you could look at the encoded values ( in this case Unicode) and see if they match.

    Something like:

    let string1EncodedValues = "Hello".unicodeScalars.map() {
    //each encoded value
    $0
    //Now add the values
    }.reduce(0){ total, value in
        total + value.value
    }
    
    let string2EncodedValues = "oellH".unicodeScalars.map() {
        $0
        }.reduce(0) { total, value in
        total + value.value
    }
    
    let equalStrings = string1EncodedValues == string2EncodedValues ? true : false
    

    You will need to handle spaces and cases as needed.

    0 讨论(0)
提交回复
热议问题