比较字符串形式的版本号

版本号是一个字符串,主要考虑以下三种用例,点分的个数一致还好,不一致需要注意

#include <boost/algorithm/string.hpp>
#include <algorithm>
#include <vector>
#include <string>

bool version_less_than(std::string str_version_a, std::string str_version_b)
{
    std::vector<std::string> vec_version_a, vec_version_b;
    boost::split(vec_version_a, str_version_a, boost::is_any_of("."));
    boost::split(vec_version_b, str_version_b, boost::is_any_of("."));
    return std::lexicographical_compare(vec_version_a.begin(), vec_version_a.end(), vec_version_b.begin(), vec_version_b.end());
}

int main() {
    {
        std::string str_version_a = "4.1.1", str_version_b = "4.1.2";
        printf("%d\n", version_less_than(str_version_a, str_version_b));
    }
    {
        std::string str_version_a = "4.1", str_version_b = "4.1.2";
        printf("%d\n", version_less_than(str_version_a, str_version_b));
    }
    {
        std::string str_version_a = "4.1.1", str_version_b = "4.1";
        printf("%d\n", version_less_than(str_version_a, str_version_b));
    }
    return 0;
}

运行结果

1
1
0

另外,对于比较,只需要通过一个小于比较运算,就可以满足小于,大于的比较,等于的比较可以通过两次小于比较来达成

————————————-

2015-9-16 09:33:20 发现上面的方法是有问题的,看这个用例

#include <boost/algorithm/string.hpp>
#include <algorithm>
#include <vector>
#include <string>

bool version_less_than(std::string str_version_a, std::string str_version_b)
{
    std::vector<std::string> vec_version_a, vec_version_b;
    boost::split(vec_version_a, str_version_a, boost::is_any_of("."));
    boost::split(vec_version_b, str_version_b, boost::is_any_of("."));
    return std::lexicographical_compare(vec_version_a.begin(), vec_version_a.end(), vec_version_b.begin(), vec_version_b.end());
}

int main() {
    {
        std::string str_version_a = "4.1.10", str_version_b = "4.1.2";
        printf("%d\n", version_less_than(str_version_a, str_version_b));
    }
    return 0;
}

输出

1

问题的本质还是拿字符串当做数字来比较了,这么改

#include <boost/algorithm/string.hpp>
#include <boost/lexical_cast.hpp>
#include <algorithm>
#include <vector>
#include <string>

bool version_less_than(std::string str_version_a, std::string str_version_b) {
    std::vector<std::string> vec_str_version_a, vec_str_version_b;
    boost::split(vec_str_version_a, str_version_a, boost::is_any_of("."));
    boost::split(vec_str_version_b, str_version_b, boost::is_any_of("."));
    std::vector<int> vec_int_version_a, vec_int_version_b;
    std::transform(vec_str_version_a.begin(), vec_str_version_a.end(), std::back_inserter(vec_int_version_a), boost::lexical_cast<int, std::string>);
    std::transform(vec_str_version_b.begin(), vec_str_version_b.end(), std::back_inserter(vec_int_version_b), boost::lexical_cast<int, std::string>);
    return std::lexicographical_compare(vec_int_version_a.begin(), vec_int_version_a.end(), vec_int_version_b.begin(), vec_int_version_b.end());
}

int main() {
    {
        std::string str_version_a = "4.1.1", str_version_b = "4.1.2";
        printf("%d\n", version_less_than(str_version_a, str_version_b));
    }
    {
        std::string str_version_a = "4.1", str_version_b = "4.1.2";
        printf("%d\n", version_less_than(str_version_a, str_version_b));
    }
    {
        std::string str_version_a = "4.1.1", str_version_b = "4.1";
        printf("%d\n", version_less_than(str_version_a, str_version_b));
    }
    {
        std::string str_version_a = "4.1.10", str_version_b = "4.1.2";
        printf("%d\n", version_less_than(str_version_a, str_version_b));
    }    
    return 0;
}
1
1
0
0

固然可以实现,但是感觉就笨重了好多,查了一下,leetcode 上面是有这个题的,https://leetcode.com/problems/compare-version-numbers/,按照 acm 流的写法,肯定就是自己手解字符串了,就像这样,http://ask.julyedu.com/question/114

Leave a Reply

Your email address will not be published. Required fields are marked *