数组:最大可能的数字

时间:2011-06-25 06:32:45

标签: c++ arrays algorithm

给定一系列元素找到可能的最大数量 通过使用数组的元素形成 例如:10 9
ans:910
2 3 5 78
ans:78532
100 9
ans: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];  
            }  
    }   

有人能提出算法来解决这个问题吗? 将理解上述比较器的说明。 谢谢

5 个答案:

答案 0 :(得分:7)

实际上,如果我们有两个字符串ST,我们最常将它们按字典顺序连接起来,以使最大数字出现。但是,当其中一个字符串是另一个字符串的前缀时,这种方法并不完美。
T = SA,即ST的前缀。我们有两种连接选择:SSASAS。显然,我们的选择将取决于哪个数字更大:ASSA。 以下是您的代码的修改,它满足了这个算法:

#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];  
        }  
}

答案 1 :(得分:4)

如果组合a+b位于b+a之前或之后,比较器会比较两个字符串。例如,它表示对于输入a=4; b=3,字符串"34" 小于而不是"43",因此4应该在3之前。

因此,数字2 3 5 78将被归类为78 5 3 2,因此结果为78532

答案 2 :(得分:4)

通过比较从左到右的数字,将它们排序为字典顺序。这样,首先出现较大的数字,从而使连接数更大。

编辑:正如Grigor指出的那样,你必须首先反转字符串,将它们排序为反向lex顺序,然后连接并反转结果。

答案 3 :(得分:3)

您正在使用比较运算符来查找通过以两种可能的方式a+bb+a连接两个数字(字符串)而形成的两个可能数字中较大的一个。由于您有兴趣比较数字的大小,atoi()函数用于将字符串转换为相应的数字  但不需要进行此转换。由于两个字符串a+bb+a的长度相同,因此字典比较与数字的大小一样好。只有当两个比较的长度不相等时才需要转换。

答案 4 :(得分:1)

给定一个整数数组,您可以简单地对最大数字执行多个二进制搜索。每次执行此操作时,将数字连接到字符串的末尾(结果),并记住排除先前添加的数字。