在C ++中对版本号数组进行排序

时间:2013-11-19 21:45:13

标签: c++ algorithm sorting

给出一个像这样的版本号数组:

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 ++人员所厌恶,所以我可能不得不用别的东西来替换它,但据我所知,它变得更加麻烦。 你会怎么做?

2 个答案:

答案 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>>准备数据。