标签:把数组排成最小(大)数
这是一道经典的面试题,初次看到这道题我们可能会想到全排列,然后把每个排列拼起来,最后我们求出拼出来的最小值就可以了,下面我们说一种更快的算法。
其实我们可以找出一种排序规则,数组根据这个排序规则就能排成一个最小的数。我们要确定排序规则,就要比较两个数字,比如m和n,我们需要一个规则判断m和n哪个应该排在前面,并不仅仅是比较这两个数的大小。
关于这道题我们还需要考虑的一个潜在问题是假如m和n都在int的表达范围内,那么它们拼接之后呢?超出int的范围怎么办?这些都是我们需要考虑的问题,这是一个隐藏的大数问题。我们都知道,我们可以通过把数字转换成字符串的形式来解决大数问题,这样多大的位数我们都能装下,装换成字符串后,比较他们拼接成的数字的大小就直接按照字符串的大小比较规则来就可以了。下面我们看看具体的代码。
#include<stdio.h> #include <stdlib.h> #include <string.h> const int g_MaxNumberLength = 10; //整形所能表示的最大位数 char *g_StrCombine1 = new char[g_MaxNumberLength*2 + 1]; //用来存放超过整形位数的字符串 char *g_StrCombine2 = new char[g_MaxNumberLength*2 + 1]; int compare(const void* strNumber1, const void* strNumber2)//自定义比较函数,比较两个字符串大小 { strcpy(g_StrCombine1, *(const char**)strNumber1); strcat(g_StrCombine1, *(const char**)strNumber2); strcpy(g_StrCombine2, *(const char**)strNumber2); strcat(g_StrCombine2, *(const char**)strNumber1); return strcmp(g_StrCombine1, g_StrCombine2)>0;//注意这里大于0默认升序排列,小于0降序 } void PrintfMinNumber(int* number, int length) { if (number == NULL || length < 0) { return; } char** strNumbers = (char**)(new int[length]); //定义一个二维数组 int i = 0; for (; i < length; ++i) { strNumbers[i] = new char[g_MaxNumberLength + 1]; // 数组里面每个元素都是char类型的指针 sprintf(strNumbers[i], "%d", number[i]); } qsort(strNumbers, length, sizeof(char*), compare); i = 0; for (; i < length; i++) { printf("%s", strNumbers[i]); } printf("\n"); i = 0; for (; i < length; ++i) { delete[] strNumbers[i]; } delete[] strNumbers; } int main() { int arr[3] = { 12, 3, 4};//这里数组内容自己随便给就可以 int len = sizeof(arr) / sizeof(arr[0]); PrintfMinNumber(arr, len); return 0; }
假如是上面数组的内容,我在vs2013下运行结果如下:
我们可以看到,正如我们预期的那样,把数组内容排成了我们需要的最小的整数。
标签:把数组排成最小(大)数
原文地址:http://10706198.blog.51cto.com/10696198/1782912