How to compare two version number strings in golang

huangapple go评论88阅读模式
英文:

How to compare two version number strings in golang

问题

在Go语言中,你可以使用strings.Split函数将版本号字符串拆分为数字部分,然后逐个比较数字的大小来确定哪个版本号更大。下面是一个示例代码:

package main

import (
	"fmt"
	"strconv"
	"strings"
)

func compareVersions(a, b string) int {
	// 将版本号字符串拆分为数字部分
	aParts := strings.Split(a, ".")
	bParts := strings.Split(b, ".")

	// 比较每个数字部分的大小
	for i := 0; i < len(aParts) && i < len(bParts); i++ {
		aNum, _ := strconv.Atoi(aParts[i])
		bNum, _ := strconv.Atoi(bParts[i])

		if aNum < bNum {
			return -1
		} else if aNum > bNum {
			return 1
		}
	}

	// 如果前面的数字部分都相等,则比较版本号长度
	if len(aParts) < len(bParts) {
		return -1
	} else if len(aParts) > len(bParts) {
		return 1
	}

	// 版本号完全相等
	return 0
}

func main() {
	a := "1.05.00.0156"
	b := "1.0.221.9289"

	result := compareVersions(a, b)
	if result < 0 {
		fmt.Println("Version a is smaller")
	} else if result > 0 {
		fmt.Println("Version a is larger")
	} else {
		fmt.Println("Versions are equal")
	}
}

这段代码定义了一个compareVersions函数,它接受两个版本号字符串作为参数,并返回一个整数来表示它们的大小关系。在main函数中,我们调用compareVersions函数来比较版本号ab,并根据比较结果输出相应的信息。

注意:这段代码假设版本号字符串的格式是正确的,即由数字和点号组成。如果版本号字符串的格式不正确,可能会导致错误。你可以根据实际情况添加错误处理逻辑。

英文:

I have two strings (they are actually version numbers and they could be any version numbers)

a := &quot;1.05.00.0156&quot;  
b := &quot;1.0.221.9289&quot;

I want to compare which one is bigger. How to do it in golang?

答案1

得分: 29

有一个来自Hashicorp的不错的解决方案-https://github.com/hashicorp/go-version

import github.com/hashicorp/go-version
v1, err := version.NewVersion("1.2")
v2, err := version.NewVersion("1.5+metadata")
// 比较示例。还有GreaterThan、Equal和一个简单的Compare,返回一个int,可以轻松实现>=、<=等。
if v1.LessThan(v2) {
    fmt.Printf("%s 小于 %s", v1, v2)
}
英文:

There is a nice solution from Hashicorp - https://github.com/hashicorp/go-version

import github.com/hashicorp/go-version
v1, err := version.NewVersion(&quot;1.2&quot;)
v2, err := version.NewVersion(&quot;1.5+metadata&quot;)
// Comparison example. There is also GreaterThan, Equal, and just
// a simple Compare that returns an int allowing easy &gt;=, &lt;=, etc.
if v1.LessThan(v2) {
    fmt.Printf(&quot;%s is less than %s&quot;, v1, v2)
}

答案2

得分: 13

前段时间我创建了一个版本比较库:https://github.com/mcuadros/go-version

version.CompareSimple("1.05.00.0156", "1.0.221.9289")
//返回:1

希望你喜欢!

英文:

Some time ago I created a version comparison library: https://github.com/mcuadros/go-version

version.CompareSimple(&quot;1.05.00.0156&quot;, &quot;1.0.221.9289&quot;)
//Returns: 1

Enjoy it!

答案3

得分: 9

这是一个通用解决方案。

package main

import "fmt"

func VersionOrdinal(version string) string {
    // ISO/IEC 14651:2011
    const maxByte = 1<<8 - 1
    vo := make([]byte, 0, len(version)+8)
    j := -1
    for i := 0; i < len(version); i++ {
        b := version[i]
        if '0' > b || b > '9' {
            vo = append(vo, b)
            j = -1
            continue
        }
        if j == -1 {
            vo = append(vo, 0x00)
            j = len(vo) - 1
        }
        if vo[j] == 1 && vo[j+1] == '0' {
            vo[j+1] = b
            continue
        }
        if vo[j]+1 > maxByte {
            panic("VersionOrdinal: invalid version")
        }
        vo = append(vo, b)
        vo[j]++
    }
    return string(vo)
}

