2014-04-02 43 views
1

这里有一个有趣的任务......转换semver版本字符串(10.2.3)长

给予了很多的版本字符串的 - 假设他们都或多或少的语义版本semantic version号码,如1.2.3 - 有什么办法把它转换成长的(用Java),所以它认为“1.2.34”小于“12.3.0”?

这里是我到目前为止

public static Long toLong(String version) { 
    if (version == null || version.isEmpty()) { 
     return 0L; 
    } 
    String[] parts = version.split("[^0-9]"); 
    long number = 0L; 
    long factor = 1; 
    for (int b = parts.length - 1; b >= 0; b--) { 
     try { 
      Long l = Long.parseLong(parts[b]); 
      number += l * factor; 
      factor = factor * 100; 
     } catch (NumberFormatException e){ 
      // silently ignored 
     } 
    } 
    return number; 
} 

它假定字符串中没有位置有两个以上的数字(所以1.2.3.4567)将无法正常工作,但我可以忍受的。但我想要更快一点。

+0

为什么“长”?为什么不是一个有重要,次要和补丁成员(以及其他部分的成员)的课程? – Biffen

+0

好问题。主要优化,简化和互操作性。长期价值进入其他(非Java)系统,我们想要一些简单和超快的比较。 – PapaFreud

回答

0

可以内String执行类似的变换:

// add "." to format the major version 
("." + versionString). 
    // replace each "." with "a00" 
    replaceAll("\\.", "a00"). 
    // keep 2 digits, remove "a" and extra leading "0" 
    replaceAll("a0+([0-9]{2})", "$1"); 

这种方法可以用于不同数量的显著数字和/或不同格式的输入字符串的可以容易地通过。性能比toLong方法慢约2.5倍(格式化1M版本字符串为2.5秒)。如果性能比代码的简单性更重要,则比toLong方法快大约5.5倍(对于1M字符串为0.2 s):

public static Long toLong2(String versionString) 
{ 
    if (versionString == null || versionString.isEmpty()) 
    { 
    return 0L; 
    } // end if empty 
    char[] C = versionString.toCharArray(); 
    int i, i1 = 0, i2 = C.length; 
    Long l, number = 0L, factor = 1L; 
    try 
    { 
    for (i = C.length - 1; i > 0; i--) 
    { 
     if (C[i] == '.') 
     { 
     i1 = i + 1; 
     l = Long.parseLong(versionString.substring(i1, i2)); 
     i2 = i; 
     number += l * factor; 
     factor = factor * 100L; 
     } // end if '.' 
    } // end for i 
    l = Long.parseLong(versionString.substring(0, i2)); 
    number += l * factor; 
    } 
    catch (NumberFormatException e) 
    { 
    // silently ignored 
    } // end try 
    return number; 
} // end method toLong2