Sort a list to form the largest possible number

前端 未结 8 1033
无人及你
无人及你 2020-11-27 20:29

I am trying to write a function that given a list of non negative integers, arranges them such that they form the largest possible number.

For example, given

8条回答
  •  感情败类
    2020-11-27 20:54

    Here is an ugly solution that does work without passing a cmp comparison function to the sorted. Basically, the key function takes each number and calculates a rational number that has that number as the repeating decimals; that is

    0   => 0
    100 => 100/999 == 0.100100100...
    10  => 10/99   == 0.1010101010...
    1   => 1/9     == 0.1111111111...
    11  => 11/99   == 0.1111111111...
    12  => 12/99   == 0.1212121212...
    9   => 9/9     == 1
    99  => 99/99   == 1
    999 => 999/999 == 1
    

    The 0 is sorted the smallest with sort key 0, and 1 followed by most zeroes would have key closest to 0.1, and thus sorted second smallest. Numbers that consist of digit 9 all have sort key equal to 1; it does not really matter if you sort 9 before or after 99.

    Sorting using these values as the key will necessarily give the correct output, unless you use numbers that are too big for float precision. (probably much sooner than 2 ** 53)

    Thus we get the following program:

    # for Python 2, not needed in Python 3
    from __future__ import division
    
    a = [50, 5, 51, 59, 2, 1, 9, 98]
    
    def fractionalize(i):
        divisor = 9
        while divisor < i:
            divisor = 10 * divisor + 9 
    
        return i / divisor
    
    print(sorted(a, key=fractionalize, reverse=True))
    

    Which produces

    [9, 98, 59, 5, 51, 50, 2, 1]
    

    As we're essentially calculating i / (10 ** ceil(log10(i + 1)) - 1) here, one can also write the following oneliner:

    from math import ceil, log10
    
    print(sorted(a, key=lambda i: i and i/(10**ceil(log10(i+1))-1), reverse=True))
    

    The i and part guards for division by zero error, in case 0 is among the numbers.

提交回复
热议问题