华为OD机试 - 获取最大软件版本号(Java & JS & Python)

题目描述
Maven 版本号定义,<主版本>.<次版本>.<增量版本>-<里程碑版本>,举例3.1.4-beta

其中,主版本和次版本都是必须的,主版本,次版本,增量版本由多位数字组成,可能包含前导零,里程碑版本由字符串组成。
<主版本>.<次版本>.<增量版本>:基于数字比较;

里程碑版本:基于字符串比较,采用字典序;

比较版本号时,按从左到右的顺序依次比较。

基于数字比较, 只需比较忽略任何前导零后的整数值 。
输入2个版本号,输出最大版本号。

输入描述
输入2个版本号,换行分割,每个版本的最大长度小于50

输出描述
版本号相同时输出第一个输入版本号

用例

输入    2.5.1-C
1.4.2-D
输出    2.5.1-C
说明    无
输入    
1.05.1
1.5.01

输出    1.05.1
说明    版本号相同,输出第一个版本号
输入    1.5
1.5.0
输出    1.5.0
说明    主次相同,存在增量版本大于不存在
输入    1.5.1-A
1.5.1-a
输出    1.5.1-a
说明    里程碑版本号,基于字典序比较,a 大于 A

## 字符串操作解法

### Java算法源码

```
import java.util.Scanner;
 
public class Main {
  public static void main(String[] args) {
    Scanner sc = new Scanner(System.in);
 
    String s1 = sc.next();
    String s2 = sc.next();
 
    System.out.println(getResult(s1, s2));
  }
 
  public static String getResult(String s1, String s2) {
    String[] v1 = getVersion(s1);
    String[] v2 = getVersion(s2);
 
    /*
     * 主要版本比较
     * */
    int major1 = Integer.parseInt(v1[0]), major2 = Integer.parseInt(v2[0]);
    if (major1 > major2) return s1;
    else if (major1 < major2) return s2;
 
    /*
     * 次要版本比较
     * */
    int minor1 = Integer.parseInt(v1[1]), minor2 = Integer.parseInt(v2[1]);
    if (minor1 > minor2) return s1;
    else if (minor1 < minor2) return s2;
 
    /*
     * 增量版本比较
     * */
    String patch1 = v1[2], patch2 = v2[2];
    if (!"".equals(patch1) || !"".equals(patch2)) {
      if ("".equals(patch2)) return s1;
      else if ("".equals(patch1)) return s2; // 走到这步,s2的增量版本确定不是空串,则如果只有s1的增量版本是空串,则返回s2
 
      // 走到此步,说明s1,s2的增量版本都不是空串,此当成数字进行比较
      int v1_patch = Integer.parseInt(patch1);
      int v2_patch = Integer.parseInt(patch2);
      if (v1_patch > v2_patch) return s1;
      else if (v1_patch < v2_patch) return s2;
    }
 
    /*
     * 里程碑版本比较
     * */
    String mile1 = v1[3], mile2 = v2[3];
    // s1,s2的里程碑的空串判断,同增量版本
    if ("".equals(mile2)) {
      return s1;
    } else if ("".equals(mile1)) {
      return s2;
    }
 
    // 如果s1,s2的里程碑版本都不是空串,则按照字典序比较
    return mile1.compareTo(mile2) >= 0 ? s1 : s2;
  }
 
  public static String[] getVersion(String s) {
    String major = "";
    String minor = "";
    String patch = "";
    String mile = "";
 
    // 找到第一个“-”,先把里程碑解析出来,因为里程碑中可能含有"-"和".",因此必须先处理掉
    int i = s.indexOf("-");
 
    String major_minor_patch = "";
    if (i != -1) {
      mile = s.substring(i + 1);
      major_minor_patch = s.substring(0, i);
    } else {
      major_minor_patch = s;
    }
 
    // 之后再处理非里程碑部分
    String[] split = major_minor_patch.split("\\.");
    major = split[0];
    minor = split[1];
 
    if (split.length > 2) {
      patch = split[2];
    }
 
    return new String[] {major, minor, patch, mile};
  }
}
```

### JavaScript算法源码

