码迷,mamicode.com
首页 > 其他好文 > 详细

41.把数组排成最小的数

时间:2014-05-21 21:03:34      阅读:262      评论:0      收藏:0      [点我收藏+]

标签:style   blog   class   c   code   java   

http://zhedahht.blog.163.com/blog/static/25411174200952174133707/

http://www.cnblogs.com/youxin/p/3294154.html

http://blog.csdn.net/wuzhekai1985/article/details/6704902

问题描述:输入一个正整数数组,将它们连接起来排成一个数,输出能排出的所有数字中最小的一个。例如输入数组{3,32,  321},则输出这两个能排成的最小数字321323。请给出解决问题的算法,并证明该算法。

思路:先将整数数组转为字符串数组,然后字符串数组进行排序,最后依次输出字符串数组即可。这里注意的是字符串的比较函数需要重新定义,不是比较a和b,而是比较ab与 ba。如果ab < ba,则a < b;如果ab > ba,则a > b;如果ab = ba,则a = b。比较函数的定义是本解决方案的关键。

结论:根据算法,如果a < b,那么a排在b前面,否则b排在a前面。

如何证明?

证明比较两个数字大小规则是有效的。

证明根据这种规则组合的数字是最小的。

1.证明比较两个数字大小规则是有效的。

一个有效的比较需要三个条件:

(1)自反性,即a等于a;

(2)对称性,即如果a大于b,则b小于a;

(3)传递性,即如果a小于b,b小于c,则a小于c。

现在分别予以证明。

(1)自反性。显然有aa=aa,所以a等于a。

(2)对称性。如果a小于b,则ab<ba,所以ba>ab。因此b大于a。

(3)传递性。 如果a小于b,则ab<ba;如果b小于c,则bc<cb。

举个例子a=1,b=23,c=345。

设a、b、c用十进制表示的时候分别为x位、y位、z位。则ab= a×10y+b,ba=b×10x+a;

则由ab<ba推出a×10y+b< b×10x+a,即a/(10x-1)<b/(10y -1)【结果1】。

同理由bc<cb推出b×10z+c< c×10y+b,即b/(10y-1)<c/(10z -1)【结果2】。

由【结果1】和【结果2】得到a/(10x-1)< c/(10z -1)【结果3】。由【结果3】得到ac<ca,即a小于c。

 

2.证明根据这种规则组合的数字是最小的。

我们把n个数按照前面的排序规则排好顺序之后,表示为F(n)=A1A2A3…An,则F(n)一定是最小的。

反证法证明:

假设这样排出来的两个数并不是最小的。即至少存在两个x和y(1<=x<y<=n),交换第x个数和地y个数后,使得A1A2…Ay…Ax…An<A1A2…Ax…Ay…An【原结论】。

设F(n)= A1A2…Ax…Ay…An。

因为Ay-1Ay<AyAy-1,则F(n)= A1A2…Ax…Ay…An< A1A2…AxAx+1…AyAy-1…An。同理不断将Ay左移,得到F(n)< A1A2…AyAxAx+1…Ay-2Ay-1…An。

因为AxAx+1<Ax+1Ax,则F(n)< A1A2…AyAx+1AxAx+2…Ay-2Ay-1…An。同理不断将Ax右移,得到F(n)< A1A2…AyAx+1Ax+2…Ay-2Ay-1Ax…An。

即F(n)=A1A2…Ax…Ay…An<A1A2…Ay…Ax…An【反证法得出的结论】。

【反证法得出的结论】与【原结论】相矛盾,所以假设不成立,原结论正确,即把n个数按照前面的排序规则排好顺序之后,表示为F(n)=A1A2A3…An,则F(n)一定是最小的。

代码如下:

bubuko.com,布布扣
#include <iostream> // cin cout
#include <string> // string
#include <sstream> // stringstream
#include <algorithm> // sort
using namespace std;

bool compare(const string& str1, const string &str2)
{
    string s1=str1+str2;
    string s2=str2+str1;
    return s1<s2;
}

void SortArrayToMinValue(int *data,int length)
{
    if(NULL==data||length<=0)
        return;
    string *strData = new string[length];
    //convert int to string
    for (int i=0;i<length;++i)
    {
        stringstream ss;
        ss<<data[i];
        ss>>strData[i];
    }
    // sort string array with user-defined compare function
    sort(strData,strData+length,compare);

    // print string array
    for (int i=0;i<length;i++)
    {
        cout<<strData[i];
    }
    cout<<endl;

    // free memory
    delete []strData;
    strData = NULL;
}

void test_case()
{
    int data[] = {3,32,321};
    int length = sizeof(data)/sizeof(int);
    SortArrayToMinValue(data,length);

    int data2[] = {456,23,1};
    int length2 = sizeof(data2)/sizeof(int);
    SortArrayToMinValue(data2,length2);
}

int _tmain(int argc, _TCHAR* argv[])
{
    test_case();
    return 0;
}
bubuko.com,布布扣

41.把数组排成最小的数,布布扣,bubuko.com

41.把数组排成最小的数

标签:style   blog   class   c   code   java   

原文地址:http://www.cnblogs.com/hellogiser/p/3739554.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!