如何比较两个版本

时间:2019-10-21 07:33:09

标签: swift

我正在尝试比较两个版本的程序,但是我无法输入比Integer大的版本,因为.numeric是数字的一部分,我认为-整数大小并进行比较。请帮助我在比较功能中转换为其他类型,或者提出其他解决方案进行比较。

import Foundation

func versionFormatting(version:inout String) {
    version = String(version
        .unicodeScalars
        .filter(CharacterSet
        .decimalDigits
        .union(CharacterSet(charactersIn: "."))
        .contains))
    if version[version.startIndex] == "."  {
        version.insert("0", at: version.startIndex)
    }
    if version[version.index(before: version.endIndex)] == "."  {
        version.insert("0", at: version.endIndex)
    }
    version = version.replacingOccurrences(of: "..", with: ".0.")
    version = version.replacingOccurrences(of: "..", with: ".0.")
}

func compareVersions(first: String, second: String) -> Int {
    let firstVersion = first.components(separatedBy: ".")
    let secondVersion = second.components(separatedBy: ".")
    let collectiveCount = min(firstVersion.count, secondVersion.count);
    for i in 0..<collectiveCount {
        if firstVersion[i].compare(secondVersion[i], options: .numeric) == .orderedDescending {
            return 0
        }
        else if secondVersion[i].compare(firstVersion[i], options: .numeric) == .orderedDescending {
            return 1
        }
    }
    let maxLengthArray: [String]
    let versionIndex: Int
    if firstVersion.count == collectiveCount {
        maxLengthArray = secondVersion
        versionIndex = 1
    }
    else {
        maxLengthArray = firstVersion
        versionIndex = 0
    }
    for i in collectiveCount..<maxLengthArray.count {
        if maxLengthArray[i].compare("0", options: .numeric) == .orderedDescending {
            return versionIndex
        }
    }
    return -1
}

//print ("First version: ")
//var firstVersion = readLine()!
var firstVersion = "1.0.0.0"
//print ("Second version: ")
//var secondVersion = readLine()!
var secondVersion = "1.0.0"

versionFormatting(version:&firstVersion)
versionFormatting(version:&secondVersion)

print(firstVersion)
print(secondVersion)

var result = compareVersions(first:firstVersion, second:secondVersion)
if result == -1 {
    print("версии равны")
}
else if result == 0 {
    print("первая версия актуальнее")
}
else {
    print("вторая версия актуальнее")
}

2 个答案:

答案 0 :(得分:0)

您应该使用数字比较。例如,我想将我的iOS版本与iOS 13版本进行比较。

let systemVersion = UIDevice.current.systemVersion
if systemVersion.compare("13.0", options: .numeric) != .orderedAscending { 
    // >= 13.0
}

答案 1 :(得分:0)

我认为这将满足您的需求。我已将其更改为迭代方法,以使其更加整洁,并使用Floats而不是Ints。如果您超出浮动上限,则可能需要查看问题而不是解决方案:-)

我还使用了一个枚举来返回结果,因为它更具可读性(尽管如果您需要原始的返回值,则可以访问rawValue。

enum Compared: Int {
   case v1Bigger = 1
   case v2Bigger = -1
   case equal = 0
}

func cleanAndSplit(_ version: String) -> [Float] {
   var cleaned = String(version.unicodeScalars.filter(CharacterSet.decimalDigits.union(CharacterSet(charactersIn: ".")).contains))
   guard !cleaned.isEmpty else {return []}
   if cleaned[cleaned.startIndex] == "."  {
       cleaned.insert("0", at: cleaned.startIndex)
   }
   if cleaned[cleaned.index(before: cleaned.endIndex)] == "."  {
       cleaned.insert("0", at: cleaned.endIndex)
   }
   cleaned = cleaned.replacingOccurrences(of: "..", with: ".0.")
   return cleaned.components(separatedBy: ".").compactMap{Float($0)}
}

func compare(_ v1: [Float], _ v2: [Float]) -> Compared  {
   guard !(v1.isEmpty && v2.isEmpty) else {return .equal}
   if v1.first! == v2.first! {
      return compare(Array(v1.dropFirst()), Array(v2.dropFirst()))
   }
   else  {
      return v1.first! > v2.first! ? .v1Bigger : .v2Bigger
   }
}

func compareVersionsStrings(_ version1: String, _ version2: String) -> Compared {
   var v1 = cleanAndSplit(version1)
   var v2 = cleanAndSplit(version2)
   let maxComponents = max(v1.count, v2.count)
   while v1.count < maxComponents { v1.append(Float(0))}
   while v2.count < maxComponents { v2.append(Float(0))}
   return compare(v1, v2)
}

let version1 = "21423542342342342365435.243543543645754687652"
let version2 = "21423542342342342365435.24354354364575468765"

let outcome  = compareVersionsStrings(version1, version2)
print(outcome)  //v1Bigger

我认为这可以处理所有不平衡或无效输入的情况,但是如果您发现更多情况,将很容易适应。