func main() {
    versions := []struct{ a, b string }{
        {"1.05.00.0156", "1.0.221.9289"},
        // Go versions
        {"1", "1.0.1"},
        {"1.0.1", "1.0.2"},
        {"1.0.2", "1.0.3"},
        {"1.0.3", "1.1"},
        {"1.1", "1.1.1"},
        {"1.1.1", "1.1.2"},
        {"1.1.2", "1.2"},
    }
    for _, version := range versions {
        a, b := VersionOrdinal(version.a), VersionOrdinal(version.b)
        switch {
        case a > b:
            fmt.Println(version.a, ">", version.b)
        case a < b:
            fmt.Println(version.a, "<", version.b)
        case a == b:
            fmt.Println(version.a, "=", version.b)
        }
    }
}

输出:

1.05.00.0156 > 1.0.221.9289
1 < 1.0.1
1.0.1 < 1.0.2
1.0.2 < 1.0.3
1.0.3 < 1.1
1.1 < 1.1.1
1.1.1 < 1.1.2
1.1.2 < 1.2
英文:

Here's a general solution.

package main
import &quot;fmt&quot;
func VersionOrdinal(version string) string {
// ISO/IEC 14651:2011
const maxByte = 1&lt;&lt;8 - 1
vo := make([]byte, 0, len(version)+8)
j := -1
for i := 0; i &lt; len(version); i++ {
b := version[i]
if &#39;0&#39; &gt; b || b &gt; &#39;9&#39; {
vo = append(vo, b)
j = -1
continue
}
if j == -1 {
vo = append(vo, 0x00)
j = len(vo) - 1
}
if vo[j] == 1 &amp;&amp; vo[j+1] == &#39;0&#39; {
vo[j+1] = b
continue
}
if vo[j]+1 &gt; maxByte {
panic(&quot;VersionOrdinal: invalid version&quot;)
}
vo = append(vo, b)
vo[j]++
}
return string(vo)
}
func main() {
versions := []struct{ a, b string }{
{&quot;1.05.00.0156&quot;, &quot;1.0.221.9289&quot;},
// Go versions
{&quot;1&quot;, &quot;1.0.1&quot;},
{&quot;1.0.1&quot;, &quot;1.0.2&quot;},
{&quot;1.0.2&quot;, &quot;1.0.3&quot;},
{&quot;1.0.3&quot;, &quot;1.1&quot;},
{&quot;1.1&quot;, &quot;1.1.1&quot;},
{&quot;1.1.1&quot;, &quot;1.1.2&quot;},
{&quot;1.1.2&quot;, &quot;1.2&quot;},
}
for _, version := range versions {
a, b := VersionOrdinal(version.a), VersionOrdinal(version.b)
switch {
case a &gt; b:
fmt.Println(version.a, &quot;&gt;&quot;, version.b)
case a &lt; b:
fmt.Println(version.a, &quot;&lt;&quot;, version.b)
case a == b:
fmt.Println(version.a, &quot;=&quot;, version.b)
}
}
}

Output:

1.05.00.0156 &gt; 1.0.221.9289
1 &lt; 1.0.1
1.0.1 &lt; 1.0.2
1.0.2 &lt; 1.0.3
1.0.3 &lt; 1.1
1.1 &lt; 1.1.1
1.1.1 &lt; 1.1.2
1.1.2 &lt; 1.2

答案4

得分: 4

go-semver 是一个用于 Go 语言的语义化版本库。它可以解析和比较两个语义化版本字符串。

示例:

vA := semver.New("1.2.3")
vB := semver.New("3.2.1")
fmt.Printf("%s < %s == %t\n", vA, vB, vA.LessThan(*vB))

输出:

1.2.3 < 3.2.1 == true

英文:

go-semver is a semantic versioning library for Go. It lets you parse and compare two semantic version strings.

Example:

