求教算法。js算法比较

比较这样的值 ,比如说比较"4.5.1" 和 "6.3.8" ,6.3.8肯定大。我的想法是先用.分割,转为数组。然后再一位一位判断比较。 请问有什么更好更优雅的方法比较这样的吗(在javascript中运行)。谢谢

阅读 7.5k
11 个回答

直接把.替换掉转成整形一比不行?

这道题目是 leetcode 上的一道经典题型。比较版本大小,题目的问题就在于 1.10 是比 1.9 大的,因为 1.10 版本一定是出现在 1.9 版本之后,这也就造成了不能直接通过比较整数大小进行判断,因为 1.10 最终会等同于 1.1,从而出错。

题目地址:165. Compare Version Numbers

这道题目当时我的 AC

/**
 * @param {string} version1
 * @param {string} version2
 * @return {number}
 */
var compareVersion = function(version1, version2) {
    var version1List = version1.split('.');
    var version2List = version2.split('.');
    var maxLength = Math.max(version1List.length, version2List.length);
    for (var i = 0; i < maxLength; i++) {
        var v1 = Number(version1List[i]) || 0;
        var v2 = Number(version2List[i]) || 0;

        if (v1 > v2) {
            return 1;
        } else if (v1 < v2) {
            return -1;
        } else {
            continue;
        }
    }
    return 0;
};
/**
 * 比较版本号的大小
 *
 * 返回值:
 * v1大于v2则返回1,
 * v1小于v2则返回-1,
 * v1等于v2则返回0
 *
 * Example:
 * versionCompare('1.1', '1.2') => -1
 * versionCompare('1.1', '1.1') =>  0
 * versionCompare('1.2', '1.1') =>  1
 * versionCompare('2.23.3', '2.22.3') => 1
 * versionCompare(1.1, 1.2) => -1
 *
 * @param v1 版本号1
 * @param v2 版本号2
 * @returns {number}
 */
function versionCompare(v1, v2) {
    if(v1 == undefined || v2 == undefined) {
        throw new Error();
    }

    var v1_Array = String(v1).split('.'),
        v2_Array = String(v2).split('.'),
        len = Math.max(v1_Array.length, v2_Array.length);

    for(var i = 0; i < len; i++) {
        var _v1 =  parseInt(v1_Array[i]) || 0;
        var _v2 = parseInt(v2_Array[i]) || 0;
        if(_v1 < _v2) {
            return -1;
        } else if(_v1 > _v2) {
            return 1;
        }
    }

    return 0;
}

ascii:
'.':46
'/':47
'0':48
...
'9':57

各位为何不考虑直接比较呢?我不相信还有比这个更加简洁的代码.

借用一下楼上的代码格式.

/**
 * 比较版本号的大小
 *
 * 返回值:
 * v1大于v2则返回1,
 * v1小于v2则返回-1,
 * v1等于v2则返回0
 *
 * Example:
 * versionCompare('1.1', '1.2') => -1
 * versionCompare('1.1', '1.1') =>  0
 * versionCompare('1.2', '1.1') =>  1
 * versionCompare('2.23.3', '2.22.3') => 1
 * versionCompare(1.1, 1.2) => -1
 *
 * @param v1 版本号1
 * @param v2 版本号2
 * @returns {number}
 */
function versionCompare(v1, v2) {
    if(v1 == undefined || v2 == undefined) {
        throw new Error();
    }
    if(v1==v2)return 0;
    else if(v1<v2) return -1;
    else return 1;
}

抛砖引玉

function compare (a, b) {
  a = parseInt(String(a).replace(/\./g, ''))
  b = parseInt(String(b).replace(/\./g, ''))
  if (isNaN(a) || isNaN(b)) { throw new TypeError('Wrong input') }
  return a - b
}

1.先确定最多有多少层(分割的小数点数+1),假如有三层
2.比较每一层的数字n = n<10?n*10:n;,比如:1.6.3与1.10.11转换成10.60.30与10.10.11
3.将第二步的结果去掉小数点后直接比较

要考虑到每个数大于9的情况
如果不大于9则直接去除.比较大小就好
贴上我之前写的一个比较版本号的函数
考虑到大于9的情况,我们版本号最后一个如果是10是大于1-9的,所以没做处理
如果需要处理的话需要先把最后一个0去掉即可

function compareOsVer(version1,version2){
    var verIndex=0,ver2Index=0;
    var    verArr=version1.split('.'),ver2Arr=version2.split('.');
    var verLen=verArr.length   ,   ver2Len=verArr.length;
    while(verIndex<verLen && ver2Index<ver2Len){
        var number=verArr[verIndex],number2=ver2Arr[ver2Index];
        if(number>number2){
            return 1;
        }else if(number<number2){
            return -1;
        }else{
            verIndex++;
            ver2Index++;
        }
    }
            return 0;
  }
function translate(version){
    var res = version.split('.').reverse().reduce(function(p, n, index, arr){
        console.log(index)
        return p - 0 + n * Math.pow(100, index);
    })
    return res;
}
function compare(version1, version2){
    var result = translate(version1) > translate(version2)? version1: version2;
    console.log(result);
    return result;
}

compare('8.1.1', '8.2.1')

不知道优雅不优雅:

var compareVersion = function(version1, version2){
  if(version1 == version2) return 0;

  version1 = version1.split("."), version2 = version2.split(".");

  for(let i = 0, len = Math.max(version1.length, version2.length); i < len; i++) {
    let tag1 = +version1[i] || 0, tag2 = +version2[i] || 0;

    if(tag1 != tag2) return tag1 > tag2 ? 1 : -1;
  }

  return 0;
}

如果是('1.0', '1.0.1')或者('v1.3', 'v1.1')呢?

  1. 递归,按需分割;
  2. 直接比较字符串,无需转化为数字;
  3. 可以比较不同长度的,也可以包含字母。
function compare(v1, v2) {
  if (v1 === v2) return 0;

  function cmp(v1, v2) {
    if (v1.length > v2.length) return 1;
    if (v1.length < v2.length) return -1;
    if (v1 === v2) return 0;
    return v1 > v2 ? 1 : -1;
  }

  const _v1 = v1.substr(0, v1.indexOf('.') + 1 || v1.length);
  const _v2 = v2.substr(0, v2.indexOf('.') + 1 || v2.length);

  return cmp(_v1, _v2) || compare(v1.substr(_v1.length), v2.substr(_v2.length));
};
console.log(compare('100.3', '34.3')); // 1
console.log(compare('1.0', '1.0.1')); // -1
console.log(compare('v1.3', 'v1.1')); // 1

把点替换为空,直接比

推荐问题
宣传栏