복붙노트

[PYTHON] 두 문자열이 파이썬에서 서로의 순열인지 확인하기

PYTHON

두 문자열이 파이썬에서 서로의 순열인지 확인하기

두 문자열 a와 b가 서로의 순열인지 검사하고 있으며, 이것을 수행하는 가장 이상적인 방법이 파이썬에서 무엇인지 궁금합니다. Zen of Python에서 "적어도 하나만 - 분명히 할 수있는 분명한 방법이 있어야합니다."하지만 적어도 두 가지 방법이 있습니다.

sorted(a) == sorted(b)

all(a.count(char) == b.count(char) for char in a)

첫 번째 문자는 b에 아무데도 없거나 두 번째 문자가 실제로 순열 (permutation) 일 때 더 느립니다 (예를 들어).

더 많은 Pythonic의 의미로, 또는 평균적으로 더 빠르다는 의미로) 더 좋은 방법이 있습니까? 또는 내가 가장 일반적으로 기대하는 상황에 따라이 두 가지 중에서 선택해야합니까?

해결법

  1. ==============================

    1.경험적으로 문자열 크기에 따라 분리하는 것이 좋습니다.

    경험적으로 문자열 크기에 따라 분리하는 것이 좋습니다.

    의사 코드 :

    returnvalue = false
    if len(a) == len(b)
       if len(a) < threshold
          returnvalue = (sorted(a) == sorted(b))
       else
           returnvalue = naminsmethod(a, b)
    return returnvalue
    

    성능이 중요하고 문자열 크기가 크거나 작을 수 있다면 이것이 내가하는 일입니다.

    입력 크기 나 유형에 따라 이러한 것들을 분리하는 것은 꽤 일반적입니다. 알고리즘은 다른 강점이나 약점을 가지고 있으며, 다른 알고리즘을 사용하는 것이 더 어리석은 경우가 있습니다 ...이 경우 Namin의 메소드는 O (n)이지만 O (n log n) 정렬 된 메소드보다 더 큰 상수 계수를가집니다.

  2. ==============================

    2.여기에 O (n) 인 방법이 있습니다, 당신이 제안하는 두 가지 방법보다 점근 적으로 더 낫습니다.

    여기에 O (n) 인 방법이 있습니다, 당신이 제안하는 두 가지 방법보다 점근 적으로 더 낫습니다.

    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
    
  3. ==============================

    3."하지만 첫 번째 문자는 (예를 들어) a의 첫 번째 문자가 b에 아무 것도 없을 때 더 느립니다."

    "하지만 첫 번째 문자는 (예를 들어) a의 첫 번째 문자가 b에 아무 것도 없을 때 더 느립니다."

    이러한 종류의 축퇴 사례 분석은 좋은 생각이 아닙니다. 그것은 모든 종류의 모호한 특별한 경우를 생각하면서 잃어버린 시간의 헛소리입니다.

    O 스타일 "전체"분석 만 수행하십시오.

    전반적으로 정렬은 O (n log (n))입니다.

    솔루션에서 char에 대한 a.count (char)는 O (n 2)입니다. 각 카운트 패스는 문자열의 전체 검사입니다.

    일부 모호한 특수 사례가 더 빨라지거나 느려지는 경우, 아마도 흥미 롭습니다. 그러나 당신이 모호한 특별한 경우의 빈도를 알고있을 때만 중요합니다. 정렬 알고리즘을 분석 할 때는 상당한 양의 정렬에 이미 적절한 순서 (행운 또는 영리한 디자인)가있는 데이터가 포함되므로 사전 정렬 된 데이터의 정렬 성능이 중요하다는 점에 유의해야합니다.

    당신의 모호한 특별한 경우 ( "첫 번째 문자는 어디에도 없습니다")는이 문제가 자주 발생합니까? 네가 생각한 특별한 사건이라면, 옆으로 치워 라. 데이터에 대한 사실이라면 고려하십시오.

  4. ==============================

    4.나는 첫 번째 것이 "명백한"방법이라고 생각한다. Python의 기본 제공 정렬이 고도로 최적화되어 있기 때문에 더 짧고 명확하며 많은 경우에 더 빠를 것 같습니다.

    나는 첫 번째 것이 "명백한"방법이라고 생각한다. Python의 기본 제공 정렬이 고도로 최적화되어 있기 때문에 더 짧고 명확하며 많은 경우에 더 빠를 것 같습니다.

  5. ==============================

    5.두 번째 예제는 실제로 작동하지 않습니다.

    두 번째 예제는 실제로 작동하지 않습니다.

    all(a.count(char) == b.count(char) for char in a)
    

    b가 a에없는 여분의 문자를 포함하지 않는 경우에만 작동합니다. 문자열의 문자가 반복되는 경우에도 작업을 복제합니다.

    두 문자열이 동일한 고유 한 문자의 순열인지 여부를 알고 싶다면 다음을 수행하십시오.

    set(a) == set(b)
    

    두 번째 예를 수정하려면 다음을 수행하십시오.

    all(str1.count(char) == str2.count(char) for char in set(a) | set(b))
    

    set () 객체는 비트 OR 연산자를 오버로드하여 두 세트의 합집합으로 평가합니다. 이렇게하면 각. 자에 대해서 한 번만 두. 자의 모든.자를 반복 할 것입니다.

    즉, sorted () 메서드는 훨씬 간단하고 직관적이며 내가 사용할 것이라고 생각했습니다.

  6. ==============================

    6.다음은 두 가지 방법을 사용하여 매우 작은 문자열에 대한 일부 실행입니다. 1. 분류 2. 계산 (특히 @namin에 의한 원래의 메소드).

    다음은 두 가지 방법을 사용하여 매우 작은 문자열에 대한 일부 실행입니다. 1. 분류 2. 계산 (특히 @namin에 의한 원래의 메소드).

    a, b, c = 'confused', 'unfocused', 'foncused'
    
    sort_method = lambda x,y: sorted(x) == sorted(y)
    
    def count_method(a, b):
        d = {}
        for x in a:
            d[x] = d.get(x, 0) + 1
        for x in b:
            d[x] = d.get(x, 0) - 1
        for v in d.itervalues():
            if v != 0:
                return False
        return True
    

    100,000 회 이상의 두 가지 방법의 평균 실행 시간은 다음과 같습니다.

    불일치 (문자열 a 및 b)

    $ python -m timeit -s 'import temp' 'temp.sort_method(temp.a, temp.b)'
    100000 loops, best of 3: 9.72 usec per loop
    $ python -m timeit -s 'import temp' 'temp.count_method(temp.a, temp.b)'
    10000 loops, best of 3: 28.1 usec per loop
    

    일치 (문자열 a 및 c)

    $ python -m timeit -s 'import temp' 'temp.sort_method(temp.a, temp.c)'
    100000 loops, best of 3: 9.47 usec per loop
    $ python -m timeit -s 'import temp' 'temp.count_method(temp.a, temp.c)'
    100000 loops, best of 3: 24.6 usec per loop
    

    사용 된 문자열은 매우 작습니다. 메서드의 시간 복잡도가 다르므로 매우 큰 문자열을 사용하면 다른 결과가 표시됩니다. 데이터에 따라 선택하십시오. 두 가지를 조합하여 사용할 수도 있습니다.

  7. ==============================

    7.내가 가진 책의 모든 단어로 Java에서 꽤 철저한 비교를 수행했습니다. 계산 방법은 모든면에서 정렬 방법보다 우수합니다. 결과 :

    내가 가진 책의 모든 단어로 Java에서 꽤 철저한 비교를 수행했습니다. 계산 방법은 모든면에서 정렬 방법보다 우수합니다. 결과 :

    Testing against 9227 words.
    
    Permutation testing by sorting ... done.        18.582 s
    Permutation testing by counting ... done.       14.949 s
    

    알고리즘과 테스트 데이터 세트를 원하는 사람이 있으면 의견을 남기십시오.

  8. ==============================

    8.우선, 이러한 문제를 해결하기 위해, 예를 들어, String 1과 String 2가 정확히 동일하거나 다를지라도 쉽게 O (1)이므로 "if"를 사용할 수 있습니다. 둘째, 숫자 값인지 또는 문자열의 단어인지를 고려하는 것이 중요합니다. 후자의 경우 (단어와 숫자 값이 동시에 문자열에 있음) 첫 번째 해결 방법은 작동하지 않습니다. "ord ()"함수를 사용하여 ASCII 수치로 만들 수 있습니다. 그러나, 결국, 당신은 정렬을 사용하고 있습니다. 따라서 최악의 경우 시간 복잡도는 O (NlogN)가됩니다. 이 시간 복잡성은 나쁘지 않습니다. 그러나 더 잘할 수 있습니다. 당신은 그것을 O (N)으로 만들 수 있습니다. 내 "제안"은 Array (목록)를 사용하고 동시에 설정합니다. 배열에서 값을 찾는 것은 시간 복잡성이 O (N) 인 반복을 필요로하지만, 집합에서 값을 검색하는 것 (파이썬에서 HashTable로 구현되는 것 같아요, 확실하지 않습니다)에는 O (1) 시간 복잡성이 있습니다 :

    우선, 이러한 문제를 해결하기 위해, 예를 들어, String 1과 String 2가 정확히 동일하거나 다를지라도 쉽게 O (1)이므로 "if"를 사용할 수 있습니다. 둘째, 숫자 값인지 또는 문자열의 단어인지를 고려하는 것이 중요합니다. 후자의 경우 (단어와 숫자 값이 동시에 문자열에 있음) 첫 번째 해결 방법은 작동하지 않습니다. "ord ()"함수를 사용하여 ASCII 수치로 만들 수 있습니다. 그러나, 결국, 당신은 정렬을 사용하고 있습니다. 따라서 최악의 경우 시간 복잡도는 O (NlogN)가됩니다. 이 시간 복잡성은 나쁘지 않습니다. 그러나 더 잘할 수 있습니다. 당신은 그것을 O (N)으로 만들 수 있습니다. 내 "제안"은 Array (목록)를 사용하고 동시에 설정합니다. 배열에서 값을 찾는 것은 시간 복잡성이 O (N) 인 반복을 필요로하지만, 집합에서 값을 검색하는 것 (파이썬에서 HashTable로 구현되는 것 같아요, 확실하지 않습니다)에는 O (1) 시간 복잡성이 있습니다 :

    def Permutation2(Str1, Str2):
    
    ArrStr1 = list(Str1) #convert Str1 to array
    SetStr2 = set(Str2) #convert Str2 to set
    
    ArrExtra = []
    
    if len(Str1) != len(Str2): #check their length
        return False
    
    elif Str1 == Str2: #check their values
        return True
    
    for x in xrange(len(ArrStr1)):
        ArrExtra.append(ArrStr1[x])
    
    for x in xrange(len(ArrExtra)): #of course len(ArrExtra) == len(ArrStr1) ==len(ArrStr2)
        if ArrExtra[x] in SetStr2: #checking in set is O(1)
            continue
        else:
            return False
    
    return True
    
  9. ==============================

    9.첫 번째 단계로 가십시오 - 이해하기가 훨씬 쉽고 쉽습니다. 엄청나게 큰 문자열을 처리하고 성능이 진짜 문제라면 Python을 사용하지 말고 C와 같은 것을 사용하십시오.

    첫 번째 단계로 가십시오 - 이해하기가 훨씬 쉽고 쉽습니다. 엄청나게 큰 문자열을 처리하고 성능이 진짜 문제라면 Python을 사용하지 말고 C와 같은 것을 사용하십시오.

    파이썬의 선 (Zen of Python)에 관한 한, 일을 수행하는 명백한 방법이 하나만 있어야한다는 것은 작고 단순한 것을 의미합니다. 분명히 충분히 복잡한 작업을 수행하는 방법에는 항상 작은 변화가있을 것입니다.

  10. ==============================

    10.미안 해요, 내 코드는 파이썬 아니에요, 나는 그것을 사용하지 못했지만, 이것은 쉽게 파이썬으로 번역 될 수 있다고 확신합니다. 이미 게시 된 다른 모든 예제보다 빠르다고 생각합니다. 또한 O (n)이지만 가능한 한 빨리 중지합니다.

    미안 해요, 내 코드는 파이썬 아니에요, 나는 그것을 사용하지 못했지만, 이것은 쉽게 파이썬으로 번역 될 수 있다고 확신합니다. 이미 게시 된 다른 모든 예제보다 빠르다고 생각합니다. 또한 O (n)이지만 가능한 한 빨리 중지합니다.

    public boolean isPermutation(String a, String b) {
        if (a.length() != b.length()) {
            return false;
        }
    
        int[] charCount = new int[256];
        for (int i = 0; i < a.length(); ++i) {
            ++charCount[a.charAt(i)];
        }
    
        for (int i = 0; i < b.length(); ++i) {
            if (--charCount[b.charAt(i)] < 0) {
                return false;
            }
        }
        return true;
    }
    

    먼저 모든 문자에 대해 사전을 사용하지 않고 크기 256의 배열을 사용합니다. 색인에 액세스하는 것이 훨씬 빨라야합니다. 그런 다음 두 번째 문자열이 반복 될 때 카운트가 0이되면 즉시 false를 반환합니다. 두 번째 루프가 끝나면 문자열의 길이가 같고 문자가 더 자주 사용 되었기 때문에 문자열이 순열임을 확신 할 수 있습니다 a와 비교 된 b.

  11. ==============================

    11.파이썬에서 martinus 코드가 있습니다. 아스키 문자열에서만 작동합니다.

    파이썬에서 martinus 코드가 있습니다. 아스키 문자열에서만 작동합니다.

    def is_permutation(a, b):
        if len(a) != len(b):
            return False
    
        char_count = [0] * 256
        for c in a:
            char_count[ord(c)] += 1
    
        for c in b:
            char_count[ord(c)] -= 1
            if char_count[ord(c)] < 0:
                return False
    
        return True
    
  12. ==============================

    12.파이썬 3.1 / 2.7에서는 collections.Counter (a) == collections.Counter (b)를 사용할 수 있습니다.

    파이썬 3.1 / 2.7에서는 collections.Counter (a) == collections.Counter (b)를 사용할 수 있습니다.

    그러나 sorted (a) == sorted (b)는 여전히 가장 명백한 IMHO입니다. 순열 - 변화하는 순서 -에 대해서 이야기하고 있습니다. 그래서 정렬은 그 차이를 지우는 명백한 조작입니다.

  13. ==============================

    13.이것은 1 주일 전에 쓴 PHP 함수로 두 단어가 anagrams인지 확인합니다. 이 방법은 (파이썬에서 같은 방식으로 구현 된 경우) 다른 방법과 비교할 때 어떻습니까? 코멘트?

    이것은 1 주일 전에 쓴 PHP 함수로 두 단어가 anagrams인지 확인합니다. 이 방법은 (파이썬에서 같은 방식으로 구현 된 경우) 다른 방법과 비교할 때 어떻습니까? 코멘트?

    public function is_anagram($word1, $word2) {
        $letters1 = str_split($word1);
        $letters2 = str_split($word2);
        if (count($letters1) == count($letters2)) {
            foreach ($letters1 as $letter) {
                $index = array_search($letter, $letters2);
                if ($index !== false) {
                    unset($letters2[$index]);
                }
                else { return false; }
            }
            return true;
        }
        return false;        
    }
    

    다음은 PHP 버전의 Python에 대한 실제 번역입니다 (JFS 사용).

    def is_anagram(word1, word2):
        letters2 = list(word2)
        if len(word1) == len(word2):
           for letter in word1:
               try:
                   del letters2[letters2.index(letter)]
               except ValueError:
                   return False               
           return True
        return False
    

    코멘트:

        1. The algorithm is O(N**2). Compare it to @namin's version (it is O(N)).
        2. The multiple returns in the function look horrible.
    
  14. ==============================

    14.이 버전은 짧은 문자열의 경우 sorted (x) == sorted (y)보다 20 % 느린 것을 제외하고는 지금까지 제시된 모든 예제보다 빠릅니다. 유스 케이스에 의존하지만 일반적으로 20 %의 성능 향상으로 짧은 문자열과 긴 문자열에 다른 버전을 사용하여 코드의 복잡성을 정당화하기에는 부족합니다 (@ patros의 답변과 동일).

    이 버전은 짧은 문자열의 경우 sorted (x) == sorted (y)보다 20 % 느린 것을 제외하고는 지금까지 제시된 모든 예제보다 빠릅니다. 유스 케이스에 의존하지만 일반적으로 20 %의 성능 향상으로 짧은 문자열과 긴 문자열에 다른 버전을 사용하여 코드의 복잡성을 정당화하기에는 부족합니다 (@ patros의 답변과 동일).

    그것은 len을 사용하지 않기 때문에 어떤 iterable을 받아들이므로 메모리에 맞지 않는 데이터에 대해서조차도 작동합니다. 예를 들어 두 개의 커다란 텍스트 파일에 반복되는 많은 줄이 주어지면 파일에 같은 줄이 있는지 여부를 묻습니다. 줄의 순서는 상관 없습니다 ).

    def isanagram(iterable1, iterable2):
        d = {}
        get = d.get
        for c in iterable1:
            d[c] = get(c, 0) + 1
        try:
            for c in iterable2:
                d[c] -= 1
            return not any(d.itervalues())
        except KeyError:
            return False
    

    왜이 버전이 더 빠른 지 명확하지 않은데, 큰 iterable1 (25MB 시소러스에서 테스트)의 경우 defaultdict (@ namin 's)입니다.

    try로 루프에서 get을 대체하면 ... ... KeyError를 제외하고 짧은 문자열 즉 중복이 거의 없을 때 2 배 느려집니다.

  15. ==============================

    15.이것은 @patros의 대답에서 파생됩니다.

    이것은 @patros의 대답에서 파생됩니다.

    from collections import Counter
    
    def is_anagram(a, b, threshold=1000000):
        """Returns true if one sequence is a permutation of the other.
    
        Ignores whitespace and character case.
        Compares sorted sequences if the length is below the threshold,
        otherwise compares dictionaries that contain the frequency of the
        elements.
        """
        a, b = a.strip().lower(), b.strip().lower()
        length_a, length_b = len(a), len(b)
        if length_a != length_b:
            return False
        if length_a < threshold:
            return sorted(a) == sorted(b)
        return Counter(a) == Counter(b)  # Or use @namin's method if you don't want to create two dictionaries and don't mind the extra typing.
    
  16. ==============================

    16.Swift (또는 다른 언어 구현)에서 인코딩 된 값 (이 경우 유니 코드)을보고 일치하는지 확인할 수 있습니다.

    Swift (또는 다른 언어 구현)에서 인코딩 된 값 (이 경우 유니 코드)을보고 일치하는지 확인할 수 있습니다.

    같은 것 :

    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
    

    필요한 경우 공백이나 사례를 처리해야합니다.

  17. ==============================

    17.

    def matchPermutation(s1, s2):
      a = []
      b = []
    
      if len(s1) != len(s2):
        print 'length should be the same'
      return
    
      for i in range(len(s1)):
        a.append(s1[i])
    
      for i in range(len(s2)):
        b.append(s2[i])
    
      if set(a) == set(b):
        print 'Permutation of each other'
      else:
        print 'Not a permutation of each other'
      return
    
    #matchPermutaion('rav', 'var') #returns True
    matchPermutaion('rav', 'abc') #returns False
    
  18. ==============================

    18.이것은 파이썬에서 사전과 해싱을 사용하는 O (n) 솔루션입니다. 예를 들어 두 번째 문자를 확인한 후에 두 문자열이 순열이 아니라고 판단하면 코드가 이런 식으로 멈출 수 있기 때문에 기본 사전을 사용하지 않습니다.

    이것은 파이썬에서 사전과 해싱을 사용하는 O (n) 솔루션입니다. 예를 들어 두 번째 문자를 확인한 후에 두 문자열이 순열이 아니라고 판단하면 코드가 이런 식으로 멈출 수 있기 때문에 기본 사전을 사용하지 않습니다.

    def if_two_words_are_permutations(s1, s2):
        if len(s1) != len(s2):
            return False
        dic = {}
    for ch in s1:
        if ch in dic.keys():
            dic[ch] += 1
        else:
            dic[ch] = 1
    for ch in s2:
        if not ch in dic.keys():
            return False
        elif dic[ch] == 0:
            return False
        else:
            dic[ch] -= 1
    return True
    
  19. ==============================

    19.

    # First method
    def permutation(s1,s2):
     if len(s1) != len(s2):return False;
     return ' '.join(sorted(s1)) == ' '.join(sorted(s2))
    
    
    # second method
    def permutation1(s1,s2):
     if len(s1) != len(s2):return False;
     array = [0]*128;
     for c in s1:
     array[ord(c)] +=1
     for c in s2:
       array[ord(c)] -=1
       if (array[ord(c)]) < 0:
         return False
     return True
    
  20. ==============================

    20.어때? 아주 솔직하고 읽기 쉽습니다. 이것은 OP 당 as 문자열에 대한 것입니다.

    어때? 아주 솔직하고 읽기 쉽습니다. 이것은 OP 당 as 문자열에 대한 것입니다.

    주어진 sorted ()의 복잡성은 O (n log n)입니다.

    def checkPermutation(a,b):
        # input: strings a and b
        # return: boolean true if a is Permutation of b
    
        if len(a) != len(b):
            return False
        else:
            s_a = ''.join(sorted(a))
            s_b = ''.join(sorted(b))
            if s_a == s_b:
                return True
            else:
                return False
    
    # test inputs
    a = 'sRF7w0qbGp4fdgEyNlscUFyouETaPHAiQ2WIxzohiafEGJLw03N8ALvqMw6reLN1kHRjDeDausQBEuIWkIBfqUtsaZcPGoqAIkLlugTxjxLhkRvq5d6i55l4oBH1QoaMXHIZC5nA0K5KPBD9uIwa789sP0ZKV4X6'
    b = 'Vq3EeiLGfsAOH2PW6skMN8mEmUAtUKRDIY1kow9t1vIEhe81318wSMICGwf7Rv2qrLrpbeh8bh4hlRLZXDSMyZJYWfejLND4u9EhnNI51DXcQKrceKl9arWqOl7sWIw3EBkeu7Fw4TmyfYwPqCf6oUR0UIdsAVNwbyyiajtQHKh2EKLM1KlY6NdvQTTA7JKn6bLInhFvwZ4yKKbzkgGhF3Oogtnmzl29fW6Q2p0GPuFoueZ74aqlveGTYc0zcXUJkMzltzohoRdMUKP4r5XhbsGBED8ReDbL3ouPhsFchERvvNuaIWLUCY4gl8OW06SMuvceZrCg7EkSFxxprYurHz7VQ2muxzQHj7RG2k3khxbz2ZAhWIlBBtPtg4oXIQ7cbcwgmBXaTXSBgBe3Y8ywYBjinjEjRJjVAiZkWoPrt8JtZv249XiN0MTVYj0ZW6zmcvjZtRn32U3KLMOdjLnRFUP2I3HJtp99uVlM9ghIpae0EfC0v2g78LkZE1YAKsuqCiiy7DVOhyAZUbOrRwXOEDHxUyXwCmo1zfVkPVhwysx8HhH7Iy0yHAMr0Tb97BqcpmmyBsrSgsV1aT3sjY0ctDLibrxbRXBAOexncqB4BBKWJoWkQwUZkFfPXemZkWYmE72w5CFlI6kuwBQp27dCDZ39kRG7Txs1MbsUnRnNHBy1hSOZvTQRYZPX0VmU8SVGUqzwm1ECBHZakQK4RUquk3txKCqbDfbrNmnsEcjFaiMFWkY3Esg6p3Mm41KWysTpzN6287iXjgGSBw6CBv0hH635WiZ0u47IpUD5mY9rkraDDl5sDgd3f586EWJdKAaou3jR7eYU7YuJT3RQVRI0MuS0ec0xYID3WTUI0ckImz2ck7lrtfnkewzRMZSE2ANBkEmg2XAmwrCv0gy4ExW5DayGRXoqUv06ZLGCcBEiaF0fRMlinhElZTVrGPqqhT03WSq4P97JbXA90zUxiHCnsPjuRTthYl7ZaiVZwNt3RtYT4Ff1VQ5KXRwRzdzkRMsubBX7YEhhtl0ZGVlYiP4N4t00Jr7fB4687eabUqK6jcUVpXEpTvKDbj0JLcLYsneM9fsievUz193f6aMQ5o5fm4Ilx3TUZiX4AUsoyd8CD2SK3NkiLuR255BDIA0Zbgnj2XLyQPiJ1T4fjStpjxKOTzsQsZxpThY9Fvjvoxcs3HAiXjLtZ0TSOX6n4ZLjV3TdJMc4PonwqIb3lAndlTMnuzEPof2dXnpexoVm5c37XQ7fBkoMBJ4ydnW25XKYJbkrueRDSwtJGHjY37dob4jPg0axM5uWbqGocXQ4DyiVm5GhvuYX32RQaOtXXXw8cWK6JcSUnlP1gGLMNZEGeDXOuGWiy4AJ7SH93ZQ4iPgoxdfCuW0qbsLKT2HopcY9dtBIRzr91wnES9lDL49tpuW77LSt5dGA0YLSeWAaZt9bDrduE0gDZQ2yX4SDvAOn4PMcbFRfTqzdZXONmO7ruBHHb1tVFlBFNc4xkoetDO2s7mpiVG6YR4EYMFIG1hBPh7Evhttb34AQzqImSQm1gyL3O7n3p98Kqb9qqIPbN1kuhtW5mIbIioWW2n7MHY7E5mt0'
    
    print(checkPermutation(a, b)) #optional
    
  21. ==============================

    21.

    def permute(str1,str2):
        if sorted(str1) == sorted(str2):
            return True
        else:
            return False
    
    str1="hello"
    str2='olehl'
    a=permute(str1,str2)
    print(a
    
  22. from https://stackoverflow.com/questions/396421/checking-if-two-strings-are-permutations-of-each-other-in-python by cc-by-sa and MIT license