vA := semver.New(&quot;1.2.3&quot;)
vB := semver.New(&quot;3.2.1&quot;)
fmt.Printf(&quot;%s &lt; %s == %t\n&quot;, vA, vB, vA.LessThan(*vB))

Output:

> 1.2.3 < 3.2.1 == true

答案5

得分: 4

以下是版本比较的一些库:

  1. https://github.com/blang/semver
  2. https://github.com/Masterminds/semver
  3. https://github.com/hashicorp/go-version
  4. https://github.com/mcuadros/go-version

我使用了blang/semver库。
例如:https://play.golang.org/p/1zZvEjLSOAr

import github.com/blang/semver/v4

v1, err := semver.Make("1.0.0-beta")
v2, err := semver.Make("2.0.0-beta")

// 可用选项
v1.Compare(v2)  // 比较
v1.LT(v2)       // 小于
v1.GT(v2)       // 大于
英文:

Here are some of the libraries for version comparison:

  1. https://github.com/blang/semver
  2. https://github.com/Masterminds/semver
  3. https://github.com/hashicorp/go-version
  4. https://github.com/mcuadros/go-version

I have used blang/semver.
Eg: https://play.golang.org/p/1zZvEjLSOAr

<!-- language: lang-go -->

 import github.com/blang/semver/v4
v1, err := semver.Make(&quot;1.0.0-beta&quot;)
v2, err := semver.Make(&quot;2.0.0-beta&quot;)
// Options availabe
v1.Compare(v2)  // Compare
v1.LT(v2)       // LessThan
v1.GT(v2)       // GreaterThan

答案6

得分: 2

这取决于你对"bigger"的理解。

一个简单的方法是:

package main

import "fmt"
import "strings"

func main() {
    a := strings.Split("1.05.00.0156", ".")
    b := strings.Split("1.0.221.9289", ".")
    for i, s := range a {
        var ai, bi int
        fmt.Sscanf(s, "%d", &ai)
        fmt.Sscanf(b[i], "%d", &bi)
        if ai > bi {
            fmt.Printf("%v 比 %v 大\n", a, b)
            break
        }
        if bi > ai {
            fmt.Printf("%v 比 %v 大\n", b, a)
            break
        }
    }
}

你可以在这里运行这段代码:http://play.golang.org/p/j0MtFcn44Z

英文:

This depends on what you mean by bigger.

A naive approach would be:

package main
import &quot;fmt&quot;
import &quot;strings&quot;
func main() {
a := strings.Split(&quot;1.05.00.0156&quot;, &quot;.&quot;)
b := strings.Split(&quot;1.0.221.9289&quot;, &quot;.&quot;)
for i, s := range a {
var ai, bi int
fmt.Sscanf(s, &quot;%d&quot;, &amp;ai)
fmt.Sscanf(b[i], &quot;%d&quot;, &amp;bi)
if ai &gt; bi {
fmt.Printf(&quot;%v is bigger than %v\n&quot;, a, b)
break
}
if bi &gt; ai {
fmt.Printf(&quot;%v is bigger than %v\n&quot;, b, a)
break
}
}
}

http://play.golang.org/p/j0MtFcn44Z

答案7

得分: 2

根据Jeremy Wall的回答:

func compareVer(a, b string) (ret int) {
    as := strings.Split(a, ".")
    bs := strings.Split(b, ".")
    loopMax := len(bs)
    if len(as) > len(bs) {
        loopMax = len(as)
    }
    for i := 0; i < loopMax; i++ {
        var x, y string
        if len(as) > i {
            x = as[i]
        }
        if len(bs) > i {
            y = bs[i]
        }
        xi,_ := strconv.Atoi(x)
        yi,_ := strconv.Atoi(y)
        if xi > yi {
            ret = -1
        } else if xi < yi {
            ret = 1
        }
        if ret != 0 {
            break
        }
    }
    return
}

点击此处查看代码。

英文:

