【Code Pratice】—— 《图解算法数据结构 ~ 第一章》
簡述
本文主要記錄了學習《圖解算法數據結構》一書中“數據結構”章節所做練習題的筆記,記錄其中的思路以及碰到的問題等。因為學習的這本書是在leetcode上的,但是感覺leetcode上只要求做函數本身的實現,而無法做到對總體的把控,總感覺缺少了一部分,所以所有的題目中,為了追求編程的完整性(頭文件、數據結構、函數定義、函數實現),練習的時候不局限于題目的要求,增加一點適應性,總的代碼文件會放到文章末尾以供后續回看。
文章目錄
- 1 | 劍指Offer05:替換空格
- 2 | 劍指Offer06:從尾到頭打印鏈表
- 3 | 劍指Offer09:用兩個棧實現隊列
- 4 | 劍指Offer20:表示數值的字符串
- 5 | 劍指Offer24:反轉鏈表
- 6 | 劍指Offer30:包含min函數的棧
- 7 | 劍指Offer35:復雜鏈表的復制
- 8 | 劍指Offer58:左旋轉字符串
- 9 | 劍指Offer59:滑動窗口的最大值
- 10 | 劍指Offer59:隊列的最大值
- 11 | 劍指Offer67:把字符串轉換成整數
1 | 劍指Offer05:替換空格
題目
將字符串A中的所有空格替換為%20
例子
A = We are family!
Result = We%20are%20family!
題目完整性
思路
只需要找到每一個空格的位置,并將空格替換成對應字符串即可,問題在于
怎么找到每一個空格的位置?
查找字符串中某字符位置都知道使用string.find()函數,但是這一系列的find()函數對于同一個字符串每次只能找第一個或最后一個出現該字符的位置。
既然每次只能找首位,那么就讓第一個空格變成第一個空格 --> 每找到一個空格,就把該空格前的字符串取出來,再刪除原字符串中的取出來的部分和這個空格,那么下一次查找時的空格就是第二個空格,依次循環查找
怎么替換空格?
上面每一次查找空格時,都保留了空格前的字符串,只需要在保存的字符串后都接上替換的字符即可
代碼
void ReplaceSpaces(string& i_cStr, const string& i_cCha) {if (("" == i_cStr) || ("" == i_cCha)){return;}string tmp = "";size_t pos = i_cStr.find(' ');while (pos != i_cStr.npos){tmp += i_cStr.substr(0, pos);tmp += i_cCha;i_cStr = i_cStr.substr(pos + 1, i_cStr.size());pos = i_cStr.find(' ');}tmp += i_cStr;i_cStr = tmp; }問題
在寫主體輸入部分的時候,輸入一行帶多個空格的字符串時碰到一點之前忽略的問題,getline() 和 cin.getline() 兩個函數的區別
- 如果定義了一個string類型的變量,那么只能使用getline(),不能使用cin.getline(),即使在參數調用的時候強轉成char*類型也沒用,具體待看源碼后記錄
- getline()默認等到輸入結束符后從緩存區中讀取完整的字符串,不需要指定輸入的長度,而cin.getline()需要指定輸入的長度,所以從實用性來說,getline()要比cin.getline()實用,而且cin.getline()可以進行緩存區溢出漏洞的利用
2 | 劍指Offer06:從尾到頭打印鏈表
題目
給定一個鏈表的頭節點,從尾到頭的輸出這個鏈表各節點的值
例子
head->1 2 3
輸出 3 2 1
思路
從尾到頭無非就是反轉的意思
代碼
vector<int> FromTail2HeadPrintLinkList(ListNode* head) {if (NULL == head){return;}ListNode* tmp = head;vector<int> res;while (tmp){res.push_back(tmp->val);tmp = tmp->next;}for (int i = 0, j = res.size() - 1; i < j; i++, j--){int temp = res[i];res[i] = res[j];res[j] = temp;}return res; }3 | 劍指Offer09:用兩個棧實現隊列
題目
用兩個棧實現一個隊列。隊列的聲明如下,請實現它的兩個函數 appendTail 和 deleteHead ,分別完成在隊列尾部插入整數和在隊列頭部刪除整數的功能。(若隊列中沒有元素,deleteHead 操作返回 -1 )
示例
輸入1:
[“CQueue”,“appendTail”,“deleteHead”,“deleteHead”,“deleteHead”]
[[],[3],[],[],[]]
輸出1:
[null,null,3,-1,-1]
輸入:
[“CQueue”,“deleteHead”,“appendTail”,“appendTail”,“deleteHead”,“deleteHead”]
[[],[],[5],[2],[],[]]
輸出:
[null,-1,null,null,5,2]
思路
棧的特性“先進后出”,隊列的特性“先進先出”
要用棧實現隊列就是構造出隊列的特性,而兩個棧可以模擬這個特性,思路如下
- 棧1:1 2 3 4 5; 棧2:
- 隊列尾部加入元素:
- 棧1入棧新元素 --> 棧1:1 2 3 4 5 6; 棧2:
- 此時執行隊列輸出時,將棧1的元素出棧并入棧到棧2,再將棧2輸出就得到了正常的隊列輸出
- 棧1:1 2 3 4 5; 棧2:
- 隊列頭部加入元素:
- 棧1出棧入棧2 --> 棧1: ; 棧2:5 4 3 2 1
- 棧1入棧新元素 --> 棧1:6; 棧2:5 4 3 2 1
- 棧2出棧入棧1 --> 棧1:6 1 2 3 4 5; 棧2:
- 此時執行隊列輸出時,將棧1的元素出棧并入棧到棧2,再將棧2輸出就得到了正常的隊列輸出
代碼
class QueBy2Stack {public:QueBy2Stack(){}void appendTail(int i_uNum);int deleteTail();void appendHead(int i_uNum);int deleteHead();void PrintQue();private:stack<int> s1;stack<int> s2; };void QueBy2Stack::appendHead(int i_uNum) {if (s2.empty()){while (!s1.empty()){s2.push(s1.top());s1.pop();}}s1.push(i_uNum);while (!s2.empty()){s1.push(s2.top());s2.pop();} }int QueBy2Stack::deleteHead() {if (s2.empty()){while (!s1.empty()){s2.push(s1.top());s1.pop();}}int result = s2.top();s2.pop();while (!s2.empty()){s1.push(s2.top());s2.pop();}return result; }void QueBy2Stack::appendTail(int i_uNum) {s1.push(i_uNum); }int QueBy2Stack::deleteTail() {int result = s1.top();s1.pop();return result; }void QueBy2Stack::PrintQue() {if (s2.empty()){while (!s1.empty()){s2.push(s1.top());s1.pop();}}while (!s2.empty()){cout << s2.top() << " ";s1.push(s2.top());s2.pop();} }void QueueBy2Stack() {int num = 0;int result = 0;cout << "**Func1: appendHead**" << endl;cout << "Please input num(stop when input -1): ";while (-1 != num){cin >> num;if (-1 != num){qbs.appendHead(num);}}cout << "now queque = [";qbs.PrintQue();cout << "]" << endl;cout << "**Func2: deleteHead**" << endl;result = qbs.deleteHead();cout << "delete num [" << result << "]]from head" << endl;cout << "now queque = [";qbs.PrintQue();cout << "]" << endl;cout << "**Func3: appendTail**" << endl;cout << "Please input num(stop when input -1): ";num = 0;while (-1 != num){cin >> num;if (-1 != num){qbs.appendTail(num);}}cout << "now queque = [";qbs.PrintQue();cout << "]" << endl;cout << "**Func4: deleteTail**" << endl;result = qbs.deleteTail();cout << "delete num [" << result << "]]from tail" << endl;cout << "now queque = [";qbs.PrintQue();cout << "]" << endl; }4 | 劍指Offer20:表示數值的字符串
題目
請實現一個函數用來判斷字符串是否表示數值(包括整數和小數)。
數值(按順序)可以分成以下幾個部分:
小數(按順序)可以分成以下幾個部分:
- 至少一位數字,后面跟著一個點 ‘.’
- 至少一位數字,后面跟著一個點 ‘.’ ,后面再跟著至少一位數字
- 一個點 ‘.’ ,后面跟著至少一位數字
整數(按順序)可以分成以下幾個部分:
部分數值列舉如下:
[“+100”, “5e2”, “-123”, “3.1416”, “-1E-16”, “0123”]
部分非數值列舉如下:
[“12e”, “1a3.14”, “1.2.3”, “±5”, “12e+5.4”]
提示:
1 <= s.length <= 20
s 僅含英文字母(大寫和小寫),數字(0-9),加號 ‘+’ ,減號 ‘-’ ,空格 ’ ’ 或者點 ‘.’
思路
按照給定的規則進行遍歷字符串,如果有不符合的項就判定為false,直到遍歷完整個字符串
題目規則:
+ & -
- 正負號最多只能出現兩次
- 正負號出現的位置只有兩種
- 字符串首:如+10 -123
- eE后:如1e+10 2e-3
小數點
- 小數點最多只能出現一次
- 小數點出現的位置必須在eE之前,如1.2e9 1.3e-10
- 小數點前或后可以沒有數字
e & E
- 指數符最多只能出現一次
- 指數符前必須為數字,后可接正負號,緊接著必須也是數字,如1e9 1e-9
字符串中除了數字以外,只能出現以上三種符號
代碼
bool StringByInter(const string& i_cStr) {int pos = 0; // 起點下標bool flg = false; // 記錄小數點是否出現while (' ' == i_cStr[pos]) // 讀 前綴空格{pos++;}if ('+' == i_cStr[pos] || '-' == i_cStr[pos]) // 讀 符號{pos++;}if ('.' == i_cStr[pos]) // 讀 小數點{flg = true;pos++;}if ('9' < i_cStr[pos] || '0' > i_cStr[pos]) // Ee不能在首位{return false;}while ('9' >= i_cStr[pos] && '0' <= i_cStr[pos]) // 讀 數字{pos++;}if ('.' == i_cStr[pos]) // 讀 小數點{if (flg){return false; // 若已存在直接返回 false}else{pos++;while ('9' >= i_cStr[pos] && '0' <= i_cStr[pos]){pos++;}}}if ('e' == i_cStr[pos] || 'E' == i_cStr[pos]) // Ee的尾巴{pos++;if ('+' == i_cStr[pos] || '-' == i_cStr[pos]) // 讀 符號{pos++;}if ('9' < i_cStr[pos] || '0' > i_cStr[pos]) // E 后面需要有數字{return false;}while ('9' >= i_cStr[pos] && '0' <= i_cStr[pos]){pos++;}}while (' ' == i_cStr[pos]) // 讀后綴空格{pos++;}if ('\0' == i_cStr[pos]){return true;}else{return false;} }5 | 劍指Offer24:反轉鏈表
題目
定義一個函數,輸入一個鏈表的頭節點,反轉該鏈表并輸出反轉后鏈表的頭節點。
思路
對于一個1 2 3 4 5的鏈表,反轉相當于把每一個節點的方向反向指向,如下
初始狀態
1(head) -> 2 -> 3 -> 4 -> 5 -> NULL
反轉狀態
NULL <- 1 <- 2 <- 3 <- 4 <- 5(head)
雙指針反轉指向
從頭結點開始,往后每個節點的指向都反轉一邊
定義兩個指針
- cur:指向當前需要反轉節點的指針
- pre:用于反轉方向的指針
反轉時定義臨時指針
- tmp:用于存放下一個要處理的節點
反轉的時候就是先保存下一個要處理的節點tmp,再把cur重新指向pre(這一步就已經實現了cur節點的反轉),處理下一個之前,先把兩指針后移到對應位置,cur移動到tmp位置,pre移動到cur的位置,圖解如下
代碼
ListNode* ReverseLink(ListNode* head) {ListNode* tmp;ListNode* pre = NULL;ListNode* cur = head;while (cur){tmp = cur->next;cur->next = pre;pre = cur;cur = tmp;}head = pre;return head; }6 | 劍指Offer30:包含min函數的棧
題目
定義棧的數據結構,請在該類型中實現一個能夠得到棧的最小元素的 min 函數在該棧中,調用 min、push 及 pop 的時間復雜度都是 O(1)。
思路
題目的關鍵在于三個操作的時間復雜度都是O(1),所以常規的遍歷棧找到最小值返回的方法肯定不行
時間復雜度為O(1),說明執行min()函數跟棧中元素的多少無關,這一點其實也給出了思路,怎么定義minStack的數據結構,以便執行min()時可以直接拿到最小值,不需要其他多余的操作?
數據結構定義
通過兩個棧定義這個minStack最小棧的數據結構
為什么不能定義一個變量來存放最小值,而定義一個棧呢?
如果使用一個變量來存放最小值的話,那么當彈出棧頂元素后,這個變量應該怎么隨著元素的彈出進行變值很難確定,變量只能存放當前的值,對于之前的最小值沒有記憶,所以這里采用兩個棧,而不是一個棧搭配一個變量定義數據結構
函數定義
如果要以上三個元素的時間復雜度都是O(1),那么
- Normal:正常的壓入彈出元素即可
- Mini:
- pop:正常彈出即可
- push:要判斷當前要壓入的元素是否比當前棧頂的元素小,如果是則壓入,否則再次壓入一個當前棧頂元素
為什么對于Mini這個棧的push操作需要這樣?
目的是為了保證兩個棧的元素同步性以及保證彈出壓入元素時,不影響之前的Mini最小值。因為對于Mini來說:如果不進行比較直接壓入的話,那么就失去了保存最小值的特性;如果比較后發現當前壓入的元素比當前棧頂元素大就不壓入元素的話,那么當彈出操作執行時,就會導致下一次的最小值錯亂。
比如依次壓入元素1 2 0 4 -1,那么Mini中的元素如下- 不比較壓入:Mini = 1 2 0 4 -1,執行三次pop后,變為Mini = 1 2,這時候執行min返回的值就不對(2 > 1)
- 比較不壓入:Mini = 1 0 -1,執行兩次pop后,變為Mini = 1,這時執行min返回的值也不對(1 > 0)
- 比較壓入:Mini = 1 1 0 0 -1,執行兩次pop后,變為Mini = 1 1 0,這時執行min返回的值是正確的(0 == 0),再執行一次pop,變為Mini = 1 1,這時執行min返回的值也是正確的(1 == 1)
代碼
class minStack {public:minStack(){}void minPush(int i_uNum);void minPop();int minTop();int minMin();private:stack<int> Normal;stack<int> Mini; };void minStack::minPush(int i_uNum) {Normal.push(i_uNum);if (!Mini.empty()){int num = i_uNum > Mini.top() ? Mini.top() : i_uNum;Mini.push(num);}else{Mini.push(i_uNum);} }void minStack::minPop() {if (!Normal.empty() && !Mini.empty()){Normal.pop();Mini.pop();}else{return;} }int minStack::minTop() {int res = -1;if (!Normal.empty()){res = Normal.top();}return res; }int minStack::minMin() {int res = -1;if (!Mini.empty()){res = Mini.top();}return res; }7 | 劍指Offer35:復雜鏈表的復制
題目
請實現 copyRandomList 函數,復制一個復雜鏈表。在復雜鏈表中,每個節點除了有一個 next 指針指向下一個節點,還有一個 random 指針指向鏈表中的任意節點或者 null。
思路
利用哈希表的查詢特點,考慮構建 原鏈表節點 和 新鏈表對應節點 的鍵值對映射關系,再遍歷構建新鏈表各節點的next和random引用指向即可,大概思路如下
代碼
class Node {public:int val;Node* next;Node* random;Node(int _val) {val = _val;next = NULL;random = NULL;} };Node* CopyRandomList(Node* head) {// 1. 如果鏈表為空返回空指針if (nullptr == head){return nullptr;}Node* cur = head;unordered_map<Node*, Node*> map;// 2. 復制各節點,并建立 “原節點 -> 新節點” 的 Map 映射while(nullptr != cur) {map[cur] = new Node(cur->val);cur = cur->next;}cur = head;// 3. 構建新鏈表的 next 和 random 指向while(nullptr != cur){map[cur]->next = map[cur->next];map[cur]->random = map[cur->random];cur = cur->next;}// 4. 返回新鏈表的頭節點return map[head]; }8 | 劍指Offer58:左旋轉字符串
題目
字符串的左旋轉操作是把字符串前面的若干個字符轉移到字符串的尾部。請定義一個函數實現字符串左旋轉操作的功能。比如,輸入字符串"abcdefg"和數字2,該函數將返回左旋轉兩位得到的結果"cdefgab"。
示例1
- 輸入: s = “abcdefg”, k = 2
- 輸出: “cdefgab”
示例2
- 輸入: s = “lrloseumgh”, k = 6
- 輸出: “umghlrlose”
思路
兩種方法:原地旋轉 和 子串拼接
原地旋轉
不需要額外申請空間,對原字符串進行旋轉操作得到最終結果,流程如下
子串拼接
申請額外的空間存放結果,結果由[0, n) 和 [n, len)的兩個子串拼接而得
代碼
string ReverseLeftStr1(string& i_cStr, int i_uNum) {if (0 == i_uNum){return i_cStr;}else if (0 > i_uNum){i_uNum = -i_uNum;i_uNum = i_cStr.length() - i_uNum;}reverse(0, i_uNum);reverse(i_uNum, i_cStr.length());reverse(0, i_cStr.length());return i_cStr; }string ReverseLeftStr2(const string& i_cStr, int i_uNum) {string res = i_cStr;if (0 == i_uNum){return res;}else if (0 < i_uNum){res = res.substr(i_uNum) + res.substr(0, i_uNum);}else{i_uNum = -i_uNum;int len = res.length();res = res.substr(len - i_uNum) + res.substr(0, len - i_uNum);}return res; }9 | 劍指Offer59:滑動窗口的最大值
題目
給定一個數組 nums 和滑動窗口的大小 k,請找出所有滑動窗口里的最大值。
示例
- 輸入: nums = [1,3,-1,-3,5,3,6,7], 和 k = 3
- 輸出: [3,3,5,5,6,7]
解釋:
思路
暴力計算
設數組 nums的長度為 n,則共有 (n?k+1)(n - k + 1)(n?k+1) 個窗口;
獲取每個窗口最大值需線性遍歷,時間復雜度為 O(k)O(k)O(k)。
根據以上分析,則暴力法 的時間復雜度為 O(nk)O(nk)O(nk) 。
雙端隊列
設數組 nums的長度為 n,則共有 (n?k+1)(n - k + 1)(n?k+1) 個窗口;
獲取每個窗口最大值需線性遍歷,時間復雜度為 O(1)O(1)O(1)。
根據以上分析,則暴力法 的時間復雜度為 O(n)O(n)O(n) 。
代碼
vector<int> MaxValSlidWin1(vector<int>& i_uArr, int i_uNum) {vector<int> res;if (0 == i_uArr.size() || 0 == i_uNum){return res;}int len = i_uArr.size();for (int i = 0; i <= len - i_uNum; i++){int max = i_uArr[i];for (int j = 1; j < i_uNum; j++){if (max < i_uArr[i + j]){max = i_uArr[i + j];}}res.push_back(max);}return res; }vector<int> MaxValSlidWin2(vector<int>& i_uArr, int i_uNum) {vector<int> res;deque<int> Maxi;if (0 == i_uArr.size() || 0 == i_uNum || 1 == i_uNum){return res;}Maxi.push_back(i_uArr[0]);for (int i = 1; i < i_uNum; i++){if (i_uArr[i] < Maxi.back()){Maxi.push_back(i_uArr[i]);}else{while (!Maxi.empty() && i_uArr[i] > Maxi.back()){Maxi.pop_back();}Maxi.push_back(i_uArr[i]);}}res.push_back(Maxi.front());for (int i = i_uNum; i < i_uArr.size(); i++){if (Maxi.size() == i_uNum) {Maxi.pop_front();}if (i_uArr[i] < Maxi.back()){Maxi.push_back(i_uArr[i]);}else{while (!Maxi.empty() && i_uArr[i] > Maxi.back()){Maxi.pop_back();}Maxi.push_back(i_uArr[i]);}res.push_back(Maxi.front());if (i_uArr[i - i_uNum + 1] == Maxi.front()){Maxi.pop_front();}}return res; }10 | 劍指Offer59:隊列的最大值
題目
請定義一個隊列并實現函數 max_value 得到隊列里的最大值,要求函數max_value、push_back 和 pop_front 的均攤時間復雜度都是O(1)。
若隊列為空,pop_front 和 max_value 需要返回 -1
示例1:
- 輸入:
- 輸出:
示例 2:
- 輸入:
- 輸出:
思路
題目跟劍指Offer30:包含min函數的最小棧類似,大概思路與其一致,區別在于:
一樣的,本題若只維護一個最大值變量,在元素入隊時更新此變量即可;但當最大值出隊后,并無法確定下一個 次最大值,因此不可行。所以也是通過構造數據結構來實現這個目的,與棧不同的是,這里數據結構申請的不是兩個隊列,而是一個單向隊列和一個雙向隊列,雙向隊列用來保存隊列中的最大值,雙向隊列隨著單向隊列的入隊和出隊操作實時更新,這樣隊列最大元素就始終對應雙向隊列的首元素。
初始化隊列 queue ,雙向隊列 deque ;
-
最大值 max_Value() :
- 當雙向隊列 deque 為空,則返回 -1?1 ;
- 否則,返回 deque 首元素;
-
入隊 push_Back() :
- 將元素 value 入隊 queue ;
- 將雙向隊列中隊尾 所有 小于 value 的元素彈出(以保持 deque 非單調遞減),并將元素 value 入隊 deque ;
-
出隊 pop_Front() :
- 若隊列 queue 為空,則直接返回 -1?1 ;
- 否則,將 queue 首元素出隊;
- 若 deque 首元素和 queue 首元素 相等 ,則將 deque 首元素出隊(以保持兩隊列 元素一致 );
例子
代碼
class maxQue {public:maxQue(){}int max_Value();int pop_Front();void push_Back(int i_uNum);private:queue<int> Normal;deque<int> Maxi; };int maxQue::max_Value() {return Maxi.empty() ? -1 : Maxi.front(); }int maxQue::pop_Front() {int res = -1;if (Normal.empty()){return res;}res = Normal.front();if (Maxi.front() == res){Maxi.pop_front();}Normal.pop();return res; }void maxQue::push_Back(int i_uNum) {Normal.push(i_uNum);while (!Maxi.empty() && Maxi.back() < i_uNum){Maxi.pop_back();}Maxi.push_back(i_uNum); }11 | 劍指Offer67:把字符串轉換成整數
題目
寫一個函數 StrToInt,實現把字符串轉換成整數這個功能。不能使用 atoi 或者其他類似的庫函數。
首先,該函數會根據需要丟棄無用的開頭空格字符,直到尋找到第一個非空格的字符為止。
當我們尋找到的第一個非空字符為正或者負號時,則將該符號與之后面盡可能多的連續數字組合起來,作為該整數的正負號;假如第一個非空字符是數字,則直接將其與之后連續的數字字符組合起來,形成整數。
該字符串除了有效的整數部分之后也可能會存在多余的字符,這些字符可以被忽略,它們對于函數不應該造成影響。
注意:假如該字符串中的第一個非空格字符不是一個有效整數字符、字符串為空或字符串僅包含空白字符時,則你的函數不需要進行轉換。
在任何情況下,若函數不能進行有效的轉換時,請返回 0。
說明:
假設我們的環境只能存儲 32 位大小的有符號整數,那么其數值范圍為 [?231, 231 ? 1]。如果數值超過這個范圍,請返回 INT_MAX (231 ? 1) 或 INT_MIN (?231) 。
示例 1:
- 輸入: “42”
- 輸出: 42
示例 2:
- 輸入: " -42"
- 輸出: -42
- 解釋: 第一個非空白字符為 ‘-’, 它是一個負號。我們盡可能將負號與后面所有連續出現的數字組合起來,最后得到-42 。
示例 3:
- 輸入: “4193 with words”
- 輸出: 4193
- 解釋: 轉換截止于數字 ‘3’ ,因為它的下一個字符不為數字。
示例 4:
- 輸入: “words and 987”
- 輸出: 0
- 解釋: 第一個非空字符是 ‘w’, 但它不是數字或正、負號。
因此無法執行有效的轉換。
示例 5:
- 輸入: “-91283472332”
- 輸出: -2147483648
- 解釋: 數字 “-91283472332” 超過 32 位有符號整數范圍。
因此返回 INT_MIN (?231) 。
思路
- true:遍歷并判斷后面是否為數字,直到遇到非數字字符停止,注意判斷數字的范圍(如果開頭的數字是0,那么要跳過前置0,因為0123實際數字是123)
- false:直接返回0
需要申請一個long long類型的結果變量,否則無法判斷,只會導致存放結果溢出,得到錯誤值
代碼
int Str2Int(const string& i_cStr) {long long res = 0;if ("" == i_cStr){return (int)res;}int iStart = 0;int iLen = i_cStr.length();while (' ' == i_cStr[iStart]){iStart++;}if ((iLen == iStart) || (!IsInter(i_cStr[iStart]) && ('+' != i_cStr[iStart]) && ('-' != i_cStr[iStart]))){return (int)res;}bool Minus = false;if ('-' == i_cStr[iStart]){iStart++;Minus = true;}else if ('+' == i_cStr[iStart]){iStart++;}while ('0' == i_cStr[iStart]){i++;}while (IsInter(i_cStr[iStart])){res *= 10;res += i_cStr[iStart] - '0';iStart++;}bool Big = false;if (res > INT32_MAX){res = INT32_MAX;Big = true;}if (Minus){res = -res;if (Big){res = INT32_MIN;}}return (int)res; }總結
以上是生活随笔為你收集整理的【Code Pratice】—— 《图解算法数据结构 ~ 第一章》的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 触屏版canvas画布实现touch坐标
- 下一篇: Barracuda WSF v4.x -