每日一题--比较版本号

文章目录

    • 题目描述
      • 比较规则
      • 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,一经查实,立即删除!

相关文章

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

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

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;各部分均由一个独…

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…

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

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

Dockerfile另一种使用普通用户启动的方式

基础镜像的Dockerfile # 使用 Debian 11.9 的最小化版本作为基础镜像 FROM debian:11.11# 维护者信息 LABEL maintainer"caibingsen" # 复制自定义的 sources.list 文件&#xff08;如果有的话&#xff09; COPY sources.list /etc/apt/sources.list # 创建…

力扣707题——设计链表

#题目 从零开始设计链表&#xff0c;我们拆分成两次任务&#xff0c;今天先看1 ,2 ,4 #代码

leetcode刷题记录(七十二)——146. LRU 缓存

&#xff08;一&#xff09;问题描述 146. LRU 缓存 - 力扣&#xff08;LeetCode&#xff09;146. LRU 缓存 - 请你设计并实现一个满足 LRU (最近最少使用) 缓存 [https://baike.baidu.com/item/LRU] 约束的数据结构。实现 LRUCache 类&#xff1a; * LRUCache(int capacity)…

微信小程序:实现单选,多选,通过变量控制单选/多选

一、实现单选功能 微信小程序提供了 radio 组件来实现单选功能。radio 组件需要配合 radio-group 使用。 1. WXML 代码 <radio-group bindchange"onRadioChange"><label wx:for"{{items}}" wx:key"id"><radio value"{{it…

vue2使用flv.js在浏览器打开flv格式视频

组件地址&#xff1a;GitHub - bilibili/flv.js: HTML5 FLV Player flv.js 仅支持 H.264 和 AAC/MP3 编码的 FLV 文件。如果视频文件使用了其他编码格式就打不开。 flv.vue <template><div><el-dialog :visible.sync"innerVisibleFlv" :close-on-pre…

Spring 中的事件驱动模型

事件驱动的基本了解 事件模式也就是观察者模式&#xff0c;当一个对象改变的时候&#xff0c;所有依赖的对象都会收到一个通知。 Subject&#xff1a;抽象主题 Observer&#xff1a;具体主题 Concrete Subject&#xff1a;抽象观察者&#xff0c;在得到更新通知之后去更新自…

STM32补充——IAP

0 前置知识&#xff1a; FLASH相关内容&#xff1a;前往STM32补充——FLASH STM32三种烧录方式&#xff08;看看就行&#xff09;&#xff1a; 1.ISP&#xff1a;In System Programming&#xff08;在系统编程&#xff09; 执行芯片厂商的 Bootloader 程序进入 ISP 模式&…

k8s的CICD实施项目

环境需求&#xff1a; 目前领导需要做一个需求&#xff0c;临时把我从运维岗位&#xff0c;把我调度到到专家组让我主导cicd的项目实施 目前环境资源 k8s环境&#xff0c;28台服务器&#xff0c;上面是k8s集群&#xff0c;要实施一个测试环境的cicd以及一个生产环境的cicd gitl…

【线性代数】基础版本的高斯消元法

[精确算法] 高斯消元法求线性方程组 线性方程组 考虑线性方程组&#xff0c; 已知 A ∈ R n , n , b ∈ R n A\in \mathbb{R}^{n,n},b\in \mathbb{R}^n A∈Rn,n,b∈Rn&#xff0c; 求未知 x ∈ R n x\in \mathbb{R}^n x∈Rn A 1 , 1 x 1 A 1 , 2 x 2 ⋯ A 1 , n x n b 1…

AIGC视频生成模型:Runway的Gen系列模型

大家好&#xff0c;这里是好评笔记&#xff0c;公主号&#xff1a;Goodnote&#xff0c;专栏文章私信限时Free。本文详细介绍Runway开发的视频生成模型Gen系列&#xff0c;包括Gen-1、Gen-2和Gen3 Alpha等&#xff0c;这些模型每次发布都震惊AI圈&#xff0c;荣获多个视频生成的…