Based on Jeremy Wall's answer:

  func compareVer(a, b string) (ret int) {
as := strings.Split(a, &quot;.&quot;)
bs := strings.Split(b, &quot;.&quot;)
loopMax := len(bs)
if len(as) &gt; len(bs) {
loopMax = len(as)
}
for i := 0; i &lt; loopMax; i++ { 
var x, y string
if len(as) &gt; i {
x = as[i]
}
if len(bs) &gt; i {
y = bs[i]
}
xi,_ := strconv.Atoi(x)
yi,_ := strconv.Atoi(y)
if xi &gt; yi {
ret = -1
} else if xi &lt; yi {
ret = 1
}
if ret != 0 {
break
}
}       
return 
}

http://play.golang.org/p/AetJqvFc3B

答案8

得分: 1

追求清晰和简洁:

func intVer(v string) (int64, error) {
    sections := strings.Split(v, ".")
    intVerSection := func(v string, n int) string {
        if n < len(sections) {
            return fmt.Sprintf("%04s", sections[n])
        } else {
            return "0000"
        }
    }
    s := ""
    for i := 0; i < 4; i++ {
        s += intVerSection(v, i)
    }
    return strconv.ParseInt(s, 10, 64)
}

func main() {
    a := "3.045.98.0832"
    b := "087.2345"
    va, _ := intVer(a)
    vb, _ := intVer(b)
    fmt.Println(va<vb)
}

比较版本意味着需要解析,所以我认为这两个步骤应该分开进行,以提高鲁棒性。

英文:

Striving for clarity and simplicity:

func intVer(v string) (int64, error) {
sections := strings.Split(v, &quot;.&quot;)
intVerSection := func(v string, n int) string {
if n &lt; len(sections) {
return fmt.Sprintf(&quot;%04s&quot;, sections[n])
} else {
return &quot;0000&quot;
}
}
s := &quot;&quot;
for i := 0; i &lt; 4; i++ {
s += intVerSection(v, i)
}
return strconv.ParseInt(s, 10, 64)
}
func main() {
a := &quot;3.045.98.0832&quot;
b := &quot;087.2345&quot;
va, _ := intVer(a)
vb, _ := intVer(b)
fmt.Println(va&lt;vb)
}

Comparing versions implies parsing so I believe these 2 steps should be separate to make it robust.

答案9

得分: 1

在leetcode上进行了测试:https://leetcode.com/problems/compare-version-numbers/

func compareVersion(version1 string, version2 string) int {
    len1, len2, i, j := len(version1), len(version2), 0, 0
    for i < len1 || j < len2 {
        n1 := 0
        for i < len1 && '0' <= version1[i] && version1[i] <= '9' {
            n1 = n1 * 10 + int(version1[i] - '0')
            i++
        }
        n2 := 0
        for j < len2 && '0' <= version2[j] && version2[j] <= '9' {
            n2 = n2 * 10 + int(version2[j] - '0')
            j++
        }
        if n1 > n2 {
            return 1
        }
        if n1 < n2 {
            return -1
        }
        i, j = i+1, j+1
    }
    return 0
}
英文:

tested in leetcode: https://leetcode.com/problems/compare-version-numbers/

func compareVersion(version1 string, version2 string) int {
    len1, len2, i, j := len(version1), len(version2), 0, 0
    for i &lt; len1 || j &lt; len2 {
        n1 := 0
        for i &lt; len1 &amp;&amp; &#39;0&#39; &lt;= version1[i] &amp;&amp; version1[i] &lt;= &#39;9&#39; {
            n1 = n1 * 10 + int(version1[i] - &#39;0&#39;)
            i++
        }
        n2 := 0
        for j &lt; len2 &amp;&amp; &#39;0&#39; &lt;= version2[j] &amp;&amp; version2[j] &lt;= &#39;9&#39; {
            n2 = n2 * 10 + int(version2[j] - &#39;0&#39;)
            j++
        }
        if n1 &gt; n2 {
            return 1
        }
        if n1 &lt; n2 {
            return -1
        }
        i, j = i+1, j+1
    }
    return 0
}

答案10

得分: 0

import (
	"fmt"
	"strconv"
	"strings"
)


func main() {
	j := ll("1.05.00.0156", "1.0.221.9289")
	fmt.Println(j)
}


