165. Compare Version Numbers

本文介绍了一种用于比较软件版本号的算法实现。该算法通过解析版本号字符串,并将其拆分为多个部分进行逐位比较,从而确定两个版本之间的大小关系。

Compare two version numbers version1 and version2.
If version1 > version2 return 1, if version1 < version2 return -1, otherwise return 0.

You may assume that the version strings are non-empty and contain only digits and the . character.
The . character does not represent a decimal point and is used to separate number sequences.
For instance, 2.5 is not "two and a half" or "half way to version three", it is the fifth second-level revision of the second first-level revision.

Here is an example of version numbers ordering:

0.1 < 1.1 < 1.2 < 13.37


The idea is simple:

Code:

public class Solution {
    public int compareVersion(String version1, String version2) {
        String[] v1 = ("1.1." + version1).split("\\.");
        String[] v2 = ("1.1." + version2).split("\\.");
        int i = 0;
        
        while(i < v1.length && i < v2.length){
            int i1 = Integer.parseInt(v1[i]);
            int i2 = Integer.parseInt(v2[i]);
            if(i1 > i2){
                return 1;
            } else if(i1 < i2){
                return -1;
            } else{
                i++;
            }
        }
        
        
        while(i < v1.length){
            if(Integer.parseInt(v1[i]) != 0){
                return 1;
            }
            i++;
        }
    
        while(i < v2.length){
            if(Integer.parseInt(v2[i]) != 0){
                return- 1;
            }
            i++;
        }
        
        return 0;
    }
}
This Question is Simple, but still something need to remember:

1. Java Split a String , should path a regex, not a String, if split(".") it will return an empty array.

2. for those questions that v1 and v2 has different length, like this question or add two String,  there are 2 solutions.

a. use three while loop like this.

b. use one while loop, and in the while loop make additional judgement, if index exceeds the boundary give it a default value. Like the code below from https://discuss.leetcode.com/topic/6238/accepted-small-java-solution/2

public int compareVersion(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;
}






### 代码分析 由于没有给出 `AbsoluteMin` 类的具体代码,下面先给出一个可能的实现: ```java import java.util.Arrays; import java.util.List; public class AbsoluteMin { public static double findAbsoluteMin(List<Double> numbers) { if (numbers == null || numbers.isEmpty()) { throw new IllegalArgumentException("Input list cannot be null or empty"); } double minAbs = Math.abs(numbers.get(0)); double result = numbers.get(0); for (double num : numbers) { double absNum = Math.abs(num); if (absNum < minAbs) { minAbs = absNum; result = num; } } return result; } public static void main(String[] args) { List<Double> numbers = Arrays.asList(-3.0, 1.0, -0.5, 2.0); System.out.println(findAbsoluteMin(numbers)); } } ``` 这段代码的功能是在给定的 `List<Double>` 中找到绝对值最小的元素。首先检查输入列表是否为空或 `null`,若为空则抛出异常。然后初始化最小绝对值和结果为列表的第一个元素,遍历列表,比较每个元素的绝对值,若小于当前最小绝对值,则更新最小绝对值和结果。 ### 代码优化 上述代码已经比较简洁,但可以考虑使用 Java 8 的 Stream API 进行优化,使代码更具函数式风格: ```java import java.util.Arrays; import java.util.Comparator; import java.util.List; import java.util.Optional; public class AbsoluteMin { public static Optional<Double> findAbsoluteMin(List<Double> numbers) { if (numbers == null || numbers.isEmpty()) { return Optional.empty(); } return numbers.stream() .min(Comparator.comparingDouble(Math::abs)); } public static void main(String[] args) { List<Double> numbers = Arrays.asList(-3.0, 1.0, -0.5, 2.0); findAbsoluteMin(numbers).ifPresent(System.out::println); } } ``` 使用 Stream API 的 `min` 方法和 `Comparator.comparingDouble` 方法,代码更加简洁易读。同时,使用 `Optional` 来处理可能为空的列表,避免了抛出异常。 ### 单元测试 使用 JUnit 5 进行单元测试: ```java import org.junit.jupiter.api.Test; import java.util.Arrays; import java.util.List; import java.util.Optional; import static org.junit.jupiter.api.Assertions.assertEquals; public class AbsoluteMinTest { @Test public void testFindAbsoluteMin() { List<Double> numbers = Arrays.asList(-3.0, 1.0, -0.5, 2.0); Optional<Double> result = AbsoluteMin.findAbsoluteMin(numbers); assertEquals(-0.5, result.get()); } @Test public void testFindAbsoluteMinEmptyList() { List<Double> numbers = Arrays.asList(); Optional<Double> result = AbsoluteMin.findAbsoluteMin(numbers); assertEquals(Optional.empty(), result); } } ``` 测试用例覆盖了正常情况和空列表的情况。 ### 变异测试 变异测试是通过对代码进行微小的修改(即变异),然后运行测试用例,看测试用例是否能检测到这些变异。可以使用 PITest 工具进行变异测试。 1. **添加依赖**:在 `pom.xml` 中添加 PITest 插件: ```xml <build> <plugins> <plugin> <groupId>org.pitest</groupId> <artifactId>pitest-maven</artifactId> <version>1.9.2</version> <configuration> <targetClasses> <param>com.example.*</param> </targetClasses> <targetTests> <param>com.example.*Test</param> </targetTests> </configuration> </plugin> </plugins> </build> ``` 2. **运行变异测试**:在命令行中运行 `mvn org.pitest:pitest-maven:mutationCoverage`。 3. **分析结果**:PITest 会生成一个 HTML 报告,显示哪些变异被杀死,哪些变异存活。根据报告可以进一步优化测试用例。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值