2013-08-23 13 views

Odpowiedz

-4

Konwersja "1.05.00.0156" na "0001" + "0005" + "0000" + "0156", a następnie na int64.

Konwertuj "1.0.221.9289" na "0001" + "0000" + "0221" + "9289", a następnie na int64.

Porównaj dwie wartości int64.

Spróbuj na Go playground

+0

Ów pracy jako mistrz. Super fajne. Dzięki @Everton. Dlaczego tak, dlaczego dokonać konwersji na int64? Czy nie można tego porównać wcześniej? – JVK

+0

Tak, można go porównać jako ciąg, ale nie wiem, jak porównać ciągi leksykalnie w Go. Potrzebujesz badań. :-) – Everton

+3

To będzie działać tak długo, jak zawsze będzie taka sama liczba cyfr w każdym ciągu wersji. Ale jeśli "2.o" ma być większe niż "1.9.8.6247", to nie zadziała. Zobacz poniżej moją odpowiedź na podejście, które zadziała w takim przypadku. –

1

To zależy co masz na myśli przez większe.

Naiwny podejście byłoby:

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 is bigger than %v\n", a, b) 
      break 
     } 
     if bi > ai { 
      fmt.Printf("%v is bigger than %v\n", b, a) 
      break 
     } 
    } 
} 

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

+1

Dla' a: = stringów.Split ("1", "."); b: = stringów.Split ("1.0.1", ".") ' , dwie ostatnie wersje Go, wynikiem jest '[brak wyjścia]'. – peterSO

+1

tak, jak powiedziałem bardzo naiwną wersję –

4

Oto ogólne rozwiązanie.

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) 
     } 
    } 
} 

wyjściowa:

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 
10

Jakiś czas temu stworzyłem Porównanie wersji biblioteki: https://github.com/mcuadros/go-version

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

spodoba!

+0

Awesome, dzięki! Proszę nie zdejmować go z GitHub w każdej chwili w następnej dekadzie: D –

2

podstawie Jeremy Walla odpowiedź:

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 
    } 

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

0

dążenie do przejrzystości i prostoty:

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) 
} 

Porównywanie wersji zakłada parsowania więc wierzę te 2 kroki powinny być oddzielone, aby jest solidny.

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 
} 
2

Jest miły rozwiązanie z 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") 
// Comparison example. There is also GreaterThan, Equal, and just 
// a simple Compare that returns an int allowing easy >=, <=, etc. 
if v1.LessThan(v2) { 
    fmt.Printf("%s is less than %s", v1, v2) 
}