演算法:字串專項
阿新 • • 發佈:2022-04-12
1. 比較版本號
nowcoder 題目連結
【題目描述】
牛客專案釋出專案版本時會有版本號,比如1.02.11,2.14.4等等。現在給你2個版本號version1和version2,請你比較他們的大小。
版本號是由修訂號組成,修訂號與修訂號之間由一個"."連線。1個修訂號可能有多位數字組成,修訂號可能包含前導0,且是合法的。例如,1.02.11,0.1,0.2都是合法的版本號。
每個版本號至少包含1個修訂號。修訂號從左到右編號,下標從0開始,最左邊的修訂號下標為0,下一個修訂號下標為1,以此類推。比較規則:
- 比較版本號時,請按從左到右的順序依次比較它們的修訂號。比較修訂號時,只需比較忽略任何前導零後的整數值。比如"0.1"和"0.01"的版本號是相等的
- 如果版本號沒有指定某個下標處的修訂號,則該修訂號視為0。例如,"1.1"的版本號小於"1.1.1"。因為"1.1"的版本號相當於"1.1.0",第3位修訂號的下標為0,小於1
- version1 > version2 返回1,如果 version1 < version2 返回-1,不然返回0.
資料範圍:
1 <= version1.length, version2.length <= 1000
version1 和 version2 的修訂號不會超過int的表達範圍,即不超過 32 位整數 的範圍示例1
輸入:"1.1","2.1"
返回值:-1
說明:version1 中下標為 0 的修訂號是 "1",version2 中下標為 0 的修訂號是 "2" 。1 < 2,所以 version1 < version2,返回-1示例2
輸入:"1.1","1.01"
返回值:0
說明:version2忽略前導0,為"1.1",和version相同,返回0
【思路】
- 既然是比較兩個字串每個點之間的數字是否相同,就直接遍歷字串比較,但是數字前導零不便於我們比較,因為我們不知道後面會出現多少前導零,因此應該將點之間的部分轉化為數字再比較才方便。
- 可以先將 string 根據'.'劃分為 vector
,利用庫函式進行操作,也可以直接遍歷,擷取分隔符'.'之間的字串,轉換為 int,再比較。
#include <string> #include <vector> #include <algorithm> using namespace ::std; // using std::string; class Solution { public: /** * 程式碼中的類名、方法名、引數名已經指定,請勿修改,直接返回方法規定的值即可 * * 比較版本號 * @param version1 string字串 * @param version2 string字串 * @return int整型 */ int compare(string version1, string version2) { vector<string> version1Vec = split(version1, "."); vector<string> version2Vec = split(version2, "."); int len = min(version1Vec.size(), version2Vec.size()); int i = 0; for (; i < len; i++) { int version1Num = atoi(version1Vec[i].c_str()); int version2Num = atoi(version2Vec[i].c_str()); if (version1Num < version2Num) return -1; else if (version1Num > version2Num) return 1; } // version1 長 while (i < version1Vec.size()) { if (atoi(version1Vec[i++].c_str()) != 0) return 1; } while (i < version2Vec.size()) { if (atoi(version2Vec[i++].c_str()) != 0) return -1; } return 0; } /** * @param str 待分割的字串 * @param pattern 以 pattern 來分割字串 * @return 分割後的 vector<string> 容器 */ vector<string> split(const string &str, const string &pattern) { vector<string> result; if (str == "") return result; string strs = str + pattern; // 尾部加分割符,統一尾部操作 size_t pos = strs.find(pattern); // 第一個分隔符位置 while (pos != strs.npos) // find 函式若未在字串中找到,返回 npos { string temp = strs.substr(0, pos); // 分割 result.push_back(temp); strs = strs.substr(pos + 1, strs.size()); // 去掉已分割字元 pos = strs.find(pattern); } return result; } /** * 程式碼中的類名、方法名、引數名已經指定,請勿修改,直接返回方法規定的值即可 * * 比較版本號 * @param version1 string字串 * @param version2 string字串 * @return int整型 */ int compare2(string version1, string version2) { int ver1 = 0, ver2 = 0; int len1 = version1.size(), len2 = version2.size(); int i = 0, j = 0; while (i < len1 || j < len2) { while (i < len1 && version1[i] != '.') { ver1 = ver1 * 10 + (version1[i] - '0'); i++; } while (j < len2 && version2[j] != '.') { ver2 = ver2 * 10 + (version2[j] - '0'); j++; } if (ver1 < ver2) return -1; if (ver1 > ver2) return 1; i++; j++; ver1 = 0; ver2 = 0; } return 0; } };