题目链接地址:
九度OJ-题目1504:把数组排成最小的数
题目描述:
输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个。例如输入数组{3,32,321},则打印出这三个数字能排成的最小数字为321323。
输入:
输入可能包含多个测试样例。
对于每个测试案例,输入的第一行为一个整数m (1<=m <=100)代表输入的正整数的个数。
输入的第二行包括m个正整数,其中每个正整数不超过10000000。
输出:
对应每个测试案例,
输出m个数字能排成的最小数字。
样例输入:
3
23 13 6
2
23456 56
样例输出:
13236
2345656
解题思路:
要想整数数组里所有数字拼接起来排成的数最小,肯定要对整数数组进行排序,让小的数字排在大的数字的左边。
例如:对于数字123和234,123排在234左边形成数字123234,而234排在123左边形成数字234123,明显123234 < 234123。因此现在问题就转化成了对整数数组进行排序。由于输入整数的范围是[1,10000000],所以拼接形成的整数可能会溢出,因此我用字符串来表示整数。我开始的想法直接比较输入的两个整数的大小,把小的整数排在大的整数的左边拼接形成新的整数。这样子看起来没有什么问题,但是WA了。。。 后来仔细一想,我忽略了一种特殊情况。例如:对于整数10和整数100,因为10比100小,所以将10排在100的左边形成整数10100,但是将100排在10左边形成的整数10010却比10100小。后来想了很久,没有想到好的办法,就采用了作者的解法 程序员面试题精选100题(41)-把数组排成最小的数[算法] 。简单来说,对于输入的两个整数n1和n2,如果n1n2 <= n2n1,就在拼接数字时将n1排在n2的左边,否则就将n2排在n1的左边。
AC代码如下:
#include<stdio.h> #include<string.h> #include<stdlib.h> char numberString[100][10]; // 用于存放整数的字符串 /** * 输入m个整数 * @param m 输入整数的个数 * @return void */ void inputNumbers(int m) { int i; for(i = 0;i < m;i++) { scanf("%s",numberString[i]); } } /** * 比较字符串numberString1numberString2和numberString2numberString1的大小 * @param numberString1 第1个整数所对应的字符串 * @param numberString2 第2个整数所对应的字符串 * @return result 返回strcmp(numberString1numberString2,numberString2numberString1)的结果 */ int stringCmp(char numberString1[],char numberString2[]) { int result = 0; char tempString1[20]; // 字符串numberString1numberString2 char tempString2[20]; // 字符串numberString2numberString1 strcpy(tempString1,numberString1); strcat(tempString1,numberString2); strcpy(tempString2,numberString2); strcat(tempString2,numberString1); result = strcmp(tempString1,tempString2); return result; } /** * 将m个整数排列生成一个最小的整数 * @param m 整数的个数 * @return void */ void generateMinNumber(int m) { int i,j; char temp[10]; for(i = 0;i < m;i++) { for(j = i;j < m;j++) { if(stringCmp(numberString[i],numberString[j]) > 0) // 自己写一个判断两个字符串大小的函数 { // 交换numberString[i]和numberString[j] strcpy(temp,numberString[i]); // temp = numberString[i]; strcpy(numberString[i],numberString[j]); // numberString[i] = numberString[j]; strcpy(numberString[j],temp); // numberString[j] = temp; } } } } /** * 输出m个整数排成生成的最小的数 * @param m 整数的个数 * @return void */ void printMinNumber(int m) { int i; for(i = 0;i < m;i++) { printf("%s",numberString[i]); } printf("\n"); } int main() { int m; while(EOF != scanf("%d",&m)) { inputNumbers(m); generateMinNumber(m); printMinNumber(m); } return 0; } /************************************************************** Problem: 1504 User: blueshell Language: C Result: Accepted Time:280 ms Memory:920 kb ****************************************************************/