Compare Version Numbers
本题收获:
1.字符串型数字转化为整型数字的方法:s[i] - '0',( 将字母转化为数字是[i]-'A' )
2.srt.at(),substr(),atoi()
3.字符串型数组的定义:string str[3]={“aaaa”,"bbbb","cccc"};差点跟python混淆了。C++中双引号和单引号的区别。
4.返回值类型要对应 return "0",
5.return 0;的位置
6.函数nextSubstr()的位置。
7.如果不是很清楚思路,通过调试来判断。
题目:
Compare two version numbers version1 and version2.
If version1 > version2 return 1, if version1 < version2 return -1, otherwise return 0.
You may assume that the version strings are non-empty and contain only digits and the .
character.
The .
character does not represent a decimal point and is used to separate number sequences.
For instance, 2.5
is not "two and a half" or "half way to version three", it is the fifth second-level revision of the second first-level revision.
Here is an example of version numbers ordering:
0.1 < 1.1 < 1.2 < 13.37
思路:
我的思路:将字符串转化为数字比较大小(字符串如何转化为数字不知道怎么操作)
leetcode/dicuss思路:将字符串转化为数字比较大小,有两种代码实现方式。
代码:
代码1:思路很易懂
1 int compareVersion(string version1, string version2) { 2 int i = 0; 3 int j = 0; 4 int n1 = version1.size(); 5 int n2 = version2.size(); 6 7 int num1 = 0; 8 int num2 = 0; 9 while(i<n1 || j<n2) //如果有有一个先结束,就结束循环 10 { 11 while(i<n1 && version1[i]!='.'){ //遇到'.'结束循环 12 num1 = num1*10+(version1[i]-'0'); 13 i++; 14 } 15 16 while(j<n2 && version2[j]!='.'){ 17 num2 = num2*10+(version2[j]-'0');; 18 j++; 19 } 20 21 if(num1>num2) return 1; 22 else if(num1 < num2) return -1; 23 24 num1 = 0; //遇到'.'后结束循环,将num置0,重新开始循环,先比较'.'之前,在比较'.'之后 25 num2 = 0; 26 i++; 27 j++; 28 } 29 30 return 0; 31 }
结合代码看思路:先比较'.'之前的,如果不相等则返回,如果相同继续以同样的方法判断'.'之后的。将对应的字符串型数字转化为整型数字:s[i] - '0'
由此题思考什么时候用while循环,什么时候用for循环,for循环在遍历,不需要条件终止时用较好,while循环在需要满足一定条件停止循环时用比较好。
代码2:涉及到的较多的库函数,但是很简洁。
1 class Solution { 2 public: 3 int compareVersion(string version1, string version2) { 4 for (; version1 != version2; version1 = nextSubstr(version1),version2 = nextSubstr(version2)) { //nextSubstr()是自己定义的函数,在下面 5 int gap = stoi(version1) - stoi(version2); //stoi()是库函数,将字符串转化为数字 6 if (gap != 0) { 7 return gap > 0 ? 1 : -1; 8 } 9 } 10 return 0; 11 } 12 13 string nextSubstr(string str) { 14 for (int i = 0; i < str.size(); i++) { 15 if (str.at(i) == '.') { //str.at(i) 等价于str[i] 16 return str.substr(i + 1); //substr()是字符函数,返回从i+1到字符串尾这段,即遇到'.'则 17 } 18 } 19 return "0"; //为什么返回的是字符串0???? 20 } 21 };
几个相关知识:
1.str.at() : at是STL中的,str.at()等价于str[i],作用相同。
2.substr() : substr(start, len)获得字符串s中 从第'start'位开始的长度为'len'的字符串 //默认时的长度为从开始位置到尾
substr(x)则是从x位开始到尾部
http://blog.csdn.net/no_retreats/article/details/7853066
3.stoi() : 将字符串转化为整型
代码2的调试过程:不太明白是怎么处理的所以记录调试过程
1 class MyClass { 2 public: 3 int compareVersion(string version1, string version2) { 4 for (version1, version2; version1 != version2; version1 = nextSubstr(version1), version2 = nextSubstr(version2)) { 5 cout << nextSubstr(version1) << endl; //23 234 6 cout << nextSubstr(version2) << endl; //56 678 7 int gap = stoi(version1) - stoi(version2); 8 cout << stoi(version1) << endl; 9 cout << stoi(version2) << endl; 10 if (gap != 0) { 11 return gap > 0 ? 1 : -1; 12 } 13 } 14 return 0; 15 } 16 17 string nextSubstr(string str) { 18 for (size_t i = 0; i < str.size(); i++) { 19 if (str.at(i) == '.') { 20 return str.substr(i + 1); 21 //cout << i + 1 << endl; //为什么在这里无法输出任何内容 22 } 23 //cout << i+1 << endl; 24 } 25 //cout << str.substr() << endl; 26 return "0"; 27 } 28 };
输入:1.23 3.45 输入:1.234 5.678
由此可以看出for循环 第一次循环'.'之前的内容,进行判断
第二次循环'.'之后的内容。进行判断
nextSubstr() 只对小数点之后的进行操作。
疑问??为什么在第26行返回的是"0",而不是数字0,应为条用时是version 而version为string,所以返回值必须为string,但是改为0,运行没有出错。
自己的测试代码:带有main函数,测试通过
1 #include "stdafx.h" 2 #include "string" 3 #include "iostream" 4 #include "vector" 5 using namespace std; 6 7 /* 8 class MyClass 9 { 10 public: 11 int compareVersion(string version1, string version2) 12 { 13 int i = 0, j = 0; 14 int num1 = 0, num2 = 0; 15 string nums1 = version1, nums2 = version2; 16 int n1 = nums1.size(), n2 = nums2.size(); 17 18 //while (i != 0 || j != 0) 19 while (i < n1 || j < n2) //第一次写错了(n1 != 0 || n2 != 0),在相等时无法输出0,因为n1,n2始终不等于0,故无法跳出循环 20 { 21 while (i < n1 && nums1[i] != '.') 22 { 23 num1 = num1 * 10 + nums1[i] - '0'; //将字符串转化为数字 - ‘0’ 24 i++; 25 } 26 27 while (j < n2 && nums2[j] != '.') 28 { 29 num2 = num2 * 10 + nums2[j] - '0'; 30 j++; 31 } 32 33 if (num1 > num2) return 1; 34 else if (num1 < num2) return -1; 35 36 num1 = 0; //如果两者'.'之前相等,则在遇见‘.’时将前面的全部转化为数字,比较,然后置0, 37 num2 = 0; 38 i++; 39 j++; 40 } 41 return 0; 42 } 43 }; 44 45 class MyClass { 46 public: 47 int compareVersion(string version1, string version2) { 48 for (version1, version2; version1 != version2; version1 = nextSubstr(version1), version2 = nextSubstr(version2)) { 49 //cout << nextSubstr(version1) << endl; 50 //cout << nextSubstr(version2) << endl; 51 int gap = stoi(version1) - stoi(version2); 52 //cout << stoi(version1) << endl; 53 //cout << stoi(version2) << endl; 54 if (gap != 0) { 55 return gap > 0 ? 1 : -1; 56 } 57 } 58 return 0; 59 } 60 61 string nextSubstr(string str) { 62 for (size_t i = 0; i < str.size(); i++) { 63 if (str.at(i) == '.') { 64 return str.substr(i + 1); 65 //cout << i + 1 << endl; //为什么在这里无法输出任何内容 66 } 67 //cout << i+1 << endl; 68 } 69 cout << str.substr() << endl; 70 return 0; //为什么返回的是“0”,而不是0 71 } 72 };*/ 73 74 class MyClass 75 { 76 public: 77 int compareVersion(string version1, string version2) 78 { 79 for (; version1 != version2; version1 = nextSubstr(version1), version2 = nextSubstr(version2)) 80 { 81 int gap = stoi(version1) - stoi(version2); 82 if (gap != 0) 83 { 84 return gap > 0 ? 1 : -1; 85 } 86 } 87 return 0; 88 } 89 string nextSubstr(string str) 90 { 91 for (size_t i = 0; i < str.size(); i++) 92 { 93 if (str[i] == '.') //为啥双引号不可以,单引号就可以,双引号是字符串“abcd”,单引号是字符'a' 94 return str.substr(i + 1); 95 } 96 return "0"; //返回类型为字符串型 97 } 98 }; 99 100 101 int _tmain(int argc, _TCHAR* argv[]) 102 { 103 while (true) 104 { 105 string str1, str2; 106 cin >> str1 >> str2; 107 MyClass solution; 108 int m; 109 m = solution.compareVersion(str1, str2); 110 cout << m << endl; 111 } 112 system("pause"); 113 return 0; 114 }
运行结果:
在写程序时,代码2出了几个错误:
1.L93 if (str[i] == '.')之前写成 if (str[i] == "."),一直错误提示: error C2446: “==”: 没有从“const char *”到“int”的转换.
错误原因是:双引号表示字符串,单引号表示字符,"." 为一个字符应该用单引号。
//"a"和'a'的区别,前者是字符串,后者是字符。
实际上,"a"在内存中一般占2个字节(不是说字符串长度,是占用内存。注意说是一般占2字节,有特殊情况),"a\0",以'\0'结尾。
而'a'是一个单字符。
当然字符串可以是"abcde"这样的,'abcde'这样就是错误的,
要注意你是意思是表示一个字符串还是一个字符,在决定用那种引号,在L96 return "0",返回的是"0"即为字符串0,应为nextSubstr()返回值类型是string
2.nextSubstr()函数的位置:nextSubstr()是一个独立的函数,它和compareVersion()是并列的,所以他的位置应该在compareVersion()外边。要清楚逻辑关系。
3.L87return 0; 的位置放在for循环外还是for循环内,放到for循环里面,结果出现如下错误,