数组:可能的最大数字

问题描述

| 给定一个元素数组,找到可以 通过使用数组的元素形成。 例如:10 9 回答:910 2 3 5 78 答案:78532 100 9 回答:9100 我知道这个问题有使用自定义字符串比较器的解决方案,但我不明白它是如何工作的。
    #include <iostream>
    #include <string>
    #include <algorithm>
    #include <vector>

    using namespace std;


    bool compare ( string a,string b )  
    {  
            return atoi( (a+b).c_str() ) < atoi((b+a).c_str() );  
    }

    int main()  
    {  
            vector<string> vs;  
            string s;  
            while ( cin >> s ) {  
                    vs.push_back(s);  
            }  
            sort( vs.begin(),vs.end(),compare );  
            for ( int i = vs.size()-1; i >= 0; i-- ) {  
                    cout << vs[i];  
            }  
    }   
谁能提出解决这个问题的算法? 将理解上述比较器的解释。 谢谢     

解决方法

        确实,如果我们有两个字符串
S
T
,我们通常会按字典顺序相反的顺序将它们连接起来,以使最大的数字出现。但是,当这些字符串之一是另一个字符串的前缀时,这种方法并不完美。 令
T
=
SA
,即
S
是ѭ2prefix的前缀。我们有两种选择::7ѭ和
SAS
。显然,我们的选择取决于哪个更大:
AS
SA
。 以下是满足此算法的代码修改:
#include <iostream>
#include <string>
#include <algorithm>
#include <vector>

using namespace std;


bool compare ( string a,string b )  
{  
        int i,j;
        for( i = 0; i < a.size() && i < b.size(); ++i )
               if( a[ i ] != b[ i ] )
                     break;
        if( i < a.size() && i < b.size() ) //  if digit mismatch happened
               return a[ i ] < b[ i ];
        if( i == a.size() )                // a is a prefix for b
        {
               string suffix = b.substr( i );
               return a + suffix < suffix + a;
        }
        else                               // b is a prefix for a
        {
               string suffix = a.substr( i );
               return suffix + b < b + suffix;
        }
}

int main()  
{  
        vector<string> vs;  
        string s;  
        while ( cin >> s ) {  
                vs.push_back(s);  
        }  
        sort( vs.begin(),vs.end(),compare );  
        for ( int i = vs.size()-1; i >= 0; i-- ) {  
                cout << vs[i];  
        }  
}
    ,        如果组合
a+b
b+a
之前或之后,比较器将比较两个字符串。因此例如它说对于输入
a=4; b=3
字符串
\"34\"
小于
\"43\"
,因此
4
应该在
3
之前。 因此,数字“ 19”将被分类为“ 20”,结果为“ 21”。     ,        只需通过从左到右比较数字将它们按字典顺序排序即可。这样,较大的数字会首先出现,从而使连接的数字更大。 编辑:正如Grigor所指出的,您必须首先反转字符串,将它们按相反的lex顺序排序,然后连接并反转结果。     ,        您正在使用比较器运算符查找通过将两个数字(字符串)以两种可能的方式
a+b
b+a
连接起来而形成的两个可能数中的较大者。由于您对比较数字的大小感兴趣,因此可以使用
atoi()
函数将字符串转换为相应的数字。  但是,此转换不是必需的。由于两个字符串
a+b
b+a
的长度相同,因此按字典顺序进行的比较与数字的大小一样好。仅当比较两个st的长度不相等时才需要转换。     ,        给定一个整数数组,您可以简单地对最大数目执行多个二进制搜索。每次执行此操作时,请将数字连接到字符串的末尾(结果),并记住排除先前添加的数字。