原题描述:
比较两个版本号 version1 和 version2。
如果 version1 > version2 返回 1,如果 version1 < version2 返回 -1, 除此之外返回 0。
你可以假设版本字符串非空,并且只包含数字和 . 字符。
. 字符不代表小数点,而是用于分隔数字序列。
例如,2.5 不是“两个半”,也不是“差一半到三”,而是第二版中的第五个小版本。
你可以假设版本号的每一级的默认修订版号为 0。例如,版本号 3.4 的第一级(大版本)和第二级(小版本)修订号分别为 3 和 4。其第三级和第四级修订号均为 0。
示例 1:
输入: version1 = “0.1”, version2 = “1.1”
输出: -1
示例 2:
输入: version1 = “1.0.1”, version2 = “1”
输出: 1
示例 3:
输入: version1 = “7.5.2.4”, version2 = “7.5.3”
输出: -1
示例 4:
输入:version1 = “1.01”, version2 = “1.001”
输出:0
解释:忽略前导零,“01” 和 “001” 表示相同的数字 “1”。
示例 5:
输入:version1 = “1.0”, version2 = “1.0.0”
输出:0
解释:version1 没有第三级修订号,这意味着它的第三级修订号默认为 “0”。
提示:
版本字符串由以点 (.) 分隔的数字字符串组成。这个数字字符串可能有前导零。
版本字符串不以点开始或结束,并且其中不会有两个连续的点。
思路:
- 字符串本身就有字典序,如果直接在字符串中把前导0去掉,则操作过程较为繁琐,还要判断两端的特殊情况。弃用,直接看2。
- 我想到用vector存储每位数字的方法,将2个string按照’.'分割,存放进vector中,然后通过给短的vector补0的方式,将2个vector的长度对齐。最后挨个比较2个vector的每个元素即可。
代码如下:
#include <iostream> #include <map> #include <string> using namespace std; void compensate0(vector<int>& vec, int diff) { for(int i = 0; i < diff; ++i) { vec.push_back(0); } } int compVector(vector<int> vec1, vector<int> vec2) { int diff = abs((int)(vec1.size() - vec2.size())); if(vec1.size() < vec2.size()) { compensate0(vec1, diff); } else { compensate0(vec2, diff); } for(int i = 0; i < vec1.size(); ++i) { if(vec1[i] > vec2[i]) { return 1; } else if(vec1[i] < vec2[i]) { return -1; } } return 0; } void getVector(string str, vector<int>& vec) { while(str.find('.') != str.npos) { int pos = str.find('.'); vec.push_back(stoi(str.substr(0, pos))); str = str.substr(pos + 1); } vec.push_back(stoi(str)); } int compareVersion(string version1, string version2) { vector<int> vec1; vector<int> vec2; getVector(version1, vec1); getVector(version2, vec2); return compVector(vec1, vec2); } static void AssertVersion(string v1, string v2, int res) { if(compareVersion(v1, v2) != res) { cout << "ERR! v1 is " << v1 << " , v2 is " << v2 << ", res is " << compareVersion(v1, v2) << endl; } else { cout << "OK" << endl; } } int main() { AssertVersion("0.1", "1.1", -1); AssertVersion("1.0.1", "1", 1); AssertVersion("7.5.2.4", "7.5.3", -1); AssertVersion("1.01", "1.001", 0); return 0; }
运行结果如下:
OK OK OK OK
其实此时就是LeetCode165。官方给的解答很简洁,但是不容易想到。我仿照官方自己写了下,如下:
class Solution { public: //当i或者j有一个超出范围后,while还在执行,++i或者++j其实已经没有意义了,但是不用管它,只要答案对就行了。 int compareVersion(string version1, string version2) { int i = 0, j = 0; while(i < version1.size() || j < version2.size()) { int sum1 = 0, sum2 = 0; for(; i < version1.size() && version1[i] != '.'; ++i) { sum1 = sum1 * 10 + (version1[i] - '0'); } ++i; //跳过'.' for(; j < version2.size() && version2[j] != '.'; ++j) { sum2 = sum2 * 10 + (version2[j] - '0'); } ++j; //跳过'.' cout << "sum1 is " << sum1 << ", sum2 is " << sum2 << endl; if(sum1 > sum2) { return 1; } else if(sum2 > sum1) { return -1; } } return 0; } };