每日一题--比较版本号

文章目录

    • 题目描述
      • 比较规则
      • 9种情况分析
      • 解释
      • 示例
    • 解题思路
      • 实现步骤
      • 代码实现
        • 复杂版本
        • 简化版本
      • 代码讲解
      • 复杂度分析

题目描述

在许多软件开发和版本管理系统中,版本号用于表示不同的更新或发布。通常版本号由多个修订号组成,这些修订号通过 . 连接。现在给定两个版本号 version1version2,请比较它们的大小,返回以下结果:

  • version1 大于 version2,返回 1
  • version1 小于 version2,返回 -1
  • 若二者相等,返回 0

比较规则

  1. 忽略前导零:修订号中可能有前导零,比较时忽略前导零。例如 “0.1” 和 “0.01” 应视为相等。
  2. 缺失修订号视为零:如果某个版本号缺少某个修订号,则该修订号视为零。例如 “1.1” 和 “1.1.0” 应视为相等,且 “1.1” 小于 “1.1.1”。
  3. 版本号形式:版本号至少包含一个修订号,修订号可能包含多位数字。

9种情况分析

情况编号version1字符version2字符描述
1数字字符数字字符比较两个数字字符时,将它们转换成整数进行比较。例如 1235
2数字字符.当 version2 到达 .,则认为 version2 结束,此时 version1 中的数字与 0 比较。
3.数字字符当 version1 到达 .,则认为 version1 结束,此时 version2 中的数字与 0 比较。
4数字字符\0当 version2 到达结尾 \0,则认为 version2 结束,此时 version1 中的数字与 0 比较。
5..两个版本号中的点号 . 相遇时,比较当前修订号的整数值。如果相等,则继续比较下一个修订号。
6.\0当 version2 到达结尾 \0,则认为 version2 结束,此时 version1 继续按修订号比较。
7\0数字字符当 version1 到达结尾 \0,则认为 version1 结束,此时 version2 中的数字与 0 比较。
8\0.当 version1 到达结尾 \0,则认为 version1 结束,此时 version2 中的点号与 0 比较。
9\0\0当两个版本号都结束时,如果之前的所有修订号都相等,返回 0,表示两个版本号相等。

