Search Here

Custom Search

Wednesday, January 16, 2008

A simple method to compare versions

Sometimes we may need to compare two versions to know which one is newer and which one is older or whether both of those are same versions. Let me explain. Suppose you have two versions in hand as String “7.2.1″ and “7.1.1″. Now you wanna know which one is the later version. At the very first sight you may think that simple string comparison will give the correct decision. But unfortunately it won’t work correctly always. Think about this input : “10.0.1″ and “9.5.2″. String comparison will return the second one as latest version. But you expect the first one. So definitely we should change the algorithm.

A very simple algorithm is to split the input string by “.” and compare individual components. It guarantees you the correct output. Here is my implementation of the method. I have applied Unit Testing (www.junit.org , www.nunit.org) on it and it passes all possible test cases. You can use it without any doubt and it works for any length of versions.

Here is the implementation. Same code will run both in Java and C#.NET



/* This method compares two given versions and returns 0,1 or -1
It returns 0 if both versions are equal,
1 if first version is newer than second one,
-1 if first version is older than the second one.
Example:
compareVersion("7.1","7.1") will return 0
compareVersion("7.1.1","7.1.1") will return 0
compareVersion("7.1","7.1.1") will return -1
compareVersion("7.1","7.2") will return -1
compareVersion("7.1","7.2.2") will return -1
compareVersion("7.2","7.1") will return 1
compareVersion("7.2.0","7.1") will return 1
compareVersion("7.2.0","7.2") will return 0
compareVersion("7.abc.0","7.2") will throw exception
*/
public static int compareVersion(String v1, String v2) throws Exception {
String[] v1Tokens = v1.split("\\."); // for C#: String[] v1Tokens = v1.split(".");
String[] v2Tokens = v2.split("\\."); // for C#: String[] v2Tokens = v2.split(".");
int maxLen;

if (v1Tokens.length > v2Tokens.length)
maxLen = v1Tokens.length;
else
maxLen = v2Tokens.length;

for (int i = 0; i < maxLen; i++) {
int n1, n2;

n1 = n2 = 0;

try {
if (i < v1Tokens.length)
n1 = Integer.parseInt(v1Tokens[i]);

if (n1 < 0)
throw new Exception(v1 + " is not a valid version.");
} catch (Exception ex) {
throw new Exception(v1 + " is not a valid version.");
}

try {
if (i < v2Tokens.length)
n2 = Integer.parseInt(v2Tokens[i]);

if (n2 < 0)
throw new Exception(v2 + " is not a valid version.");
} catch (Exception ex) {
throw new Exception(v2 + " is not a valid version.");
}

if (n1 > n2)
return 1;
else if (n1 < n2)
return -1;
}

return 0;
}

No comments: