原题描述:
比较两个版本号 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;
}
};