题目:设有n个正整数,将它们连接成一排,组成一个最小的多位整数?
例如:n=2时,2个整数32,321连接成的最小整数是:32132;
n=4时,4个整数55,31,312,33连接成的最小整数为:312313355。
解答:由于题目涉及到整数的连接,如果直接进行整数的连接,可能会超出整数的表示范围,因此我们将之转换为字符串之间的连接更简单些,同时自定义字符串的比较规则:如果字符串A+B > B+A,那么A>B。同时可以证明A+B>=B+A,B+C>=C+B,则A+C>=C+A。
因此,解题思路为:1)先将输入的n个整数转换成字符串;2)按照自定义的字符串比较规则将n个字符串排序;3)最后按照从小到大的顺序输出字符串,即实现连接成最小的整数。
代码如下:
#include <iostream>
#include <set>
#include <string>
class ASCENum
{
public:
ASCENum(const char* ch) : str(ch){}
//重载'<'操作符
bool operator <(const ASCENum &other) const
{
if(str == other.str)
{
return false;
}
//下面就是我们的自定义字符串比较规则额
std::string right = str + other.str;
std::string left = other.str + str;
if(right >= left) //相等时算是false
return false;
else if(right < left)
return true;
}
const char* GetStr() const
{
return str.c_str();
}
private:
std::string str;
};
void ASCEOut(int *target, int len)
{
std::set<ASCENum> asceStrings;
ASCENum temp("");
char c[20];
//将数据由小到大顺序插入set中
for(int i=0; i<len; i++)
{
itoa(target[i], c, 10); //将int转为char[]
temp = ASCENum(c);
asceStrings.insert(temp);
}
//按顺序输出,就可以实现组成一个最小的多位数
//如果反向输出则是一个最大的多位数
for(std::set<ASCENum>::iterator it = asceStrings.begin(); it != asceStrings.end(); it++)
{
std::cout<<(*it).GetStr();
}
std::cout<<std::endl;
}
int main()
{
int testcase1[] = {443, 4432, 44324};
int testcase2[] = {123, 132, 213, 231, 321, 312};
ASCEOut(testcase1, 3);
ASCEOut(testcase2, 6);
system("pause");
return 0;
}
参考文献:
http://zhedahht.blog.163.com/blog/static/25411174200952174133707/
http://blog.youkuaiyun.com/yysdsyl/archive/2009/06/06/4248537.aspx