解释

  1. 数字字符比较:如果当前字符是数字,则可以通过将字符转换为整数进行比较。
  2. 点字符(.:在版本号中,点字符用于分隔不同的修订号。当遇到点字符时,意味着当前修订号的结束,我们需要比较当前的修订号。
  3. 空字符(\0:当版本号中的字符指针到达字符串结尾时,表示该版本号结束。在此情况下,缺失的修订号应视为 0,因此进行比较时需要考虑这一点。

示例

输入输出解释
“1.1”, “2.1”-11.1 小于 2.1,所以返回 -1
“1.1”, “1.01”01.11.01 相等,忽略前导零后结果相同。
“1.1”, “1.1.1”-11.1 相当于 1.1.0,所以返回 -1
“2.0.1”, “2”12.0.1 大于 2,所以返回 1
“0.226”, “0.36”1226 大于 36,所以返回 1

解题思路

我们可以使用双指针遍历两个版本号字符串,同时按修订号进行比较。具体步骤如下:

  1. 处理前导零:通过整数处理修订号时,自动去除前导零。
  2. 缺失修订号处理:如果某个版本号没有对应的修订号,我们将该修订号视为 0
  3. 逐个比较修订号:从左到右比较修订号,直到找到大小差异或者比较完所有修订号。

实现步骤

  1. 双指针遍历版本号:使用两个指针分别指向两个版本号字符串。
  2. 提取修订号:当遇到 . 或字符串结束时,表示一个修订号结束,比较两个修订号的大小。
  3. 忽略前导零:在提取修订号时直接计算其值。
  4. 处理缺失修订号:如果一个版本号比另一个短,则视缺失的修订号为 0

代码实现

复杂版本

其实就是按照9种情况讨论:

int compare(char* version1, char* version2 ) {int i = 0, j = 0;int temp1 = 0;int temp2 = 0;while (version1[i] != '\0' || version2[j] != '\0') {if ((version2[j] != '.'&& version2[j] != '\0')&& (version1[i] != '.'&&version1[i] != '\0')) {temp1 = temp1 * 10 + (version1[i] - '0');i++;temp2 = temp2 * 10 + (version2[j] - '0');j++;} else if ((version2[j] == '.' || version2[j] == '\0') && (version1[i] != '.'&&version1[i] != '\0')) {temp1 = temp1 * 10 + (version1[i] - '0');i++;} else if ((version1[i] == '.' || version1[i] == '\0') && (version2[j] != '.'&&version2[j] != '\0')) {temp2 = temp2 * 10 + (version2[j] - '0');j++; } else if ((version2[j] == '.' || version2[j] == '\0') && (version1[i] == '.' ||version1[i] == '\0')) {if (temp1 > temp2)return 1;if (temp1 < temp2)return -1;else {temp1 = 0;temp2 = 0;if (version1[i] == '.')i++;if (version2[j] == '.')j++;}} else break;}if (temp1 > temp2){return 1;}else if (temp1 < temp2)return -1;else  return 0;// write code here}
简化版本

其实完全没必要,明明很简单的思路,自己非搞得极度麻烦。

int compare(char* version1, char* version2) {int i = 0, j = 0;int temp1 = 0, temp2 = 0;while (version1[i] != '\0' || version2[j] != '\0') {// 处理版本号1和版本号2的当前修订号temp1 = 0; temp2 = 0;// 处理version1和version2的当前修订号while (version1[i] != '.' && version1[i] != '\0') {temp1 = temp1 * 10 + (version1[i] - '0');i++;}while (version2[j] != '.' && version2[j] != '\0') {temp2 = temp2 * 10 + (version2[j] - '0');j++;}// 比较修订号if (temp1 > temp2) {return 1; // version1 > version2}if (temp1 < temp2) {return -1; // version1 < version2}// 处理 '.' 位置if (version1[i] == '.') i++;if (version2[j] == '.') j++;}return 0; // version1 == version2
}

代码讲解

  1. 初始化:定义两个指针 ij,分别指向 version1version2 的当前位置。temp1temp2 用来存储当前修订号的值。

  2. 遍历修订号

    • 使用两个 while 循环分别提取两个版本号中的当前修订号。每次遇到 . 或字符串结束时,就结束当前修订号的提取。
  3. 比较修订号:当提取出两个修订号时,比较它们的大小:

    • 如果 temp1 > temp2,返回 1,表示 version1 更大。
    • 如果 temp1 < temp2,返回 -1,表示 version1 更小。
    • 如果相等,继续处理下一个修订号。
  4. 跳过点号:如果当前字符是 .,跳过它,继续处理下一个修订号。

  5. 结束条件:当遍历完两个版本号时,如果没有发现大小差异,说明它们相等,返回 0

复杂度分析

  • 时间复杂度:每次我们都在字符串上按修订号进行遍历,因此时间复杂度是 O(n),其中 n 是两个版本号字符串的最大长度。
  • 空间复杂度:只有几个整型变量用于存储索引和临时值,空间复杂度是 O(1)。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/67895.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Effective C++读书笔记——item23(用非成员,非友元函数取代成员函数)

一、主要观点&#xff1a; 在某些情况下&#xff0c;使用 non-member、non-friend 函数来替换 member 函数可以增强封装性和可扩展性&#xff0c;提供更好的软件设计。 二、详细解释&#xff1a; 封装性&#xff1a; 类成员函数的封装性考量&#xff1a;成员函数可以访问类的…

GBase8c aes_encrypt和aes_decrypt函数

在数据库中&#xff0c;aes_encrypt和aes_decrypt函数进行加解密时使用的块加密模式。 GBase8c 与 MySQL 的aes_encrypt和aes_decrypt函数区别&#xff1a; 1、GBase8c 中的初始化向量init_vector不能为空 2、MySQL的加密模块block_encryption_mode 为aes-128-ecb&#xff0c;…

重新理解tech lead角色

角色&#xff1a; tech leadleaderdeveloperarchitectleader:balance priorities,communicate clear goals,make apt decisions(做出适当的决定);supervise team members&#xff08;管理团队成员&#xff09;,delegate tasks, issue feedback, evaluate risks, and resolve co…

三相电变为家庭220V,市电火线和零线关系,为什么用三相电输送

参考&#xff1a; https://www.zhihu.com/question/30555841/answer/85723024 上面是电力系统的主要组成&#xff0c;发电站发电后升压传输&#xff0c;然后到各大城市再降压使用。 我们看到电塔上都是三根线&#xff0c;那么因为整个过程都是三相电。 为什么用三相电&#xff…

Java 和 JavaScript 的区别

尽管名字相似&#xff0c;JavaScript 的名字中带有 “Java”&#xff0c;确实让很多人误以为它与 Java 有紧密联系。但实际上&#xff0c;它们是完全不同的语言&#xff0c;只是在 JavaScript 的发展历史中与 Java 有一定的关联。 1. JavaScript 的诞生背景 时间点&#xff1…

linux数据压缩

在Linux系统中&#xff0c;有多种工具可用于文件的压缩和解压缩。虽然compress是一个早期Unix系统中的文件压缩工具&#xff0c;但在现代Linux系统中&#xff0c;更推荐使用如gzip、bzip2、xz等效率更高的工具。以下是基于您提供的信息整理的关于Linux文件压缩工具及其使用方法…

outlook附件限制最大5m如何解决

Outlook 附件大小限制为 5MB&#xff0c;通常由邮件服务器&#xff08;如 Exchange、Office 365、Gmail 等&#xff09;或本地 Outlook 配置决定。可以采取以下几种方法来解决该限制问题&#xff1a; 解决方案 1&#xff1a;调整服务器端限制&#xff08;管理员权限&#xff09…

Python----Python高级(正则表达式:语法规则,re库)

一、正则表达式 1.1、概念 正则表达式&#xff0c;又称规则表达式,&#xff08;Regular Expression&#xff0c;在代码中常简写为regex、 regexp或RE&#xff09;&#xff0c;是一种文本模式&#xff0c;包括普通字符&#xff08;例如&#xff0c;a 到 z 之间的字母&#xff0…

linux网络 | 传输层TCP | 认识tcp报头字段与分离

前言&#xff1a; 本节内容继续传输层的讲解&#xff0c; 本节讲解的是tcp协议。 tcp协议是我们日常中最常用的协议。就比如我们浏览网页&#xff0c;我们知道网页时http或者https协议。 其实http或者https底层就是用的tcp协议。tcp协议&#xff0c;全名又称为传输控制协议&…

Mysql触发器(学习自用)

一、介绍 二、触发器语法 注意&#xff1a;拿取新的数据时用new&#xff0c;旧数据用old。

ubuntu20使用apt安装mysql8

目录 ubuntu20使用apt安装mysql8报错列表参考链接首先删除旧mysql 一、下载配置mysql8库索引下载apt包解压包配置更新apt库索引 二、下载安装mysql8三、启动mysql服务配置开机自启动&#xff0c;忽略 本地登录远程登录查看mysql的所有用户使用客户端远程登陆如果报错完成 参考链…

昇腾AI产品

一.AI计算的基础知识 1.并行计算 指同时使用多种计算资源解决技术问题的过程&#xff0c;是提高计算机系统计算速度和数据处理能力的一种有效手段。它的基本思想是用多个处理器来共同求解同一个问题&#xff0c;即将被求解的问题分解成若干个部分&#xff0c;各部分均由一个独…

Unity编辑拓展显示自定义类型

配合自定义特性或着header可以添加注解 using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEditor; using System.Reflection; using System; using Unity.VisualScripting;#if UNITY_EDITORpublic class EditorRender {public sta…

微前端qiankun的部署

微前端qiankun的部署 本地开发主应用配置启动端口子应用配置启动端口测试环境部署:场景 1:主应用和微应用部署到同一个服务器(同一个 IP 和端口)微应用都放在在一个特殊名称(不会和微应用重名)的文件夹下主应用配置子应用配置配置nginx本地开发 主应用配置启动端口 打开…

Linux内核编程(二十一)USB驱动开发-键盘驱动

一、驱动类型 USB 驱动开发主要分为两种&#xff1a;主机侧的驱动程序和设备侧的驱动程序。一般我们编写的都是主机侧的USB驱动程序。 主机侧驱动程序用于控制插入到主机中的 USB 设备&#xff0c;而设备侧驱动程序则负责控制 USB 设备如何与主机通信。由于设备侧驱动程序通常与…

学习Hibernate的调优方案

Hibernate是一个非常流行的Java ORM&#xff08;对象关系映射&#xff09;框架&#xff0c;它可以帮助开发者更轻松地处理数据库操作。然而&#xff0c;如果不进行适当的性能调优&#xff0c;Hibernate可能会导致应用程序运行缓慢。本文将详细探讨Hibernate的调优方案&#xff…

总结 uniapp 上不适配iphone的:new Date 时间、border线条、渐变

1、border样式缺了一边 这是错误样式&#xff1a; 需要添加: border: 1rpx solid #57c7bb; transform: rotateZ(0deg);//加入此代码解决iphone 不适配问题2、时间出现NaN 原因是因为ios中使用new Date 的时候出了问题 解决方案: 1.调整时间格式:将时间格式从"yyyy-MM-d…

docker重启的方法

在 Docker 中,重启容器的方法有以下几种: 1. 使用 docker restart 命令 这是最常用的方法,可以通过容器名称或容器 ID 来重启容器。 docker restart <容器名称或容器ID> 例如: docker restart my_container 2. 使用 docker stop 和 docker start 命令 你也可以…

内网渗透测试工具及渗透测试安全审计方法总结

1. 内网安全检查/渗透介绍 1.1 攻击思路 有2种思路&#xff1a; 攻击外网服务器&#xff0c;获取外网服务器的权限&#xff0c;接着利用入侵成功的外网服务器作为跳板&#xff0c;攻击内网其他服务器&#xff0c;最后获得敏感数据&#xff0c;并将数据传递到攻击者&#xff0…

FPGA 开发工作需求明确:关键要点与实践方法

FPGA开发工作需求明确&#xff1a;关键要点与实践方法 一、需求明确的重要性 在FPGA开发领域&#xff0c;明确的需求是项目成功的基石。FPGA开发往往涉及复杂的硬件逻辑设计、高速信号处理以及与其他系统的协同工作。若需求不明确&#xff0c;可能导致开发过程中频繁变更设计…