func ll(a, b string) int {
	var length, r, l int = 0, 0, 0
	v1 := strings.Split(a, ".")
	v2 := strings.Split(b, ".")
	len1, len2 := len(v1), len(v2)

	length = len2
	if len1 > len2 {
		length = len1
	}

	for i := 0; i < length; i++ {
		if i < len1 && i < len2 {
			if v1[i] == v2[i] {
				continue
			}
		}
		r = 0
		if i < len1 {
			if number, err := strconv.Atoi(v1[i]); err == nil {
				r = number
			}
		}

		l = 0
		if i < len2 {
			if number, err := strconv.Atoi(v2[i]); err == nil {
				l = number
			}
		}

		if r < l {
			return -1
		} else if r > l {
			return 1
		}
	}

	return 0
}

这是一个用Go语言编写的程序,它定义了一个名为ll的函数,该函数接受两个字符串参数ab,并返回一个整数。在main函数中,调用了ll函数,并将结果打印出来。ll函数的功能是比较两个版本号字符串的大小关系,如果a小于b,则返回-1;如果a大于b,则返回1;如果a等于b,则返回0。

英文:
import (
&quot;fmt&quot;
&quot;strconv&quot;
&quot;strings&quot;
)
func main() {
j := ll(&quot;1.05.00.0156&quot;  ,&quot;1.0.221.9289&quot;)
fmt.Println(j)
}
func ll(a,b string) int {
var length ,r,l int = 0,0,0
v1 := strings.Split(a,&quot;.&quot;)
v2 := strings.Split(b,&quot;.&quot;)
len1, len2 := len(v1), len(v2)
length = len2
if len1 &gt; len2 {
length = len1
}
for i:= 0;i&lt;length;i++ {
if i &lt; len1 &amp;&amp; i &lt; len2 {
if v1[i] == v2[i] {
continue
}
}
r = 0
if i &lt; len1 {
if number, err := strconv.Atoi(v1[i]); err == nil {
r = number
}
}
l = 0
if i &lt; len2 {
if number, err := strconv.Atoi(v2[i]); err == nil {
l = number
}
}
if r &lt; l {
return -1
}else if r&gt; l {
return 1
}
}
return 0
}

答案11

得分: 0

如果你可以保证版本字符串具有相同的格式(例如SemVer),你可以将其转换为整数并进行比较。这里是一个用于对SemVer切片进行排序的实现:

	versions := []string{"1.0.10", "1.0.6", "1.0.9"}
	sort.Slice(versions[:], func(i, j int) bool {
		as := strings.Split(versions[i], ".")
		bs := strings.Split(versions[j], ".")
		if len(as) != len(bs) || len(as) != 3 {
			return versions[i] < versions[j]
		}

		ais := make([]int, len(as))
		bis := make([]int, len(bs))
		for i := range as {
			ais[i], _ = strconv.Atoi(as[i])
			bis[i], _ = strconv.Atoi(bs[i])
		}

		//X.Y.Z

		// 如果X和Y相同,比较Z
		if ais[0] == bis[0] && ais[1] == bis[1] {
			return ais[2] < bis[2]
		}

		// 如果X相同,比较Y
		if ais[0] == bis[0] {
			return ais[1] < bis[1]
		}

		// 比较X
		return ais[0] < bis[0]
	})
	fmt.Println(versions)
英文:

If you can guarantee version strings have same format (i.e. SemVer), you can convert to int and compare int. Here is an implementation for sorting slices of SemVer:

	versions := []string{&quot;1.0.10&quot;, &quot;1.0.6&quot;, &quot;1.0.9&quot;}
	sort.Slice(versions[:], func(i, j int) bool {
		as := strings.Split(versions[i], &quot;.&quot;)
		bs := strings.Split(versions[j], &quot;.&quot;)
		if len(as) != len(bs) || len(as) != 3 {
			return versions[i] &lt; versions[j]
		}

		ais := make([]int, len(as))
		bis := make([]int, len(bs))
		for i := range as {
			ais[i], _ = strconv.Atoi(as[i])
			bis[i], _ = strconv.Atoi(bs[i])
		}

		//X.Y.Z

		// If X and Y are the same, compare Z
		if ais[0] == bis[0] &amp;&amp; ais[1] == bis[1] {
			return ais[2] &lt; bis[2]
		}

		// If X is same, compare Y
		if ais[0] == bis[0] {
			return ais[1] &lt; bis[1]
		}

		// Compare X
		return ais[0] &lt; bis[0]
	})
	fmt.Println(versions)

