题目描述
输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个。例如输入数组{3,32,321},则打印出这三个数字能排成的最小数字为321323。
代码如下
#include "JzOffer.h"
string Int2Str(int num);
//定义结构
struct StrNum
{
string strnum;
StrNum(const string& _s) : strnum(_s) {}
bool operator<(const StrNum& _s2) const
{
int i = 0, j = 0;
char c1 = this -> strnum[0];
char c2 = _s2.strnum[0];
while(true)
{
if(i == this->strnum.length()) i--;
else c1 = this->strnum[i];
if(j == _s2.strnum.length()) j--;
else c2 = _s2.strnum[j];
if(c1 != c2)
{
break;
}
else
{
i++;
j++;
}
}
return c1 < c2;
}
};
string PrintMinNumber(vector<int> numbers)
{
string outstr;
if(numbers.empty()) return outstr;
std::map<StrNum,int> strnums;
std::map<StrNum,int>::iterator imap;
for(int i = 0; i < numbers.size(); i++)
{
string instr = Int2Str(numbers[i]);
imap = strnums.find(instr);
if (imap == strnums.end())
{
strnums.insert(make_pair(instr,1));
}
else
{
imap->second++;
}
}
imap = strnums.begin();
while (imap != strnums.end())
{
while(imap->second)
{
outstr += imap->first.strnum;
imap->second--;
}
imap++;
}
return outstr;
}
bool TwoStr2Compare(const string& str1, const string& str2)
{
int i = 0, j = 0;
char c1 = str1[0];
char c2 = str2[0];
while(true)
{
if(i == str1.length()) i--;
else c1 = str1[i];
if(j == str2.length()) j--;
else c2 = str2[j];
if(c1 != c2)
{
break;
}
else
{
i++;
j++;
}
}
return c1 < c2;
}
string Int2Str(int num)
{
string outstr;
while(num)
{
outstr.push_back(num%10 + 48);
num /= 10;
}
int sizeOfStr = outstr.size();
for(int i = 0, j = sizeOfStr - 1; i <= sizeOfStr / 2, j >= sizeOfStr / 2; i++, j--)
{
char temp = outstr[i];
outstr[i] = outstr[j];
outstr[j] = temp;
}
return outstr;
}
void PrintMinNumberTest()
{
int Array[3] = {3,32,321};
vector<int> vecint;
for(int i = 0; i < 3; i++)
vecint.push_back(Array[i]);
vector<string> strnums;
for(int i = 0; i < 3; i++)
strnums.push_back(Int2Str(vecint[i]));
sort(strnums.begin(),strnums.end(),TwoStr2Compare);
PrintMinNumber(vecint);
}