比较版本为字符串

Dmi*_*riy 6 c++ string-comparison version-numbering

将版本号作为字符串进行比较并不容易......
"1.0.0.9">"1.0.0.10",但它不正确.
正确地做到这一点的显而易见的方法是解析这些字符串,转换为数字并作为数字进行比较.有没有其他方式更"优雅"地做到这一点?例如,boost :: string_algo ......

Bil*_*eal 23

我没有看到比解析更优雅的东西 - 但使用已经存在的标准库设施.假设您不需要错误检查:

void Parse(int result[4], const std::string& input)
{
    std::istringstream parser(input);
    parser >> result[0];
    for(int idx = 1; idx < 4; idx++)
    {
        parser.get(); //Skip period
        parser >> result[idx];
    }
}

bool LessThanVersion(const std::string& a,const std::string& b)
{
    int parsedA[4], parsedB[4];
    Parse(parsedA, a);
    Parse(parsedB, b);
    return std::lexicographical_compare(parsedA, parsedA + 4, parsedB, parsedB + 4);
}
Run Code Online (Sandbox Code Playgroud)

任何更复杂的东西都会更难维护,不值得你花时间.

  • 算法很好.我建议将它包装为`class Version {Version(std :: string const&); bool operator <(Version const&rhs)const; };`.这允许你有一个`std :: set <Version>`. (3认同)
  • +1:整洁的STL用法.'std :: lexicographical_compare`中的错字. (2认同)

Mar*_*ork 6

我会创建一个版本类.
然后,为版本类定义比较运算符很简单.

#include <iostream>
#include <sstream>
#include <vector>
#include <iterator>

class Version
{
    // An internal utility structure just used to make the std::copy in the constructor easy to write.
    struct VersionDigit
    {
        int value;
        operator int() const {return value;}
    };
    friend std::istream& operator>>(std::istream& str, Version::VersionDigit& digit);
    public:
        Version(std::string const& versionStr)
        {
            // To Make processing easier in VersionDigit prepend a '.'
            std::stringstream   versionStream(std::string(".") + versionStr);

            // Copy all parts of the version number into the version Info vector.
            std::copy(  std::istream_iterator<VersionDigit>(versionStream),
                        std::istream_iterator<VersionDigit>(),
                        std::back_inserter(versionInfo)
                     );
        }

        // Test if two version numbers are the same. 
        bool operator<(Version const& rhs) const
        {
            return std::lexicographical_compare(versionInfo.begin(), versionInfo.end(), rhs.versionInfo.begin(), rhs.versionInfo.end());
        }

    private:
        std::vector<int>    versionInfo;
};

// Read a single digit from the version. 
std::istream& operator>>(std::istream& str, Version::VersionDigit& digit)
{
    str.get();
    str >> digit.value;
    return str;
}


int main()
{
    Version     v1("10.0.0.9");
    Version     v2("10.0.0.10");

    if (v1 < v2)
    {
        std::cout << "Version 1 Smaller\n";
    }
    else
    {
        std::cout << "Fail\n";
    }
}
Run Code Online (Sandbox Code Playgroud)