以下为题目描述
问题描述
在某个项目中,每个版本都用版本号标记,由一个或多个修订号组成,修订号之间由点号.分隔。每个修订号可能有多位数字,并且可能会包含前导零。你需要根据两个版本号 version1 和 version2,判断哪个版本更新,或者它们是否相同。
例如,2.5.33 和 0.1 都是有效的版本号。
当比较两个版本时,从左到右依次比较它们的修订号。忽略每个修订号的前导零,直接比较修订号对应的整数值。如果其中一个版本没有足够的修订号,缺失部分默认补为0。
你需要根据以下规则返回比较结果:
- 如果
version1 > version2,返回1。 - 如果
version1 < version2,返回-1。 - 如果两个版本相等,返回
0。
测试样例
样例1:
输入:
version1 = "0.1" , version2 = "1.1"
输出:-1
样例2:
输入:
version1 = "1.0.1" , version2 = "1"
输出:1
样例3:
输入:
version1 = "7.5.2.4" , version2 = "7.5.3"
输出:-1
样例4:
输入:
version1 = "1.0" , version2 = "1.0.0"
输出:0
解决方案
import java.math.BigInteger;
public class Main {
public static void main(String[] args) {
System.out.println(solution("0.1", "1.1") == -1);
System.out.println(solution("1.0.1", "1") == 1);
System.out.println(solution("7.5.2.4", "7.5.3") == -1);
System.out.println(solution("1.0", "1.0.0") == 0);
}
public static int solution(String version1, String version2) {
// Split the version strings into revision numbers
String[] revisions1 = version1.split("\\.");
String[] revisions2 = version2.split("\\.");
// Determine the maximum length to iterate over
int maxLength = Math.max(revisions1.length, revisions2.length);
for (int i = 0; i < maxLength; i++) {
// 获取第 i 个修订号,若超出数组长度,则补为 "0"
String rev1 = i < revisions1.length ? revisions1[i] : "0";
String rev2 = i < revisions2.length ? revisions2[i] : "0";
// 去除前导零
rev1 = rev1.replaceFirst("^0+", "");
rev2 = rev2.replaceFirst("^0+", "");
// 如果去除前导零后为空,则修订号为 "0"
if (rev1.isEmpty()) rev1 = "0";
if (rev2.isEmpty()) rev2 = "0";
// 转换为 BigInteger
BigInteger num1 = new BigInteger(rev1);
BigInteger num2 = new BigInteger(rev2);
// 比较两个修订号
int comparison = num1.compareTo(num2);
if (comparison > 0) {
return 1; // version1 is greater
} else if (comparison < 0) {
return -1; // version2 is greater
}
// If equal, continue to next revision
}
// All revisions are equal
return 0;
}
}
代码解释
- 分割版本号字符串
String[] revisions1 = version1.split("\\.");
String[] revisions2 = version2.split("\\.");
首先先来分割版本号字符串,使用正则表达式来解决
• 使用正则表达式 "\." 将版本号字符串按点号分割,得到修订号数组
• 例如,"1.0.1" 分割后得到 ["1", "0", "1"]
2.确定比较的最大长度
int maxLength = Math.max(revisions1.length, revisions2.length);
• 为了比较所有修订号,取两个版本修订号数组的最大长度
- 逐个比较修订号
for (int i = 0; i < maxLength; i++) {
// 获取第 i 个修订号,若超出数组长度,则补为 "0"
String rev1 = i < revisions1.length ? revisions1[i] : "0";
String rev2 = i < revisions2.length ? revisions2[i] : "0";
// 去除前导零
rev1 = rev1.replaceFirst("^0+", "");
rev2 = rev2.replaceFirst("^0+", "");
// 如果去除前导零后为空,则修订号为 "0"
if (rev1.isEmpty()) rev1 = "0";
if (rev2.isEmpty()) rev2 = "0";
// 转换为 BigInteger
BigInteger num1 = new BigInteger(rev1);
BigInteger num2 = new BigInteger(rev2);
// 比较两个修订号
int comparison = num1.compareTo(num2);
if (comparison > 0) {
return 1; // version1 更大
} else if (comparison < 0) {
return -1; // version2 更大
}
// 若相等,继续下一轮比较
}
• 获取修订号:
使用条件运算符检查索引是否越界,若越界则补为 "0"。
• 去除前导零:
使用正则表达式 "^0+" 去除字符串开头的所有零,例如,"001" 去除前导零后得到 "1"。
如果去除后为空字符串,则说明修订号原本是 "0" 或者全是零,需要将其设为 "0"。
• 转换为 BigInteger :
使用 BigInteger 而不是 Integer 或 Long,是为了防止修订号过大导致溢出。
• 比较修订号:
使用 compareTo 方法比较两个 BigInteger 对象。
如果 num1 大于 num2,返回 1。
如果 num1 小于 num2,返回 -1。
如果相等,继续比较下一个修订号