题目描述
输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个。例如输入数组{3,32,321},则打印出这三个数字能排成的最小数字为321323。
思路:
1、全排列
求出数组中所有数字的全排列,然后把每个全排列拼起来,求出拼出来的数字的最大值。
2、定义新的排序规则
如果两个数字m,n拼接成mn和nm,如果mn<nm,那么m应该排在n的前面,我们定义此时m小于n,如果mn=nm,我们定义m等于n。
可以考虑将数字转成字符串,一来防止数字拼接时的溢出,二来字符串的拼接和比较容易实现。
由于把数字m和n拼接起来得到mn和nm,它们的位数一定是相同的,因此比较它们的大小只需按照字符串大小的比较规则即可。
代码如下:
#include <iostream>
#include <string>
#include <sstream>
#include <vector>
#include <algorithm>
using namespace std;
bool cmp(string& s1, string& s2)
{
string str1,str2;
str1 += s1; str1 += s2;
str2 += s2; str2 += s1;
return str1 < str2; // <就是最小的数,>就是最大的
}
string minnum(vector<int> v)
{
string res = "";
vector<string> numstr;
for (auto vit : v)//采用auto关键字,方便快捷
{
stringstream ss;//关键点在这个,每次要重新初始化
ss << vit;
string tmp = ss.str();
numstr.push_back(tmp);
}
sort(numstr.begin(), numstr.end(),cmp);//自定义比较排序
for (auto it : numstr)
res += it;
return res;
}
int main()
{
int num;
vector<int> v;
while (cin >> num) //持续输入,遇到q则停止
{
v.push_back(num);
char ch = getchar();
if (ch == 'q')
break;
}
string ret = minnum(v);
cout << ret<<endl;
return 0;
}
输出结果: