你如何比较Java中的两个版本string?
有比较版本号的标准习惯用法吗? 我不能只使用一个stringcompareTo,因为我还不知道最大的点数是多less。 我需要比较版本,并具有以下内容:
1.0 < 1.1 1.0.1 < 1.1 1.9 < 1.10
以点作为分隔符对string进行标记,然后从左侧开始逐个比较整数转换。
这个旧post的另一个解决scheme(对于那些可能有帮助的):
public class Version implements Comparable<Version> { private String version; public final String get() { return this.version; } public Version(String version) { if(version == null) throw new IllegalArgumentException("Version can not be null"); if(!version.matches("[0-9]+(\\.[0-9]+)*")) throw new IllegalArgumentException("Invalid version format"); this.version = version; } @Override public int compareTo(Version that) { if(that == null) return 1; String[] thisParts = this.get().split("\\."); String[] thatParts = that.get().split("\\."); int length = Math.max(thisParts.length, thatParts.length); for(int i = 0; i < length; i++) { int thisPart = i < thisParts.length ? Integer.parseInt(thisParts[i]) : 0; int thatPart = i < thatParts.length ? Integer.parseInt(thatParts[i]) : 0; if(thisPart < thatPart) return -1; if(thisPart > thatPart) return 1; } return 0; } @Override public boolean equals(Object that) { if(this == that) return true; if(that == null) return false; if(this.getClass() != that.getClass()) return false; return this.compareTo((Version) that) == 0; } }
Version a = new Version("1.1"); Version b = new Version("1.1.1"); a.compareTo(b) // return -1 (a<b) a.equals(b) // return false Version a = new Version("2.0"); Version b = new Version("1.9.9"); a.compareTo(b) // return 1 (a>b) a.equals(b) // return false Version a = new Version("1.0"); Version b = new Version("1"); a.compareTo(b) // return 0 (a=b) a.equals(b) // return true Version a = new Version("1"); Version b = null; a.compareTo(b) // return 1 (a>b) a.equals(b) // return false List<Version> versions = new ArrayList<Version>(); versions.add(new Version("2")); versions.add(new Version("1.0.5")); versions.add(new Version("1.01.0")); versions.add(new Version("1.00.1")); Collections.min(versions).get() // return min version Collections.max(versions).get() // return max version // WARNING Version a = new Version("2.06"); Version b = new Version("2.060"); a.equals(b) // return false
编辑:
@davisog:感谢您的评论,这段代码是针对Android平台开发的,正如Google所推荐的,“匹配”方法检查整个string,而不像使用监pipe模式的Java。 ( Android文档 – JAVA文档 )
使用Maven非常简单:
import org.apache.maven.artifact.versioning.DefaultArtifactVersion; DefaultArtifactVersion minVersion = new DefaultArtifactVersion("1.0.1"); DefaultArtifactVersion maxVersion = new DefaultArtifactVersion("1.10"); DefaultArtifactVersion version = new DefaultArtifactVersion("1.11"); if (version.compareTo(minVersion) < 0 || version.compareTo(maxVersion) > 0) { System.out.println("Sorry, your version is unsupported"); }
你可以从这个页面获得Maven Artifact的正确的依赖string:
<dependency> <groupId>org.apache.maven</groupId> <artifactId>maven-artifact</artifactId> <version>3.0.3</version> </dependency>
您需要对版本string进行规范化处理,以便进行比较。 就像是
import java.util.regex.Pattern; public class Main { public static void main(String... args) { compare("1.0", "1.1"); compare("1.0.1", "1.1"); compare("1.9", "1.10"); compare("1.a", "1.9"); } private static void compare(String v1, String v2) { String s1 = normalisedVersion(v1); String s2 = normalisedVersion(v2); int cmp = s1.compareTo(s2); String cmpStr = cmp < 0 ? "<" : cmp > 0 ? ">" : "=="; System.out.printf("'%s' %s '%s'%n", v1, cmpStr, v2); } public static String normalisedVersion(String version) { return normalisedVersion(version, ".", 4); } public static String normalisedVersion(String version, String sep, int maxWidth) { String[] split = Pattern.compile(sep, Pattern.LITERAL).split(version); StringBuilder sb = new StringBuilder(); for (String s : split) { sb.append(String.format("%" + maxWidth + 's', s)); } return sb.toString(); } }
打印
'1.0' < '1.1' '1.0.1' < '1.1' '1.9' < '1.10' '1.a' > '1.9'
最好重用现有代码,使用Maven的ComparableVersion类
优点:
- Apache许可证,版本2.0,
- testing,
- 使用(复制)在像spring-security-core,jboss等多个项目
- 多个function
- 它已经是java.lang.Comparable了
- 只是复制粘贴一个类,没有第三方的依赖关系
不要在maven-artifact中包含依赖项,因为这会拉动各种传递依赖
// VersionComparator.java import java.util.Comparator; public class VersionComparator implements Comparator { public boolean equals(Object o1, Object o2) { return compare(o1, o2) == 0; } public int compare(Object o1, Object o2) { String version1 = (String) o1; String version2 = (String) o2; VersionTokenizer tokenizer1 = new VersionTokenizer(version1); VersionTokenizer tokenizer2 = new VersionTokenizer(version2); int number1 = 0, number2 = 0; String suffix1 = "", suffix2 = ""; while (tokenizer1.MoveNext()) { if (!tokenizer2.MoveNext()) { do { number1 = tokenizer1.getNumber(); suffix1 = tokenizer1.getSuffix(); if (number1 != 0 || suffix1.length() != 0) { // Version one is longer than number two, and non-zero return 1; } } while (tokenizer1.MoveNext()); // Version one is longer than version two, but zero return 0; } number1 = tokenizer1.getNumber(); suffix1 = tokenizer1.getSuffix(); number2 = tokenizer2.getNumber(); suffix2 = tokenizer2.getSuffix(); if (number1 < number2) { // Number one is less than number two return -1; } if (number1 > number2) { // Number one is greater than number two return 1; } boolean empty1 = suffix1.length() == 0; boolean empty2 = suffix2.length() == 0; if (empty1 && empty2) continue; // No suffixes if (empty1) return 1; // First suffix is empty (1.2 > 1.2b) if (empty2) return -1; // Second suffix is empty (1.2a < 1.2) // Lexical comparison of suffixes int result = suffix1.compareTo(suffix2); if (result != 0) return result; } if (tokenizer2.MoveNext()) { do { number2 = tokenizer2.getNumber(); suffix2 = tokenizer2.getSuffix(); if (number2 != 0 || suffix2.length() != 0) { // Version one is longer than version two, and non-zero return -1; } } while (tokenizer2.MoveNext()); // Version two is longer than version one, but zero return 0; } return 0; } } // VersionTokenizer.java public class VersionTokenizer { private final String _versionString; private final int _length; private int _position; private int _number; private String _suffix; private boolean _hasValue; public int getNumber() { return _number; } public String getSuffix() { return _suffix; } public boolean hasValue() { return _hasValue; } public VersionTokenizer(String versionString) { if (versionString == null) throw new IllegalArgumentException("versionString is null"); _versionString = versionString; _length = versionString.length(); } public boolean MoveNext() { _number = 0; _suffix = ""; _hasValue = false; // No more characters if (_position >= _length) return false; _hasValue = true; while (_position < _length) { char c = _versionString.charAt(_position); if (c < '0' || c > '9') break; _number = _number * 10 + (c - '0'); _position++; } int suffixStart = _position; while (_position < _length) { char c = _versionString.charAt(_position); if (c == '.') break; _position++; } _suffix = _versionString.substring(suffixStart, _position); if (_position < _length) _position++; return true; } }
例:
public class Main { private static VersionComparator cmp; public static void main (String[] args) { cmp = new VersionComparator(); Test(new String[]{"1.1.2", "1.2", "1.2.0", "1.2.1", "1.12"}); Test(new String[]{"1.3", "1.3a", "1.3b", "1.3-SNAPSHOT"}); } private static void Test(String[] versions) { for (int i = 0; i < versions.length; i++) { for (int j = i; j < versions.length; j++) { Test(versions[i], versions[j]); } } } private static void Test(String v1, String v2) { int result = cmp.compare(v1, v2); String op = "=="; if (result < 0) op = "<"; if (result > 0) op = ">"; System.out.printf("%s %s %s\n", v1, op, v2); } }
输出:
1.1.2 == 1.1.2 ---> same length and value 1.1.2 < 1.2 ---> first number (1) less than second number (2) => -1 1.1.2 < 1.2.0 ---> first number (1) less than second number (2) => -1 1.1.2 < 1.2.1 ---> first number (1) less than second number (2) => -1 1.1.2 < 1.12 ---> first number (1) less than second number (12) => -1 1.2 == 1.2 ---> same length and value 1.2 == 1.2.0 ---> first shorter than second, but zero 1.2 < 1.2.1 ---> first shorter than second, and non-zero 1.2 < 1.12 ---> first number (2) less than second number (12) => -1 1.2.0 == 1.2.0 ---> same length and value 1.2.0 < 1.2.1 ---> first number (0) less than second number (1) => -1 1.2.0 < 1.12 ---> first number (2) less than second number (12) => -1 1.2.1 == 1.2.1 ---> same length and value 1.2.1 < 1.12 ---> first number (2) less than second number (12) => -1 1.12 == 1.12 ---> same length and value 1.3 == 1.3 ---> same length and value 1.3 > 1.3a ---> first suffix ('') is empty, but not second ('a') => 1 1.3 > 1.3b ---> first suffix ('') is empty, but not second ('b') => 1 1.3 > 1.3-SNAPSHOT ---> first suffix ('') is empty, but not second ('-SNAPSHOT') => 1 1.3a == 1.3a ---> same length and value 1.3a < 1.3b ---> first suffix ('a') compared to second suffix ('b') => -1 1.3a < 1.3-SNAPSHOT ---> first suffix ('a') compared to second suffix ('-SNAPSHOT') => -1 1.3b == 1.3b ---> same length and value 1.3b < 1.3-SNAPSHOT ---> first suffix ('b') compared to second suffix ('-SNAPSHOT') => -1 1.3-SNAPSHOT == 1.3-SNAPSHOT ---> same length and value
想知道为什么大家都认为这些版本只是由整数组成 – 在我的情况下并不是这样。
为什么重新发明轮子(假定版本遵循Semver标准)
首先通过Maven安装https://github.com/vdurmont/semver4j
然后使用这个库
Semver sem = new Semver("1.2.3"); sem.isGreaterThan("1.2.2"); // true
public static int compareVersions(String version1, String version2){ String[] levels1 = version1.split("\\."); String[] levels2 = version2.split("\\."); int length = Math.max(levels1.length, levels2.length); for (int i = 0; i < length; i++){ Integer v1 = i < levels1.length ? Integer.parseInt(levels1[i]) : 0; Integer v2 = i < levels2.length ? Integer.parseInt(levels2[i]) : 0; int compare = v1.compareTo(v2); if (compare != 0){ return compare; } } return 0; }
public int compare(String v1, String v2) { v1 = v1.replaceAll("\\s", ""); v2 = v2.replaceAll("\\s", ""); String[] a1 = v1.split("\\."); String[] a2 = v2.split("\\."); List<String> l1 = Arrays.asList(a1); List<String> l2 = Arrays.asList(a2); int i=0; while(true){ Double d1 = null; Double d2 = null; try{ d1 = Double.parseDouble(l1.get(i)); }catch(IndexOutOfBoundsException e){ } try{ d2 = Double.parseDouble(l2.get(i)); }catch(IndexOutOfBoundsException e){ } if (d1 != null && d2 != null) { if (d1.doubleValue() > d2.doubleValue()) { return 1; } else if (d1.doubleValue() < d2.doubleValue()) { return -1; } } else if (d2 == null && d1 != null) { if (d1.doubleValue() > 0) { return 1; } } else if (d1 == null && d2 != null) { if (d2.doubleValue() > 0) { return -1; } } else { break; } i++; } return 0; }
对于我的项目,我使用我的公共版本库https://github.com/raydac/commons-version它包含两个辅助类; – parsing版本(parsing版本可以与另一个版本对象比较,因为它是可比较的)和VersionValidator它允许检查一些expression式,如!=ide-1.1.1,>idea-1.3.4-SNAPSHOT;<1.2.3
我使用语义版本约定为 Android平台上的版本创build了一个简单的实用程序 。 所以它只适用于格式为XYZ(Major.Minor.Patch)的string,其中X,Y和Z是非负整数。 你可以在我的GitHub上find它。
方法Version.compareVersions(String v1,String v2)比较两个版本string。 如果版本相同,则返回0;如果版本v1在版本v2之前,则返回1;如果版本v2在版本v2之后,则返回-1;如果版本格式无效,则返回-2。
自己写了一个小函数
public static boolean checkVersionUpdate(String olderVerison, String newVersion) { if (olderVerison.length() == 0 || newVersion.length() == 0) { return false; } List<String> newVerList = Arrays.asList(newVersion.split("\\.")); List<String> oldVerList = Arrays.asList(olderVerison.split("\\.")); int diff = newVerList.size() - oldVerList.size(); List<String> newList = new ArrayList<>(); if (diff > 0) { newList.addAll(oldVerList); for (int i = 0; i < diff; i++) { newList.add("0"); } return examineArray(newList, newVerList, diff); } else if (diff < 0) { newList.addAll(newVerList); for (int i = 0; i < -diff; i++) { newList.add("0"); } return examineArray(oldVerList, newList, diff); } else { return examineArray(oldVerList, newVerList, diff); } } public static boolean examineArray(List<String> oldList, List<String> newList, int diff) { boolean newVersionGreater = false; for (int i = 0; i < oldList.size(); i++) { if (Integer.parseInt(newList.get(i)) > Integer.parseInt(oldList.get(i))) { newVersionGreater = true; break; } else if (Integer.parseInt(newList.get(i)) < Integer.parseInt(oldList.get(i))) { newVersionGreater = false; break; } else { newVersionGreater = diff > 0; } } return newVersionGreater; }
我创build了一个简单的实用程序方法,几乎适用于除alpha和beta版本以外的所有情况。
/** * Compares versions * * @param ver1 * @param ver2 * @return 1 if {@code ver1} is > {@code ver2}, -1 if {@code ver1} is < {@code ver2} and 0 otherwise */ public static int compareVersions(String ver1, String ver2) { // some null validations if (ver1 == null || ver2 == null) { return ver1 == ver2 ? 0 : ver1 == null ? -1 : 1; } String v1 = ver1.replaceAll("[^0-9]+", ""); String v2 = ver2.replaceAll("[^0-9]+", ""); int len1 = v1.length(); int len2 = v2.length(); // trim any trailing 0 (for comparing cases 6.3 and 6.3.0) if (len1 > 0 && len2 > 0) { v1 = (v1.charAt(len1 - 1) == '0') ? v1.substring(0, len1 - 1) : v1; v2 = (v2.charAt(len2 - 1) == '0') ? v2.substring(0, len2 - 1) : v2; } int res = v1.compareTo(v2); return res < 0 ? -1 : res > 0 ? 1 : res; }
这是对它的unit testing:
@Test public void testCompareSDKVersions() { assertEquals(1, compareSDKVersions("6.3.2", "5.2.4")); assertEquals(1, compareSDKVersions("6.3.2-snapshot", "5.3.4")); assertEquals(1, compareSDKVersions("7.0", "2.3.0")); assertEquals(1, compareSDKVersions("7.0", "")); assertEquals(1, compareSDKVersions("6.3.0", null)); assertEquals(0, compareSDKVersions("6.3", "6.3")); assertEquals(0, compareSDKVersions("6.3", "6.3.0")); assertEquals(0, compareSDKVersions("6.3.2-snapshot", "6.3.2")); assertEquals(0, compareSDKVersions(null, null)); assertEquals(-1, compareSDKVersions("6.3.2", "6.3.3")); assertEquals(-1, compareSDKVersions("6.0.1", "6.3")); assertEquals(-1, compareSDKVersions("6.2", "6.3.0")); assertEquals(-1, compareSDKVersions("", "7.0")); assertEquals(-1, compareSDKVersions("6_2", "6_3_0")); assertEquals(-1, compareSDKVersions(null, "6.3.0")); }
compareSDKVersions
方法基本上除去了版本string中的所有数字,并按字典顺序进行比较。
这是一个优化的实现:
public static final Comparator<CharSequence> VERSION_ORDER = new Comparator<CharSequence>() { @Override public int compare (CharSequence lhs, CharSequence rhs) { int ll = lhs.length(), rl = rhs.length(), lv = 0, rv = 0, li = 0, ri = 0; char c; do { lv = rv = 0; while (--ll >= 0) { c = lhs.charAt(li++); if (c < '0' || c > '9') break; lv = lv*10 + c - '0'; } while (--rl >= 0) { c = rhs.charAt(ri++); if (c < '0' || c > '9') break; rv = rv*10 + c - '0'; } } while (lv == rv && (ll >= 0 || rl >= 0)); return lv - rv; } };
结果:
"0.1" - "1.0" = -1 "1.0" - "1.0" = 0 "1.0" - "1.0.0" = 0 "10" - "1.0" = 9 "3.7.6" - "3.7.11" = -5 "foobar" - "1.0" = -1
对于Scala,您可以使用我制作的库: https : //github.com/kypeli/sversion
Version("1.2") > Version("1.1") // true Version("1.2.1") > Version("1.1.2") // true Version("1.1.1") == Version("1.1.1") // true Version("1.1.1") > Version("1.1") // true Version("1.1.0") == Version("1.1") // true Version("1.1-RC2") > Version("1.1-RC1") // true Version("1.1-RC1") > Version("1.1") // true
此代码尝试解决这种types的比较版本。
大多数版本说明符(如> = 1.0)都是不言自明的。 说明符〜>有特殊的含义,最好用例子来表示。 > 2.0.3与> = 2.0.3和<2.1相同。 > 2.1与> = 2.1和<3.0相同。
public static boolean apply(String cmpDeviceVersion, String reqDeviceVersion) { Boolean equal = !cmpDeviceVersion.contains(">") && !cmpDeviceVersion.contains(">=") && !cmpDeviceVersion.contains("<") && !cmpDeviceVersion.contains("<=") && !cmpDeviceVersion.contains("~>"); Boolean between = cmpDeviceVersion.contains("~>"); Boolean higher = cmpDeviceVersion.contains(">") && !cmpDeviceVersion.contains(">=") && !cmpDeviceVersion.contains("~>"); Boolean higherOrEqual = cmpDeviceVersion.contains(">="); Boolean less = cmpDeviceVersion.contains("<") && !cmpDeviceVersion.contains("<="); Boolean lessOrEqual = cmpDeviceVersion.contains("<="); cmpDeviceVersion = cmpDeviceVersion.replaceAll("[<>=~]", ""); cmpDeviceVersion = cmpDeviceVersion.trim(); String[] version = cmpDeviceVersion.split("\\."); String[] reqVersion = reqDeviceVersion.split("\\."); if(equal) { return isEqual(version, reqVersion); } else if(between) { return isBetween(version, reqVersion); } else if(higher) { return isHigher(version, reqVersion); } else if(higherOrEqual) { return isEqual(version, reqVersion) || isHigher(version, reqVersion); } else if(less) { return isLess(version, reqVersion); } else if(lessOrEqual) { return isEqual(version, reqVersion) || isLess(version, reqVersion); } return false; } private static boolean isEqual(String[] version, String[] reqVersion) { String strVersion = StringUtils.join(version); String strReqVersion = StringUtils.join(reqVersion); if(version.length > reqVersion.length) { Integer diff = version.length - reqVersion.length; strReqVersion += StringUtils.repeat(".0", diff); } else if(reqVersion.length > version.length) { Integer diff = reqVersion.length - version.length; strVersion += StringUtils.repeat(".0", diff); } return strVersion.equals(strReqVersion); } private static boolean isHigher(String[] version, String[] reqVersion) { String strVersion = StringUtils.join(version); String strReqVersion = StringUtils.join(reqVersion); if(version.length > reqVersion.length) { Integer diff = version.length - reqVersion.length; strReqVersion += StringUtils.repeat(".0", diff); } else if(reqVersion.length > version.length) { Integer diff = reqVersion.length - version.length; strVersion += StringUtils.repeat(".0", diff); } return strReqVersion.compareTo(strVersion) > 0; } private static boolean isLess(String[] version, String[] reqVersion) { String strVersion = StringUtils.join(version); String strReqVersion = StringUtils.join(reqVersion); if(version.length > reqVersion.length) { Integer diff = version.length - reqVersion.length; strReqVersion += StringUtils.repeat(".0", diff); } else if(reqVersion.length > version.length) { Integer diff = reqVersion.length - version.length; strVersion += StringUtils.repeat(".0", diff); } return strReqVersion.compareTo(strVersion) < 0; } private static boolean isBetween(String[] version, String[] reqVersion) { return (isEqual(version, reqVersion) || isHigher(version, reqVersion)) && isLess(getNextVersion(version), reqVersion); } private static String[] getNextVersion(String[] version) { String[] nextVersion = new String[version.length]; for(int i = version.length - 1; i >= 0 ; i--) { if(i == version.length - 1) { nextVersion[i] = "0"; } else if((i == version.length - 2) && NumberUtils.isNumber(version[i])) { nextVersion[i] = String.valueOf(NumberUtils.toInt(version[i]) + 1); } else { nextVersion[i] = version[i]; } } return nextVersion; }
我喜欢@Peter Lawrey的想法,而且我把它扩展到了更多的限制:
/** * Normalize string array, * Appends zeros if string from the array * has length smaller than the maxLen. **/ private String normalize(String[] split, int maxLen){ StringBuilder sb = new StringBuilder(""); for(String s : split) { for(int i = 0; i<maxLen-s.length(); i++) sb.append('0'); sb.append(s); } return sb.toString(); } /** * Removes trailing zeros of the form '.00.0...00' * (and does not remove zeros from, say, '4.1.100') **/ public String removeTrailingZeros(String s){ int i = s.length()-1; int k = s.length()-1; while(i >= 0 && (s.charAt(i) == '.' || s.charAt(i) == '0')){ if(s.charAt(i) == '.') k = i-1; i--; } return s.substring(0,k+1); } /** * Compares two versions(works for alphabets too), * Returns 1 if v1 > v2, returns 0 if v1 == v2, * and returns -1 if v1 < v2. **/ public int compareVersion(String v1, String v2) { // Uncomment below two lines if for you, say, 4.1.0 is equal to 4.1 // v1 = removeTrailingZeros(v1); // v2 = removeTrailingZeros(v2); String[] splitv1 = v1.split("\\."); String[] splitv2 = v2.split("\\."); int maxLen = 0; for(String str : splitv1) maxLen = Math.max(maxLen, str.length()); for(String str : splitv2) maxLen = Math.max(maxLen, str.length()); int cmp = normalize(splitv1, maxLen).compareTo(normalize(splitv2, maxLen)); return cmp > 0 ? 1 : (cmp < 0 ? -1 : 0); }
希望它可以帮助别人。 它通过了所有的testing用例在比特位和代码中(需要在compareVersion函数中取消注释两行)。
轻松testing!
public class VersionComparator { /* loop through both version strings * then loop through the inner string to computer the val of the int * for each integer read, do num*10+<integer read> * and stop when stumbling upon '.' * When '.' is encountered... * see if '.' is encountered for both strings * if it is then compare num1 and num2 * if num1 == num2... iterate over p1++, p2++ * else return (num1 > num2) ? 1 : -1 * If both the string end then compare(num1, num2) return 0, 1, -1 * else loop through the longer string and * verify if it only has trailing zeros * If it only has trailing zeros then return 0 * else it is greater than the other string */ public static int compareVersions(String v1, String v2) { int num1 = 0; int num2 = 0; int p1 = 0; int p2 = 0; while (p1 < v1.length() && p2 < v2.length()) { num1 = Integer.parseInt(v1.charAt(p1) + ""); num2 = Integer.parseInt(v2.charAt(p2) + ""); p1++; p2++; while (p1 < v1.length() && p2 < v2.length() && v1.charAt(p1) != '.' && v2.charAt(p2) != '.') { if (p1 < v1.length()) num1 = num1 * 10 + Integer.parseInt(v1.charAt(p1) + ""); if (p2 < v2.length()) num2 = num2 * 10 + Integer.parseInt(v2.charAt(p2) + ""); p1++; p2++; } if (p1 < v1.length() && p2 < v2.length() && v1.charAt(p1) == '.' && v2.charAt(p2) == '.') { if ((num1 ^ num2) == 0) { p1++; p2++; } else return (num1 > num2) ? 1 : -1; } else if (p1 < v1.length() && p2 < v2.length() && v1.charAt(p1) == '.') return -1; else if (p1 < v1.length() && p2 < v2.length() && v2.charAt(p2) == '.') return 1; } if (p1 == v1.length() && p2 == v2.length()) { if ((num1 ^ num2) == 0) return 0; else return (num1 > num2) ? 1 : -1; } else if (p1 == v1.length()) { if ((num1 ^ num2) == 0) { while (p2 < v2.length()) { if (v2.charAt(p2) != '.' && v2.charAt(p2) != '0') return -1; p2++; } return 0; } else return (num1 > num2) ? 1 : -1; } else { if ((num1 ^ num2) == 0) { while (p1 < v1.length()) { if (v1.charAt(p1) != '.' && v1.charAt(p1) != '0') return 1; p1++; } return 0; } else return (num1 > num2) ? 1 : -1; } } public static void main(String[] args) { System.out.println(compareVersions("11.23", "11.21.1.0.0.1.0") ^ 1); System.out.println(compareVersions("11.21.1.0.0.1.0", "11.23") ^ -1); System.out.println(compareVersions("11.23", "11.23.0.0.0.1.0") ^ -1); System.out.println(compareVersions("11.2", "11.23") ^ -1); System.out.println(compareVersions("11.23", "11.21.1.0.0.1.0") ^ 1); System.out.println(compareVersions("1.21.1.0.0.1.0", "2.23") ^ -1); System.out.println(compareVersions("11.23", "11.21.1.0.0.1.0") ^ 1); System.out.println(compareVersions("11.23.0.0.0.0.0", "11.23") ^ 0); System.out.println(compareVersions("11.23", "11.21.1.0.0.1.0") ^ 1); System.out.println(compareVersions("1.5.1.3", "1.5.1.3.0") ^ 0); System.out.println(compareVersions("1.5.1.4", "1.5.1.3.0") ^ 1); System.out.println(compareVersions("1.2.1.3", "1.5.1.3.0") ^ -1); System.out.println(compareVersions("1.2.1.3", "1.22.1.3.0") ^ -1); System.out.println(compareVersions("1.222.1.3", "1.22.1.3.0") ^ 1); } }
我的Java解决scheme
public int compareVersion(String version1, String version2) { String[] first = version1.split("\\."); String[] second = version2.split("\\."); int len = first.length<=second.length? first.length:second.length; // the loop runs for whichever is the short version of two strings for(int i=0;i<len;i++){ int firstInt = Integer.parseInt(first[i]); int secondInt = Integer.parseInt(second[i]); if(firstInt<secondInt){ return -1; } else if(firstInt>secondInt){ return 1; } } // below two condition check if the length are the not the same //if first string length is short then start from after first string length and compare it with second string value. second string value is not zero that means it is greater. if(first.length<second.length){ for(int i=first.length;i<second.length;i++){ int secondInt = Integer.parseInt(second[i]); if(secondInt!=0){ return -1; } } } // similar logic as above just that first length is grater this time. else if(first.length>second.length){ for(int i=second.length;i<first.length;i++){ int firstInt = Integer.parseInt(first[i]); if(firstInt!=0){ return 1; } } } // return 0 if both string value is the same return 0; }