《算法之美》のn个数连接得到最小的多位整数

题目:设有n个正整数,将它们连接成一排,组成一个最小的多位整数?

例如:n=2时,2个整数32321连接成的最小整数是:32132

         n=4时,4个整数553131233连接成的最小整数为:312313355

 

解答:由于题目涉及到整数的连接,如果直接进行整数的连接,可能会超出整数的表示范围,因此我们将之转换为字符串之间的连接更简单些,同时自定义字符串的比较规则:如果字符串A+B > B+A,那么A>B。同时可以证明A+B>=B+AB+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.csdn.net/yysdsyl/archive/2009/06/06/4248537.aspx

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值