给出一个像这样的版本号数组:
vector<string> v = { "9.8.17.5295", "9.13.0.0",
"12.3.9.1017", "25.3.6.1" };
在C ++中对它们进行排序的最佳方法是什么?当然,问题在于我们不能只按字典顺序对它们进行排序,但我们必须将每个字符串拆分成组件并以数字方式比较这些组件。在Python中,可以这样做:
v.sort(key=lambda x : tuple(map( int, x.split('.'))))
但是如何在C ++中执行此操作?无论我能想出什么,与这种单线相比看起来相当麻烦。到目前为止我发现的最好的是:
array<int, 4> splitversion( const string& s )
{
array<int, 4> z;
sscanf( s.c_str(), "%d.%d.%d.%d", &z[0], &z[1], &z[2], &z[3] );
return z;
}
int main()
{
vector<string> v = { "9.8.17.5295", "25.3.6.1", "9.13.0.0", "12.3.9.1017" };
sort( v.begin(), v.end(), []( string s1, string s2 )
{ return splitversion( s1 ) < splitversion( s2 ); } );
}
当然,sscanf被C ++人员所厌恶,所以我可能不得不用别的东西来替换它,但据我所知,它变得更加麻烦。 你会怎么做?
答案 0 :(得分:1)
没有人会皱眉:) 这看起来不错。 更快的解决方案是散列每个元素并根据哈希值进行排序。 示例哈希将是:
array<int, 4> z;
sscanf( s.c_str(), "%d.%d.%d.%d", &z[0], &z[1], &z[2], &z[3] );
unsigned long long hash = (z[0] << 24) + (z[1] << 16) + (z[2] << 8) + z[3];
越过原始数组/向量,根据哈希值排序将在长向量上显着更快。 这将需要更多代码。 至于最少的代码,你是非常好的。您可以使用lambda函数,但它们的可读性较差。
答案 1 :(得分:0)
我会做同样的事情,除了
char c;
istringstream(s) >> z[0] >> c >> z[1] >> c >> z[2] >> c >> z[3];
尽管如此,所有这些流都很慢,所以你最好使用像boost::spirit
这样的东西,以防你有很多版本号或至少在排序前在vector<pair<array<int, 4>, string>>
准备数据。