给定一系列元素找到可能的最大数量
通过使用数组的元素形成
例如: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];
}
}
有人能提出算法来解决这个问题吗? 将理解上述比较器的说明。 谢谢
答案 0 :(得分:7)
实际上,如果我们有两个字符串S
和T
,我们最常将它们按字典顺序连接起来,以使最大数字出现。但是,当其中一个字符串是另一个字符串的前缀时,这种方法并不完美。
设T
= SA
,即S
是T
的前缀。我们有两种连接选择:SSA
和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];
}
}
答案 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+b
和b+a
连接两个数字(字符串)而形成的两个可能数字中较大的一个。由于您有兴趣比较数字的大小,atoi()
函数用于将字符串转换为相应的数字
但不需要进行此转换。由于两个字符串a+b
和b+a
的长度相同,因此字典比较与数字的大小一样好。只有当两个比较的长度不相等时才需要转换。
答案 4 :(得分:1)
给定一个整数数组,您可以简单地对最大数字执行多个二进制搜索。每次执行此操作时,将数字连接到字符串的末尾(结果),并记住排除先前添加的数字。