Re: [閒聊] 每日LeetCode

看板Marginalman作者 (愛麗絲)時間2年前 (2022/12/30 02:41), 編輯推噓5(500)
留言5則, 5人參與, 2年前最新討論串166/719 (看更多)
※ 引述《sustainer123 (caster)》之銘言: : C code : ------------------ : #include <string.h> : bool isSubsequence(char * s, char * t){ : int m=0; : int j=0; : for(int i=0; i<strlen(s); i++){ : for(; j<strlen(t); j++){ : if(s[i] == t[j]){ : j++; : m++; : break; : } : } : if(i == m){ : return 0; : } : } : return 1; : } : ------------------- 還有一個小問題是 for 迴圈裡的 strlen() 像是 for (int i = 0; i < strlen(s); i++) { /* ... */ } 每次跑到 i < strlen(s) 這裡時,會又要去執行一遍 strlen(s) 上面的程式最差情況可能會變成 O(n^2) 當然如果編譯器夠聰明的話有可能幫你優化掉 但最好還是不要冒這個風險,因為編譯器必須要知道 1. s 不會改指向其他人 2. s 指到的東西也不會改變 缺一個都不行。可以寫成 for (int i = 0, n = strlen(s); i < n; i++) { /* ... */ } 之類的,或是也可以用 C 字串以 '\0' 結尾的特性,改成 for (int i = 0; s[i]; i++) { /* ... */ } 至於上面的程式到底會不會重複跑 strlen() 首先要先知道 LeetCode 用的編譯版本和參數 可以在選語言那邊點左邊的 (i) 會跳出詳細的說明 https://i.imgur.com/9RDAnUl.png
可以看到是用 gcc 8.2 配上 gnu11 基本上就是 C11 加上一堆奇怪的 GNU extension 優化等級是 -O1 拿到 https://godbolt.org/ 之類的地方編譯 可以發現,外層的 strlen(s) 只會跑一次 但內層的 strlen(t) 會跑 strlen(s) 次 甚至我改 -O3 或改成 const char * const t 都沒用 看來 gcc 的這個優化只有對當下這層迴圈有效 但我用 clang 編就能只跑一次 = = 但因為 s 長度 <= 100 所以還是能在時間內就是了 -- ※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 140.112.16.175 (臺灣) ※ 文章網址: https://www.ptt.cc/bbs/Marginalman/M.1672339302.A.D6C.html

12/30 02:43, 2年前 , 1F
大師
12/30 02:43, 1F

12/30 03:25, 2年前 , 2F
大師
12/30 03:25, 2F

12/30 04:53, 2年前 , 3F
大師
12/30 04:53, 3F

12/30 11:00, 2年前 , 4F
感謝大師 以後都用終止符當條件
12/30 11:00, 4F

12/30 11:01, 2年前 , 5F
大師
12/30 11:01, 5F
文章代碼(AID): #1ZhTzcri (Marginalman)
討論串 (同標題文章)
文章代碼(AID): #1ZhTzcri (Marginalman)