```
/* JavaScript Node ACM模式 控制台输入获取 */
const readline = require("readline");
 
const rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout,
});
 
const lines = [];
rl.on("line", (line) => {
  lines.push(line);
 
  if (lines.length === 2) {
    console.log(getResult(lines[0], lines[1]));
    lines.length = 0;
  }
});
 
function getResult(s1, s2) {
  const [major1, minor1, patch1, mile1] = getVersion(s1);
  const [major2, minor2, patch2, mile2] = getVersion(s2);
 
  if (major1 > major2) return s1;
  else if (major1 < major2) return s2;
 
  if (minor1 > minor2) return s1;
  else if (minor1 < minor2) return s2;
 
  /**
   * 注意下面JS判断与空串是否相同时,必须要使用===,不能使用==,因为 0 == "" 为true
   */
 
  if (patch1 !== "" || patch2 !== "") {
    if (patch2 === "") {
      return s1;
    } else if (patch1 === "") {
      return s2;
    }
 
    // 走到此步,说明s1,s2的增量版本都不是空串,此当成数字进行比较
    if (patch1 > patch2) {
      return s1;
    } else if (patch1 < patch2) {
      return s2;
    }
  }
 
  // s1,s2的里程碑的空串判断,同增量版本
  if (mile2 === "") {
    return s1;
  } else if (mile1 === "") {
    return s2;
  }
 
  // 如果s1,s2的里程碑版本都不是空串,则按照字典序比较
  return mile1 >= mile2 ? s1 : s2;
}
 
function getVersion(s) {
  let major = "";
  let minor = "";
  let patch = "";
  let mile = "";
 
  // 找到第一个“-”,先把里程碑解析出来,因为里程碑中可能含有"-"和".",因此必须先处理掉
  const i = s.indexOf("-");
 
  let major_minor_pathc = "";
  if (i != -1) {
    mile = s.slice(i + 1);
    major_minor_pathc = s.slice(0, i);
  } else {
    major_minor_pathc = s;
  }
 
  // 之后再处理非里程碑部分
  const tmp = major_minor_pathc.split(".");
  major = Number(tmp[0]);
  minor = Number(tmp[1]);
 
  if (tmp.length > 2) {
    patch = Number(tmp[2]);
  }
 
  return [major, minor, patch, mile];
}
```

### Python算法源码

```
# 输入获取
s1 = input()
s2 = input()
 
 
# 解析版本号字符串s
def getVersion(s):
    patch = ""
    mile = ""
 
    i = s.find("-")
 
    # 找到第一个“-”,先把里程碑解析出来,因为里程碑中可能含有"-"和".",因此必须先处理掉
    major_minor_patch = ""
    if i != -1:
        mile = s[i + 1:]
        major_minor_patch = s[0:i]
    else:
        major_minor_patch = s
 
    # 之后再处理非里程碑部分
    tmp = major_minor_patch.split(".")
    major = int(tmp[0])
    minor = int(tmp[1])
 
    if len(tmp) > 2:
        patch = int(tmp[2])
 
    return major, minor, patch, mile
 
 
# 算法入口
def getResult(s1, s2):
    major1, minor1, patch1, mile1 = getVersion(s1)
    major2, minor2, patch2, mile2 = getVersion(s2)
 
    if major1 > major2:
        return s1
    elif major1 < major2:
        return s2
 
    if minor1 > minor2:
        return s1
    elif minor1 < minor2:
        return s2
 
    if patch1 != "" or patch2 != "":
        if patch2 == "":
            return s1
        elif patch1 == "":
            return s2
 
        # 走到此步,说明s1,s2的增量版本都不是空串,此当成数字进行比较
        if patch1 > patch2:
            return s1
        elif patch1 < patch2:
            return s2
 
    # s1,s2的里程碑的空串判断,同增量版本
    if mile2 == "":
        return s1
    elif mile1 == "":
        return s2
 
    # 如果s1,s2的里程碑版本都不是空串,则按照字典序比较
    return s1 if mile1 >= mile2 else s2
 
 
# 算法调用
print(getResult(s1, s2))
```

## 正则解法

### JavaScript算法源码

