首页 > 代码库 > [C++]LeetCode: 59 Compare Version Numbers

[C++]LeetCode: 59 Compare Version Numbers

题目:

Compare two version numbers version1 and version1.
If version1 > version2 return 1, if version1 < version2 return -1, otherwise return 0.

You may assume that the version strings are non-empty and contain only digits and the . character.
The . character does not represent a decimal point and is used to separate number sequences.
For instance, 2.5 is not "two and a half" or "half way to version three", it is the fifth second-level revision of the second first-level revision.

Here is an example of version numbers ordering:

0.1 < 1.1 < 1.2 < 13.37

Answer 1: C语言方法

思路:

利用strtol函数自动根据分隔符 ‘.’ 将版本号隔开,逐一比较,直到不相等为止。

背景知识:

1. strtol

long int strtol(const char *nptr,char **endptr,int base);

将参数nptr字符串根据参数base来转换成长整型数。base指示进制数,如10表示是十进制。strtol扫描会跳过前面的空格字符,直到遇到数字或正负符号开始,再遇到非数字或者字符串结束符”\0“结束转换,并将结果返回。

endptr是一个传出参数,函数返回时指向后面未被识别的第一个字符。例如char *pos; strtol("123abc", &pos, 10);,strtol返回123,pos指向字符串中的字母a。如果字符串开头没有可识别的整数,例如char *pos; strtol("ABCabc", &pos, 10);,则strtol返回0,pos指向字符串开头,可以据此判断这种出错的情况,而这是atoi处理不了的。

2. CString 和String区别

CString是以空字符null结束的字符数组。string类是标准库的类,并不是内置类型,标准库就像是我们自己定义的类差不多的,string类型对象没有标配‘\0‘结尾的。不过String可以实现自动转换。

Attention:

1. 注意‘.’的作用,是区分版本号,所以会出现如下的版本号,含有多个‘.’.  如”12.13.24.0“ 所以必须根据分隔符来区分数字块并比较。

2. 注意如果两个版本号长度不一致,缺少的应该补0比较。如”12.3.34 和 12.3“ <=> "12.3.34 和 12.3.0"

3. 注意指针的操作,strtol返回参数,直接改变C风格字符串的指针,指向分隔符。 

long v1 = *vStr1 == '\0' ? 0 : strtol(vStr1, &vStr1, 10);
复杂度:O(N)

AC Code:

class Solution {
public:
    int compareVersion(string version1, string version2) {
        int ret = 0;
        
        //将string转成C风格字符数组
        char* vStr1 = (char*) version1.c_str();
        char* vStr2 = (char*) version2.c_str();
        
        while(ret == 0 && (*vStr1 != '\0' || *vStr2 != '\0'))
        {
            //strtol将会扫描参数nptr字符串,跳过前面的空格字符,直到遇上数字或正负符号才开始做转换,再遇到非数字或字符串结束时('\0')结束转换,并将结果返回。第二个参数是一个传出参数,函数返回时指向后面未被识别的第一个字符,即‘.’
            long v1 = *vStr1 == '\0' ? 0 : strtol(vStr1, &vStr1, 10);
            long v2 = *vStr2 == '\0' ? 0 : strtol(vStr2, &vStr2, 10);
            if(v1 > v2)
                ret = 1;
            else if(v1 < v2)
                ret = -1;
            else
            {
                if(*vStr1 != '\0') vStr1++;
                if(*vStr2 != '\0') vStr2++;
            }
        }
        
        return ret;
        
    }
};

Answer2: C++方法

思路:直接用split函数根据分隔符‘.’将版本号区分开,并存入数组中,然后逐一比较。使用Boost库里的split函数。

#include <boost/algorithm/string.hpp>
std::vector<std::string> strs;
boost::split(strs, "string to split", boost::is_any_of("\t "));
Code: leetcode貌似没办法调用boost库。

Line 1: ‘boost’ is not a namespace-name

using namespace boost;

class Solution {
public:
    int compareVersion(string version1, string version2) {
        int ret = 0;
        if(version1.size() == 0 || version2.size() == 0) return ret;
        
        vector<string> v1;
        vector<string> v2;
        
        boost::split(v1, version1, boost::is_any_of("."));
        boost::split(v2, version2, boost::is_any_of("."));
        
        int len1 = v1.size();
        int len2 = v2.size();
        
        int i = 0;
        for(ret == 0 && (i < len1 || i < len2))
        {
            int x1 = i < len1 ? stoi(v1[i]) : 0;
            int x2 = i < len2 ? stoi(v2[i]) : 0;
            if(x1 > x2)
                ret = 1;
            else if(x1 < x2)
                ret = -1;
            else
              i++;  
        }
        
        return ret;
    }
};

[C++]LeetCode: 59 Compare Version Numbers