题目链接地址:
题目描述:
输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个。例如输入数组{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
****************************************************************/