Switch indexes, create the next highest number using the same exact 9 digits presented

后端 未结 3 1724
自闭症患者
自闭症患者 2020-11-28 16:07

So I received a challenge that states the following: \"Design a program that takes as input a 9 digit number where no digit appears twice and produces as output an arrangeme

3条回答
  •  孤街浪徒
    2020-11-28 16:45

    Here's a more efficient approach, using the algorithm of the 14th century Indian mathematician Narayana Pandita, which can be found in the Wikipedia article on Permutation. This ancient algorithm is still one of the fastest known ways to generate permutations in order, and it is quite robust, in that it properly handles permutations that contain repeated elements.

    The code below includes a simple test() function that generates all permutations of an ordered numeric string.

    #! /usr/bin/env python
    
    ''' Find the next permutation in lexicographic order after a given permutation
    
        This algorithm, due to Narayana Pandita, is from
        https://en.wikipedia.org/wiki/Permutation#Generation_in_lexicographic_order
    
        1. Find the largest index j such that a[j] < a[j + 1]. If no such index exists, 
        the permutation is the last permutation.
        2. Find the largest index k greater than j such that a[j] < a[k].
        3. Swap the value of a[j] with that of a[k].
        4. Reverse the sequence from a[j + 1] up to and including the final element a[n].
    
        Implemented in Python by PM 2Ring 2015.07.28
    '''
    
    import sys
    
    def next_perm(a):
        ''' Advance permutation a to the next one in lexicographic order '''
        n = len(a) - 1
        #1. Find the largest index j such that a[j] < a[j + 1]
        for j in range(n-1, -1, -1):
            if a[j] < a[j + 1]:
                break
        else:
            #This must be the last permutation
            return False
    
        #2. Find the largest index k greater than j such that a[j] < a[k]
        v = a[j]
        for k in range(n, j, -1):
            if v < a[k]:
                break
    
        #3. Swap the value of a[j] with that of a[k].
        a[j], a[k] = a[k], a[j]
    
        #4. Reverse the tail of the sequence
        a[j+1:] = a[j+1:][::-1]
    
        return True
    
    
    def test(n):
        ''' Print all permutations of an ordered numeric string (1-based) '''
        a = [str(i) for i in range(1, n+1)]
        i = 0
        while True:
            print('%2d: %s' % (i, ''.join(a)))
            i += 1
            if not next_perm(a):
                break
    
    
    def main():
        s = sys.argv[1] if len(sys.argv) > 1 else '781623954'
        a = list(s)
        next_perm(a)
        print('%s -> %s' % (s, ''.join(a)))
    
    
    if __name__ == '__main__':
        #test(4)
        main()
    

提交回复
热议问题