题目解析:
比较两个版本号,版本号由“.”分隔成多个修订号,比较思路应从左向右依次进行比较,只要任意一组修订号不相等则已经可以得到结果,若相等则需要比较下一组修订号,在大多数的比较中其实并不需要将完整的版本号进行比较。
- 难点1: 需要处理分隔符“.”将字符串形式的版本号进行分割,分割为多组修订号
- 难点2: 每组修订号需要进行格式转换由string转换为int类型才能方便比较
- 难点3: 修订号可能会出现若干前导0以及省略的情况
官方答案缺陷:
官方题解中方法1的指针方法需要对“.”和前导0进行处理,且也需要比较繁琐的数据类型转换,方法2用分割的思路用了istringstream,但先遍历了一遍流输入将每一个分割的修订号存入vector中,再将vector中的string修订号转为int按位进行比较相当于遍历了两遍,实际上可以在遍历的时候直接进行数据的转换和比较。
个人思路:
C++中的stringstream可以结合getline()实现对字符串进行指定分隔符的分割,而stringstream本身也可以方便的进行类型转换,不需要像官方答案中进行较为复杂的string到int的转换,结合stringstream中的eof()可以对该流是否到达末尾进行判断,因此可以利用该条件结合while执行循环,并在单次循环中直接进行修订号的比较而不用像官方答案中将整个流分割完输入到vector之后再进行比较,也节省了额外的存储空间,只需要两个int变量进行比较即可。
代码:
public:
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
* 比较版本号
* @param version1 string字符串
* @param version2 string字符串
* @return int整型
*/
int compare(string version1, string version2) {
//创建stringstream对象用来存储版本号
//sstmp为临时stringstream变量用来接收分割后的string并将其转换为int
stringstream ss1,ss2,sstmp;
//string类型的临时变量用来接收getline分割出来的string类型的修订号
string stmp;
//两个int型变量用来存储当前的修订号并进行比较
int v1,v2;
//将string类型的两个版本号输入到ss对象中
ss1<<version1;
ss2<<version2;
//eof()用来判断当前的stringstream是否输入到了末尾,若已达到末尾则返回true
//所以while循环条件为两个版本号任意1个尚未比较到末尾则继续进行比较
while(!ss1.eof()||!ss2.eof()){
//若其中的一个修订号中有省略情况则两个版本号长度不一样会出现其中一个填到达末尾的情况
//那么省略的部分直接补为0再与另一个修订号进行比较
if(ss1.eof()) v1=0;
else{
getline(ss1,stmp,'.'); //用getline()对“.”进行分割并将分割结果输入到stmp中
sstmp<<stmp;//以下两行为stringstream类型数据的数据转换
sstmp>>v1;//string类型的stmp通过<<输入到sstmp中再由>>直接转换为int类型的数据
//注意这步转换会自动忽略前导的0而转换为正常的int类型数据,0011会自动转为11
sstmp.clear();//stringstream复用需要clear}
if(ss2.eof()) v2=0;
else{
getline(ss2,stmp,'.');
sstmp<<stmp;
sstmp>>v2;
sstmp.clear();}
if(v1>v2) return 1;//若v1>v2则返回1
if(v1<v2) return -1; //若v1<v2则返回-1
}
return 0;//若两个版本号经过了上述循环仍未分出大小则返回0}
};