How can I sort numbers lexicographically?

前端 未结 14 915
半阙折子戏
半阙折子戏 2020-12-09 04:56

Here is the scenario.

I am given an array \'A\' of integers. The size of the array is not fixed. The function that I am supposed to write may be called once with an

相关标签:
14条回答
  • 2020-12-09 05:43

    I'd just turn them into strings, and then sort then sort using strcmp, which does lex comparisons.

    Alternatively you can write a "lexcmp" function that compares two numbers using % 10 and /10 but that's basically the same thing as calling atoi many times, so not a good idea.

    0 讨论(0)
  • 2020-12-09 05:44

    One really hacky method (using C) would be:

    • generate a new array of all the values converted to floats
    • do a sort using the mantissa (significand) bits for the comparison

    In Java (from here):

    long bits = Double.doubleToLongBits(5894.349580349);
    
    boolean negative = (bits & 0x8000000000000000L) != 0; 
    long exponent = bits & 0x7ff0000000000000L >> 52;
    long mantissa = bits & 0x000fffffffffffffL;
    

    so you would sort on the long mantissa here.

    0 讨论(0)
  • 2020-12-09 05:46

    If all the numbers are less than 1E+18, you could cast each number to UINT64, multiply by ten and add one, and then multiply by ten until they are at least 1E+19. Then sort those. To get back the original numbers, divide each number by ten until the last digit is non-zero (it should be one) and then divide by ten once more.

    0 讨论(0)
  • 2020-12-09 05:51
    #!/usr/bin/perl
    
    use strict;
    use warnings;
    
    my @x = ( 12, 2434, 23, 1, 654, 222, 56, 100000 );
    
    print $_, "\n" for sort @x;
    
    __END__
    

    Some timings ... First, with empty @x:

    C:\Temp> timethis s-empty
    TimeThis :  Elapsed Time :  00:00:00.188
    

    Now, with 10,000 randomly generated elements:

    TimeThis :  Elapsed Time :  00:00:00.219
    

    This includes the time taken to generate the 10,000 elements but not the time to output them to the console. The output adds about a second.

    So, save some programmer time ;-)

    0 讨论(0)
  • 2020-12-09 05:54

    The actual sorting can be done by any algorithm you like. The key to this problem is finding the comparison function that will properly identify which numbers should be "less than" others, according to this scheme:

    bool isLessThan(int a, int b)
    {
        string aString = ToString(a);
        string bString = ToString(b);
    
        int charCount = min(aString.length(), bString.length())
        for (charIndex = 0; charIndex < charCount; charIndex++)
        {
            if (aString[charIndex] < bString[charIndex]) { return TRUE; }
        }
    
        // if the numbers are of different lengths, but identical
        // for the common digits (e.g. 123 and 12345)
        // the shorter string is considered "less"
        return (aString.length() < bString.length());
    }
    
    0 讨论(0)
  • 2020-12-09 05:56

    Since you mentioned Java is the actual language in question:

    You don't need to convert to and from strings. Instead, define your own comparator and use that in the sort.

    Specifically:

    Comparator<Integer> lexCompare = new Comparator<Integer>(){
       int compareTo( Integer x, Integer y ) {
          return x.toString().compareTo( y.toString() );
       }
    };
    

    Then you can sort the array like this:

    int[] array = /* whatever */;
    Arrays.sort( array, lexCompare );
    

    (Note: The int/Integer mismatch works automatically through auto-boxing)

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