答案12

得分: 0

解决方案1

这是一个版本比较函数,返回表示两个版本之间关系的符号。

// 如果 v1 > v2 返回 '>'
// 如果 v1 < v2 返回 '<'
// 否则返回 '='
func CompareVersion(v1, v2 string) byte {
	v1Slice := strings.Split(v1, ".")
	v2Slice := strings.Split(v2, ".")

	var maxSize int
	{ // 使它们具有相同的长度。
		if len(v1Slice) < len(v2Slice) {
			maxSize = len(v2Slice)
		} else {
			maxSize = len(v1Slice)
		}
	}

	v1NSlice := make([]int, maxSize)
	v2NSlice := make([]int, maxSize)
	{
		// 将字符串转换为整数。
		for i := range v1Slice {
			v1NSlice[i], _ = strconv.Atoi(v1Slice[i])
		}

		for i := range v2Slice {
			v2NSlice[i], _ = strconv.Atoi(v2Slice[i])
		}
	}

	var result byte
	var v2Elem int
	for i, v1Elem := range v1NSlice {
		if result != '=' && result != 0 { // 前面的比较已经得到了答案。
			return result
		}

		v2Elem = v2NSlice[i]

		if v1Elem > v2Elem {
			result = '>'
		} else if v1Elem < v2Elem {
			result = '<'
		} else {
			result = '='
		}
	}
	return result
}

go playground

解决方案2

这是另一种更直接的方法。

CmpVer("1.01", "==", "1.001") // true
var (
	ErrInvalidOperator = errors.New("invalid operator")
)

func CmpVer(v1, op, v2 string) (bool, error) {
	v1Slice := strings.Split(v1, ".")
	v2Slice := strings.Split(v2, ".")

	var maxSize int
	// 让它们具有相同的长度。
	if len(v1Slice) < len(v2Slice) {
		maxSize = len(v2Slice)
	} else {
		maxSize = len(v1Slice)
	}

	v1NSlice := make([]int, maxSize)
	v2NSlice := make([]int, maxSize)

	var err error
	// 将字符串转换为整数。
	for i := range v1Slice {
		v1NSlice[i], err = strconv.Atoi(v1Slice[i])
		if err != nil {
			return false, err
		}
	}
	for i := range v2Slice {
		v2NSlice[i], err = strconv.Atoi(v2Slice[i])
		if err != nil {
			return false, err
		}
	}

	var sign rune
	var v2Elem int
	for i, v1Elem := range v1NSlice {
		if sign != '=' && sign != 0 { // 前面的比较已经得到了答案。
			break
		}

		v2Elem = v2NSlice[i]
		if v1Elem > v2Elem {
			sign = '>'
		} else if v1Elem < v2Elem {
			sign = '<'
		} else {
			sign = '='
		}
	}

	switch op {
	case ">":
		return sign == '>', nil
	case ">=":
		return sign == '>' || sign == '=', nil
	case "==":
		fallthrough
	case "=":
		return sign == '=', nil
	case "!=":
		return sign != '=', nil
	case "<":
		return sign == '<', nil
	case "<=":
		return sign == '<' || sign == '=', nil
	default:
		return false, fmt.Errorf("%w: %s", ErrInvalidOperator, op)
	}
}

playground

英文:

Solution1

This is a version comparison that returns symbols to indicate the relationship between the two versions.

