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
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.
One really hacky method (using C) would be:
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.
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.
#!/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 ;-)
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());
}
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)