165. 比较版本号

题目

给你两个 版本号字符串 version1 和 version2 ,请你比较它们。版本号由被点 '.' 分开的修订号组成。修订号的值 是它 转换为整数 并忽略前导零。

比较版本号时,请按 从左到右的顺序 依次比较它们的修订号。如果其中一个版本字符串的修订号较少,则将缺失的修订号视为 0

返回规则如下:

  • 如果 _version1_ < _version2_ 返回 -1
  • 如果 _version1_ > _version2_ 返回 1
  • 除此之外返回 0

示例 1:

输入:version1 = "1.2", version2 = "1.10"

输出:-1

解释:

version1 的第二个修订号为 "2",version2 的第二个修订号为 "10":2 < 10,所以 version1 < version2。

示例 2:

输入:version1 = "1.01", version2 = "1.001"

输出:0

解释:

忽略前导零,"01" 和 "001" 都代表相同的整数 "1"。

示例 3:

输入:version1 = "1.0", version2 = "1.0.0.0"

输出:0

解释:

version1 有更少的修订号,每个缺失的修订号按 "0" 处理。

提示:

  • 1 <= version1.length, version2.length <= 500
  • version1 和 version2 仅包含数字和 '.'
  • version1 和 version2 都是 有效版本号
  • version1 和 version2 的所有修订号都可以存储在 32 位整数 中

解题思路

  • 分割与转换 (Parsing & Conversion)
    • 创建一个函数或使用现有的库(比如 istringstream)来分割 version1 字符串。分隔符是 .
    • 这将得到一个字符串数组,例如 "1.01.2" -> {"1", "01", "2"}
    • 遍历这个字符串数组,将每个元素(如 "01")转换为整数(如 1)。这里可以使用 std::stoi,它会自动处理前导零。
    • 最终,你会得到一个代表 version1 的整数数组(vector<int>),例如 {1, 1, 2}
    • 对 version2 执行完全相同的操作,得到它的整数数组。
  • 比较 (Comparison)
    • 现在拥有了两个整数数组,问题就退化成了我们刚刚解决的上一个问题
    • 可以直接调用我们之前写的 compareArrays 函数,或者重写那个逻辑:
      • 找到两个整数数组中的最大长度 max_len
      • 循环从 0 到 max_len - 1
      • 在循环中,获取两个数组当前索引的数字(如果索引越界,则视为 0)。
      • 比较这两个数字,一旦发现不相等,就立刻返回结果 (1 或 -1)。
    • 如果循环结束都没有返回,说明两个版本号相等,返回 0

具体代码

class Solution {
public:
    int compareVersion(string version1, string version2) {

        // --- 步骤1: 分割 version1 并转换为整数数组 ---
        vector<int> v1_tokens; // 用于存储 version1 的修订号
        vector<int> v2_tokens; // 用于存储 version2 的修订号
        string token;
        istringstream tokenStream(version1);
        // 使用 istringstream 和 getline 按 '.' 分割字符串
        while (getline(tokenStream, token, '.')) 
        {
            // 将分割出的字符串修订号转换为整数并存入 vector
            v1_tokens.push_back(stoi(token));
        }

        // --- 步骤2: 重用 stringstream 分割 version2 ---
        tokenStream.str(version2); // 将流的内容替换为 version2
        tokenStream.clear();       // 清除流的 EOF 等状态,以便进行新的读取
        while (getline(tokenStream, token, '.')) 
        {
            v2_tokens.push_back(stoi(token));
        }

        // --- 步骤3: 逐位比较修订号 ---
        // 获取两个版本中最长的修订号数量,作为比较的循环次数
        size_t max_num = max(v1_tokens.size(), v2_tokens.size());
        
        for(size_t i = 0; i < max_num; ++i)
        {
            // 获取 version1 的当前修订号,如果索引越界则视为 0
            int v1_num = (i < v1_tokens.size()) ? v1_tokens[i] : 0;

            // 获取 version2 的当前修订号,如果索引越界则视为 0
            int v2_num = (i < v2_tokens.size()) ? v2_tokens[i] : 0;

            // 比较当前位的修订号
            if (v1_num < v2_num)
                return -1; // version1 更小
            if (v1_num > v2_num)
                return 1;  // version1 更大
        }
        
        // 如果循环结束仍未返回,说明两个版本号在所有位上都相等
        return 0;
    }
};