鍍金池/ 問(wèn)答/PHP  HTML/ 如何比較兩個(gè)版本號(hào)大小,如:1.2.4a和1.2.3b?

如何比較兩個(gè)版本號(hào)大小,如:1.2.4a和1.2.3b?

如題詳述:

請(qǐng)用您熟悉的編程語(yǔ)言,編程實(shí)現(xiàn)一個(gè)比較任意兩個(gè)軟件版本號(hào)大小的函數(shù),如 1.2.3a 和 1.2.4b 比較,后者版本號(hào)更大,請(qǐng)考慮各種情況,不可以使用系統(tǒng)提供的比較函數(shù)。

注:請(qǐng)問(wèn)大家有沒(méi)有好的實(shí)現(xiàn)方法與思路?

回答
編輯回答
喵小咪

// 這個(gè)是小年糕公司的筆試題, 我做了這個(gè)題目獲得了面試資格.去公司面試也是筆試,筆試掛掉了。
// 然后到公司是做這3個(gè)題目,https://www.cnblogs.com/mingz...

// 不考慮字母
function s2i(s) {
    return s.split('').reduce(function(a, c) {
        var code = c.charCodeAt(0);
        if (48<=code && code < 58) {
            a.push(code-48);
        }
        return a;
    }, []).reduce(function(a, c) {
        return 10*a + c;
    }, 0);
}
 
function versionCmp(s1, s2) {
    var a = s1.split('.').map(function(s) {
        return s2i(s);
    });
    var b = s2.split('.').map(function(s) {
        return s2i(s);
    });
    var n = a.length < b.length ? a.length : b.length;
    for (var i = 0; i < n; i++) {
        if (a[i] < b[i]) {
            return -1;
        } else if (a[i] > b[i]) {
            return 1;
        }
    }
    if (a.length < b.length) return -1;
    if (a.length > b.length) return 1;
    var last1 = s1.charCodeAt(s1.length-1) | 0x20,
        last2 = s2.charCodeAt(s2.length-1) | 0x20;
    return last1 > last2 ? 1 : last1 < last2 ? -1 : 0;
}
2018年2月15日 05:41
編輯回答
久礙你

version_compare

2017年11月17日 03:43
編輯回答
生性

安利一個(gè)npm包

const semver = require('semver')

semver.valid('1.2.3') // '1.2.3'
semver.valid('a.b.c') // null
semver.clean('  =v1.2.3   ') // '1.2.3'
semver.satisfies('1.2.3', '1.x || >=2.5.0 || 5.0.0 - 7.2.3') // true
semver.gt('1.2.3', '9.8.7') // false
semver.lt('1.2.3', '9.8.7') // true
semver.valid(semver.coerce('v2')) // '2.0.0'
semver.valid(semver.coerce('42.6.7.9.3-alpha')) // '42.6.7'
2017年4月10日 22:15
編輯回答
吢丕

常見(jiàn)的版本號(hào)命名方式,GNU,WINDOWS等,無(wú)外乎數(shù)字+字母,數(shù)字可能就是版本的迭代,如:V1.2.3, 也可能是日期,如V2018-06-25, 20180625。還有可能跟上階段命名如 α β γ等。如果你只想比較數(shù)字部分,只需要去掉非數(shù)字部分,比較大小就行。
如果要比較字母部分,那要區(qū)分來(lái)看,對(duì)a b c這種,直接轉(zhuǎn)成小寫(xiě)做大小比較就行。對(duì)trial, demo, unregistered這些,你要做個(gè)字典了。
如js代碼

let version1 = 'v1.2.3a';
let version2 = 'v1.2.4b';
let versionNumber1 = version1.replace(/[a-zA-Z]/g, (match,i)=> match.charCodeAt()).replace(/[^\d]/g, '') - 0;
let versionNumber2 = version2.replace(/[a-zA-Z]/g, (match,i)=> match.charCodeAt()).replace(/[^\d]/g, '') - 0;
console.log(versionNumber1 > versionNumber2); 

以上代碼面對(duì) v1.2.97av1.10.1b 這樣位數(shù)不一樣的版本號(hào)可能有問(wèn)題,特改進(jìn)下,差異太大的就不行了,比如比較v2021333,v1.2.3

let version1 = 'v1.2.97a';
let version2 = 'v1.10.1b';
let versionArr1 = version1.replace(/[a-zA-Z]/g, (match,i)=> '.' + match.charCodeAt()).split(/[^\d]/);
let versionArr2 = version2.replace(/[a-zA-Z]/g, (match,i)=> '.' + match.charCodeAt()).split(/[^\d]/);

// 保證兩個(gè)數(shù)據(jù)長(zhǎng)度一樣,面向 `v1.2` 和 `v1.2.3` 這樣的情況
if(versionArr1.length > versionArr2.length) {
    versionArr2.splice(versionArr2.length, 0, ...Array(versionArr1.length-versionArr2.length).fill(0))
} else {
    versionArr1.splice(versionArr1.length, 0, ...Array(versionArr2.length-versionArr1.length).fill(0))
}

// 按節(jié)比較
let result = 'version1 equels version2.'
for(let i=0 ; i < versionArr1.length; i ++) {
    if (+versionArr1[i] > +versionArr2[i]) {
        result = 'version1 is bigger.';
        break;
    } else if (+versionArr1[i] < +versionArr2[i]){
        result = 'version2 is bigger.';
        break;
    } 
}
console.log(result);
2017年11月21日 14:47
編輯回答
假灑脫

按.分割,逐一對(duì)比

文檔上大致寫(xiě)了version_compare的原理

clipboard.png

2017年12月10日 03:29
編輯回答
拮據(jù)
function compare(version1,version2){
            let arr1 = version1.split('.'); //版本1分割
            let arr2 = version2.split('.'); //版本2分割
            let [firstFlag,secondFlag,thirdFlag]=[false,false,false]; //定義版本的三個(gè)部分大小標(biāo)志

            //1.判斷第一位
            if( Number.parseInt(arr1[0]) > Number.parseInt(arr2[0]) ){
                firstFlag = true;
            }

            //2.判斷第二位
            if( Number.parseInt(arr1[1]) > Number.parseInt(arr2[1]) ){
                secondFlag = true;
            }
                
            /*3.判斷第三位
                1.全部為數(shù)字  
                2.全部為字母
                3.數(shù)字字母混合
            */
            //如果數(shù)組中第三個(gè)元素經(jīng)過(guò)parseInt之后,得到的都不是NaN,說(shuō)明都為數(shù)字
            if( Number(arr1[2]) && Number(arr2[2]) ){
                console.log('都為數(shù)字');
                thirdFlag = Number.parseInt(arr1[2]) > Number.parseInt(arr2[2]);
                //如果parseInt之后都為NaN,說(shuō)明都是字母
            }else if( Number.isNaN(Number.parseInt(arr1[2])) && Number.isNaN(Number.parseInt(arr2[2])) ){
                console.log('都為字母');
                thirdFlag = arr1[2].charCodeAt() > arr2[2].charCodeAt();
            }else{
                console.log('字母和數(shù)字混合的');
                let num1 = Number.parseInt(arr1[2]);
                let num2 = Number.parseInt(arr2[2]);
                let word1 = arr1[2].split(num1)[1];
                let word2 = arr2[2].split(num2)[1];
                if(num1 > num2){
                    thirdFlag = true;
                }else{
                    thirdFlag = word1.charCodeAt() > word2.charCodeAt();
                }
            }
            return firstFlag || secondFlag || thirdFlag;
        }
2018年5月12日 00:30