```
/* JavaScript Node ACM模式 控制台输入获取 */
const readline = require("readline");
 
const rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout,
});
 
const lines = [];
rl.on("line", (line) => {
  lines.push(line);
 
  if (lines.length === 2) {
    console.log(getResult(lines));
    lines.length = 0;
  }
});
 
function getResult(versions) {
  const reg = /^(\d+)(\.(\d+))(\.(\d+))?(\-.+)?$/;
  return versions.sort((v1, v2) => {
    let [_1, major1, _11, minor1, _111, patch1, mile1] = reg.exec(v1);
    let [_2, major2, _22, minor2, _222, patch2, mile2] = reg.exec(v2);
 
    major1 = Number(major1);
    major2 = Number(major2);
 
    if (major1 !== major2) return major2 - major1;
 
    minor1 = Number(minor1);
    minor2 = Number(minor2);
 
    if (minor1 !== minor2) return minor2 - minor1;
 
    if (patch1 !== undefined && patch2 !== undefined) {
      patch1 = Number(patch1);
      patch2 = Number(patch2);
      if (patch1 !== patch2) return patch2 - patch1;
    } else if (patch1 !== undefined && !patch2) {
      return -1;
    } else if (patch2 !== undefined && !patch1) {
      return 1;
    }
 
    if (mile1 && mile2) {
      return mile1 === mile2 ? 0 : mile2 > mile1 ? 1 : -1;
    } else if (mile1 && !mile2) {
      return -1;
    } else if (!mile1 && mile2) {
      return 1;
    } else {
      return 0;
    }
  })[0];
}
```

### Java算法源码

```
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
 
public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
 
        String str1 = sc.next();
        String str2 = sc.next();
 
        System.out.println(getResult(new String[]{str1, str2}));
    }
 
    public static String getResult(String[] versions) {
        String reg = "^(\\d+)(\\.(\\d+))(\\.(\\d+))?(\\-.+)?$";
        Pattern p = Pattern.compile(reg);
 
        Arrays.sort(versions, (v1, v2) -> {
            Matcher m1 = p.matcher(v1);
            Matcher m2 = p.matcher(v2);
 
            if (m1.find() && m2.find()) {
                Integer major1 = Integer.parseInt(m1.group(1));
                Integer major2 = Integer.parseInt(m2.group(1));
 
                if(major1 != major2) return major2 - major1;
 
                Integer minor1 = Integer.parseInt(m1.group(3));
                Integer minor2 = Integer.parseInt(m2.group(3));
 
                if(minor1 != minor2) return minor2 - minor1;
 
                String patch1 = m1.group(5);
                String patch2 = m2.group(5);
 
                if(patch1 != null && patch2 != null) {
                    int patch1_intVal = Integer.parseInt(patch1);
                    int patch2_intVal = Integer.parseInt(patch2);
                    if(patch1_intVal != patch2_intVal) {
                        return Integer.parseInt(patch2) - Integer.parseInt(patch1);
                    }
                } else if(patch1 != null) {
                    return -1;
                } else if(patch2 != null) {
                    return 1;
                }
 
 
                String mile1 = m1.group(6);
                String mile2 = m2.group(6);
 
                if(mile1 != null && mile2 != null) {
                    return mile2.compareTo(mile1);
                } else if(mile1 != null) {
                    return -1;
                } else if(mile2 != null) {
                    return 1;
                } else {
                    return 0;
                }
            }
 
            return 0;
        });
 
        return versions[0];
    }
 
}
```

### Python算法源码

```
import re
 
# 输入获取
v1 = input()
v2 = input()
 
 
# 算法入口
def getResult(v1, v2):
    pattern = r"^(\d+)(?:\.(\d+))(?:\.(\d+))?(?:\-(.+))?$"
 
    major1, minor1, patch1, mile1 = re.findall(pattern, v1)[0]
    major2, minor2, patch2, mile2 = re.findall(pattern, v2)[0]
 
    if major1 != major2:
        if int(major1) > int(major2):
            return v1
        else:
            return v2
 
    if int(minor1) != int(minor2):
        if int(minor1) > int(minor2):
            return v1
        else:
            return v2
 
    if patch1 != patch2:
        if patch1 != "" and patch2 != "":
            if int(patch1) > int(patch2):
                return v1
            elif int(patch1) < int(patch2):
                return v2
        elif patch1 != "" and patch2 == "":
            return v1
        elif patch1 == "" and patch2 != "":
            return v2
 
    if mile1 != mile2:
        if mile1 != "" and mile2 != "":
            if mile1 > mile2:
                return v1
            elif mile1 < mile2:
                return v2
        elif mile1 != "" and mile2 == "":
            return v1
        elif mile1 == "" and mile2 != "":
            return v2
 
    return v1
 
 
# 算法调用
print(getResult(v1, v2))
```

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值