Re: [問題] 版本字串比較

看板C_and_CPP (C/C++)作者 (非常念舊)時間4年前 (2020/10/02 22:55), 4年前編輯推噓0(0015)
留言15則, 1人參與, 4年前最新討論串2/2 (看更多)
※ 引述《gn00618777 (非常念舊)》之銘言: : release 版本格式: x.x.xxx : 目的 : 1.1.066 以及 1.1.66 ,程式都能認定同一版本。 : (為了防止開發者少填1個0,也就是1.1.66) : (少填1個0,會使strncmp 1.1.66 > 1.1.066) : (我是覺得公司都已經規定格式了,1.1.66不就不被允許嗎..) : (但上層總是想得比我們下面的人多拉~) : (所以我用了每小數點為分隔來求出每個數字來比) : (因此就能認定1.1.066 == 1.1.66了) : version 會存在既定 array(a_version, b_version)因為到時寫成 fun傳入來源指標 : 用strtok系列會改變來源位址,所以用a_version, b_version既定來存 : char a_version[] = "1.1.066"; : char b_version[] = "1.1.66"; : char *a_ptr = NULL; : char *b_ptr = NULL; : char *p,*q; : int i = 0; : int result = 0; : p = strtok_r(a_version, ".", &a_ptr); : q = strtok_r(b_version, ".", &b_ptr); : while(p != NULL && q != NULL) { : if((int)strtoul(p, NULL, 10) > (int)strtoul(q, NULL, 10)) { : result = 1; : break; : } else if((int)strtoul(p, NULL, 10) < (int)strtoul(q, NULL, 10)) { : result = -1; : break; : } else { : //do nothing : } : p = strtok_r(NULL, ".", &a_ptr); : q = strtok_r(NULL, ".", &b_ptr); : } : return result; //1: a>b -1:a<b 0: a==b 要用一個 buffer 的寫法我放棄了,我覺得應該還是要用兩個空間去存比較安全 原因 1 strtok 會改到source 原因 2 確保source 進來結尾能是'\0' 有些大大熱心提供的程式我還未消化完,非常感謝。我先提供自己的完整寫法 有些環境編譯器沒有 strtok_r的header,我是使用 https://reurl.cc/bRVono glibc porting過來的。 並搭配 leetcode 165 的測試題 https://reurl.cc/GrjYVG 驗證。另外我比leetcode 要求的回傳1 or -1 or 0 更進一步,我的不只回傳1 -1 0 ,可以回傳大多少小多少 有覺得更好的建議再多多指教囉。 int compare_version(const char *str1_version, const char *str2_version) { char a_version[FW_VERSION_SIZE+1] = {0}; char b_version[FW_VERSION_SIZE+1] = {0}; char *a_ptr = NULL, *b_ptr = NULL; char *p = NULL, *q = NULL; int a = 0, b = 0; if(str1_version) strncpy(a_version, str1_version, FW_VERSION_SIZE); if(str2_version) strncpy(b_version, str2_version, FW_VERSION_SIZE); p = strtok_r(a_version, ".", &a_ptr); q = strtok_r(b_version, ".", &b_ptr); if(p) a = atoi(p); if(q) b = atoi(q); if(a != b) return a - b; while(a == b) { p = strtok_r(NULL, ".", &a_ptr); q = strtok_r(NULL, ".", &b_ptr); p != NULL ? (a = atoi(p)) : (a = 0); q != NULL ? (b = atoi(q)) : (b = 0); if(p == NULL && q == NULL) return 0; } return a - b; } -- ※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 59.115.84.195 (臺灣) ※ 文章網址: https://www.ptt.cc/bbs/C_and_CPP/M.1601650535.A.301.html ※ 編輯: gn00618777 (59.115.84.195 臺灣), 10/02/2020 23:01:41

10/03 09:27, 4年前 , 1F
你的問題在於還沒分析完全就開始實作, C 語言有兩種
10/03 09:27, 1F

10/03 09:27, 4年前 , 2F
字串, 一種是 C-style string, 另一種不是用內容來分
10/03 09:27, 2F

10/03 09:28, 4年前 , 3F
而是用 (char*,size_t) 這樣的 tuple描述, 前者無法
10/03 09:28, 3F

10/03 09:29, 4年前 , 4F
支援巢狀結構, 所以 strtok() 是用截斷的方式, 但我
10/03 09:29, 4F

10/03 09:29, 4年前 , 5F
們如果要想拿出子字串, 應該使用後者, 這樣既不用改
10/03 09:29, 5F

10/03 09:30, 4年前 , 6F
變輸入字串內容, 也可以更有系統的描述問題, 在你的
10/03 09:30, 6F

10/03 09:31, 4年前 , 7F
問題裡, 目標即是將輸入的字串拆成 3 個 tuple, 分別
10/03 09:31, 7F

10/03 09:33, 4年前 , 8F
為: (a_version, 1), (a_version + 2, 1), (a_versio
10/03 09:33, 8F

10/03 09:34, 4年前 , 9F
n + 4, 3) 只要給你任何字串都有辦法拆出 n 個 tuple
10/03 09:34, 9F

10/03 09:34, 4年前 , 10F
那版本字串的比對問題就轉變為 n 的 tuple 各自去比
10/03 09:34, 10F

10/03 09:35, 4年前 , 11F
較的問題了, 比較 tuple 甚至也不一定要先轉成整數,
10/03 09:35, 11F

10/03 09:36, 4年前 , 12F
類似像 strncmp() 的邏輯甚至是反方向地比對字元也是
10/03 09:36, 12F

10/03 09:39, 4年前 , 13F
原文推文已經提供可以客製化的實作了, 核心概念就是
10/03 09:39, 13F

10/03 09:39, 4年前 , 14F
兩個 while 迴圈去萃取 tuple 而已, 剩下就看你理解
10/03 09:39, 14F

10/03 09:39, 4年前 , 15F
程度
10/03 09:39, 15F
文章代碼(AID): #1VTpzdC1 (C_and_CPP)
討論串 (同標題文章)
本文引述了以下文章的的內容:
完整討論串 (本文為第 2 之 2 篇):
文章代碼(AID): #1VTpzdC1 (C_and_CPP)