??上一篇已經足夠長了,再長也就有點不禮貌了,所以在這兒繼續來總結分享那個面試中遇到的題目,文中的問題和提供的答案或者代碼均代表個人的理解,如有不合理或者錯誤的地方,歡迎大家批評指正。
本文中題目列表
- 1. 編碼實現子串定位
- 2. 找出兩個字符串中最大公共子字符串
- 3. 在一個字符串中找到可能的最長的子字符串,且該字符串是由同一字符組成的
- 4. 把字符1串插入到字符串2中
- 5. 在字符串中找出連續最長的數字串,并把這個串的長度返回
- 6. 實現刪除字符串str1中含有的字符串str2
- 7. 寫一個函數,找出被重復的數字,時間復雜度必須為O(n)
- 8. 結構體、聯合體占用內存問題
- 9. 請寫出以下數據類型與零值比較的if語句。
- 10. 如下程序運行結果是什么。
- 11. 使用宏(或者函數)實現兩個數的交換的功能。
- 12. 已知類String的原型如下,編寫類String的構造函數,析構函數和賦值函數。
- 13. 不用庫函數,用C語言實現將一整型數字轉化為字符串。
- 14. 用指針的方法,將字符串“ABCD1234efgh”前后對調顯示。
- 15. 判斷一個字符串是不是回文。
1. 編碼實現子串定位
題目:編碼實現子串定位,函數原型為int FindSubStr(const char *MainStr, const char *SubStr)
。
查找子串的位置,其功能類似與函數
strstr()
,其函數原型是char *strstr(const char *haystack, const char *needle)
。本文中實現的方式比較簡單明了,注釋也很詳細。參考代碼如下。
int FindSubStr(const char *MainStr, const char *SubStr)
{/* 定義位置臨時變量,初始化為0,表示沒找到 */int t_index = 0;char *t_main_str = MainStr;char *t_sub_str = SubStr;/* NOTE 下面這部分代碼(SECTION -> !SECTION)為冗余設計,如果寫上了說明你對于一些異常情況有考慮并處理的能力,算是加分項 *//* SECTION 參數判斷 */if (NULL == t_main_str || NULL == t_sub_str) /* 空指針判斷 */return -1;int t_main_len = strlen(MainStr);int t_sub_len = strlen(SubStr);if (t_main_len == 0 || t_sub_len == 0) /* 字符串長度判斷,長度為0那就沒有繼續的必要了 */return -2;if (t_main_len < t_sub_len) /* 子串長度比主串長,玩呢 */return -3;/* !SECTION 參數判斷 *//* 結束查找的條件,主串到結尾 */while (*t_main_str != '\0'){/* 兩個字符串都沒有到結為,并且 子串與主串字符相同 */while (*t_main_str && *t_sub_str && *t_main_str == *t_sub_str){/* 記錄當前位置(PS:此位置不一定是最終結果,當做標識使用) */t_index = (t_main_str - MainStr) + 1;/* 移動指針 */t_main_str++;t_sub_str++;}/* 子串到結尾了(PS:說明前面的執行已經匹配到了完整的子串) */if (*t_sub_str == '\0'){/* 計算子串在主串中的開始的位置 */t_index = (t_main_str - MainStr) + 1 - (t_sub_str - SubStr);/* 跳出循環(PS:必須的)*/break;}/* 如果位置不為0,說明匹配到了一些字符,但是沒有匹配完整的子串 */if (t_index != 0){/* 指針要做后退一個,不然后面的++會導致跳過一個字符 */t_main_str--;/* 當然臨時的標識也要恢復 */t_index = 0;/* 重新開始匹配子串 */t_sub_str = SubStr;}/* 無條件移動主串的指針 */t_main_str++;}/* 返回位置 */return t_index;
}
2. 找出兩個字符串中最大公共子字符串
題目:找出兩個字符串中最大公共子字符串,如"abccade",“dgcadde"的最大子串為"cad”。
像這種只有題目要求和舉例說明的題目,編碼相對來說比較靈活了,但是在定義函數的時候相關參數和返回值都要盡量體現其合理性的,當然只要正當的考慮即可,下面給出兩種實現的方案供參考(方案二中使用
malloc()
函數,但是需要調用者去free,這是個坑)。
// 方案一:直接通過參數輸出公共子串在任一字符串中其實位置,通過返回值輸出公共子串的長度
int FindCommonStr(const char *str1, const char *str2, char **comm)
{char *t_str1 = (char *)str1;char *t_str2 = (char *)str2;char *t_common = NULL;int i = 0, j = 0, k = 0, t_len = 0, t_maxlen = 0;/* 參數判斷 */if (NULL == t_str1 || NULL == t_str2 || NULL == comm){return -1;}/* 字符串中一個字符一個字符判斷 */for (i = 0; t_str1[i] != '\0'; i++){/* 保存字符串1當前位置,后面需要自增 */k = i;/* 字符串中一個字符一個字符判斷 */for (j = 0; t_str2[j] != '\0'; j++){/* 相同字符的長度,每次重新開始 */t_len = 0;/* 兩個字符串的字符一致 */if (t_str1[k] == t_str2[j]){while ('\0' != t_str1[k] && /* 字符串沒到結束 */'\0' != t_str2[j] && /* 字符串沒到結束 */t_str1[k] == t_str2[j]) /* 字符一致 */{/* 指針后移 */k++;j++;/* 相同字符長度自增 */t_len++;}/* 本次相同字符長度大于記錄的最大長度 */if (t_len > t_maxlen){/* 更新最大長度 */t_maxlen = t_len;/* 記錄公共子串起始的位置 */t_common = &t_str1[i]; /* NOTE 如果取另一字符串的話則是:&t_str2[j - t_len]; */}}}}/* 輸出公共子串 */*comm = t_common;/* 返回公共子串的長度 */return t_maxlen;
}// 方案二:通過返回值返回最大公共子串,此方案最貼近題目要求,但是需要注意的是 malloc 調用
char *FindCommonStr(const char *str1, const char *str2)
{char *t_str1 = (char *)str1;char *t_str2 = (char *)str2;int i = 0