// If v1 &gt; v2 return &#39;&gt;&#39;
// If v1 &lt; v2 return &#39;&lt;&#39;
// Otherwise return &#39;=&#39;
func CompareVersion(v1, v2 string) byte {
v1Slice := strings.Split(v1, &quot;.&quot;)
v2Slice := strings.Split(v2, &quot;.&quot;)
var maxSize int
{ // Make them both the same size.
if len(v1Slice) &lt; len(v2Slice) {
maxSize = len(v2Slice)
} else {
maxSize = len(v1Slice)
}
}
v1NSlice := make([]int, maxSize)
v2NSlice := make([]int, maxSize)
{
// Convert string to the int.
for i := range v1Slice {
v1NSlice[i], _ = strconv.Atoi(v1Slice[i])
}
for i := range v2Slice {
v2NSlice[i], _ = strconv.Atoi(v2Slice[i])
}
}
var result byte
var v2Elem int
for i, v1Elem := range v1NSlice {
if result != &#39;=&#39; &amp;&amp; result != 0 { // The previous comparison has got the answer already.
return result
}
v2Elem = v2NSlice[i]
if v1Elem &gt; v2Elem {
result = &#39;&gt;&#39;
} else if v1Elem &lt; v2Elem {
result = &#39;&lt;&#39;
} else {
result = &#39;=&#39;
}
}
return result
}

<kbd>go playground</kbd>

Solution2

This is another more straightforward approach.

CmpVer(&quot;1.01&quot;, &quot;==&quot;, &quot;1.001&quot;) // true
var (
	ErrInvalidOperator = errors.New(&quot;invalid operator&quot;)
)

func CmpVer(v1, op, v2 string) (bool, error) {
	v1Slice := strings.Split(v1, &quot;.&quot;)
	v2Slice := strings.Split(v2, &quot;.&quot;)

	var maxSize int
	// Let each other have the same length.
	if len(v1Slice) &lt; len(v2Slice) {
		maxSize = len(v2Slice)
	} else {
		maxSize = len(v1Slice)
	}

	v1NSlice := make([]int, maxSize)
	v2NSlice := make([]int, maxSize)

	var err error
	// convert string to int
	for i := range v1Slice {
		v1NSlice[i], err = strconv.Atoi(v1Slice[i])
		if err != nil {
			return false, err
		}
	}
	for i := range v2Slice {
		v2NSlice[i], err = strconv.Atoi(v2Slice[i])
		if err != nil {
			return false, err
		}
	}

	var sign rune
	var v2Elem int
	for i, v1Elem := range v1NSlice {
		if sign != &#39;=&#39; &amp;&amp; sign != 0 { //  // The previous comparison has got the answer already.
			break
		}

		v2Elem = v2NSlice[i]
		if v1Elem &gt; v2Elem {
			sign = &#39;&gt;&#39;
		} else if v1Elem &lt; v2Elem {
			sign = &#39;&lt;&#39;
		} else {
			sign = &#39;=&#39;
		}
	}

	switch op {
	case &quot;&gt;&quot;:
		return sign == &#39;&gt;&#39;, nil
	case &quot;&gt;=&quot;:
		return sign == &#39;&gt;&#39; || sign == &#39;=&#39;, nil
	case &quot;==&quot;:
		fallthrough
	case &quot;=&quot;:
		return sign == &#39;=&#39;, nil
	case &quot;!=&quot;:
		return sign != &#39;=&#39;, nil
	case &quot;&lt;&quot;:
		return sign == &#39;&lt;&#39;, nil
	case &quot;&lt;=&quot;:
		return sign == &#39;&lt;&#39; || sign == &#39;=&#39;, nil
	default:
		return false, fmt.Errorf(&quot;%w: %s&quot;, ErrInvalidOperator, op)
	}
}

<kbd>playground</kbd>

答案13

得分: -8

将"1.05.00.0156"转换为"0001"+"0005"+"0000"+"0156",然后转换为int64类型。

将"1.0.221.9289"转换为"0001"+"0000"+"0221"+"9289",然后转换为int64类型。

比较这两个int64值。

Go playground上尝试一下。

英文:

Convert "1.05.00.0156" to "0001"+"0005"+"0000"+"0156", then to int64.

Convert "1.0.221.9289" to "0001"+"0000"+"0221"+"9289", then to int64.

Compare the two int64 values.

Try it on the <kbd>Go playground</kbd>

huangapple
  • 本文由 发表于 2013年8月24日 02:20:11
  • 转载请务必保留本文链接:https://go.coder-hub.com/18409373.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定