LeetCode[String]: 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

这个问题比较简单,按照常规思路,我的C++代码实现如下:

int compareVersion(string version1, string version2) {
    int level1 = 0, level2 = 0;

    int idx1 = 0, idx2 = 0;
    while (idx1 != version1.length() || idx2 != version2.length()) {
        level1 = 0;
        for ( ; idx1 < version1.length(); ++idx1) {
            if (version1[idx1] == '.') {
                ++idx1;
                break;
            }
            else {
                level1 = level1 * 10 + (version1[idx1] - '0');
            }
        }

        level2 = 0;
        for ( ; idx2 < version2.length(); ++idx2) {
            if (version2[idx2] == '.') {
                ++idx2;
                break;
            }
            else {
                level2 = level2 * 10 + (version2[idx2] - '0');
            }
        }

        if (level1 > level2) return 1;
        else if (level1 < level2) return -1;
    }

    return 0;
}


最近LeetCode上有了运行时间的对比,运行时间虽然由于服务器的状态不同可能导致一定的测试误差,但是还是能够在一定程度上反应程序的性能的。我以上解法的运行结果如下图所示:


Discuss上看到一个用C风格的字符串操作函数strtol来完成的,以前没有用到过这个函数,在此学习一下。

函数原型:long int strtol(const char nptr,char *endptr,int base);
参数base范围从2至36,或0。参数base代表采用的进制方式,如base值为10则采用10进制,若base值为16则采用16进制等。当base值为0时则是采用10进制做转换,但遇到如’0x’前置字符则会使用16进制做转换、遇到’0’前置字符而不是’0x’的时候会使用8进制做转换。
一开始strtol()会扫描参数nptr字符串,跳过前面的空格字符,直到遇上数字或正负符号才开始做转换,再遇到非数字或字符串结束时('\0')结束转换,并将结果返回。若参数endptr不为NULL,则会将遇到不合条件而终止的nptr中的字符指针由endptr返回;若参数endptr为NULL,则不会返回非法字符串。

在这个问题中,endptr能派上用场。C++代码如下:

int compareVersion(string version1, string version2) {
    const char *str1 = version1.c_str();
    const char *str2 = version2.c_str();
    while (*str1 != '\0' || *str2 != '\0') {
        int level1 = (*str1 == '\0' ? 0 : strtol(str1, (char **)&str1, 10));
        int level2 = (*str2 == '\0' ? 0 : strtol(str2, (char **)&str2, 10));

        if (level1 > level2) return 1;
        else if (level1 < level2) return -1;

        if (*str1 != '\0') ++str1;
        if (*str2 != '\0') ++str2;
    }

    return 0;
}


在以上代码中,需要注意两个问题:
第一,string转char *时,string.c_str()返回的是const char *;
第二,循环体中多处对*str1和*str2是否为'\0'进行判断,这是不好的代码,应该避免。
以上代码的运行性能跟第一种解法一样。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值