前一陣遇到一個如標題的算法題,是將原有字符串的某些片段替換成指定的新字符串片段,例如將源字符串:abcdeabcdfbcdefg中的cde替換成12345,得到結果字符串:ab12345abcdfb12345fg,即:abcdeabcdfbcdefg -> ab12345abcdfb12345fg。
顯然不能用string.Replace方法,需要自定義一個方法 string Replace(string originalString, string strToBeReplaced, string strToReplace),下面是我的實現代碼,在半個小時內完成,通過了調試和常規數據的測試驗證,還算是及格吧。
1 public static string Replace(string originalString, string strToBeReplaced, string strToReplace) 2 { 3 string resultString = null; 4 char[] originalCharArray = originalString.ToCharArray(); 5 char[] strToBeCharArray = strToBeReplaced.ToCharArray(); 6 char[] strToCharArray = strToReplace.ToCharArray(); 7 List<Char> newCharList = new List<Char>(); 8 9 for (int i = 0; i < originalCharArray.Count(); i++) 10 { 11 if (originalCharArray[i] == strToBeCharArray[0]) 12 { 13 bool IsReplace = false; 14 for (int j = 0; j < strToBeCharArray.Count(); j++) 15 { 16 if (((i + j) < originalCharArray.Count()) 17 && (originalCharArray[i + j] == strToBeCharArray[j])) 18 { 19 IsReplace = true; 20 } 21 else 22 { 23 IsReplace = false; 24 break; 25 } 26 } 27 if (IsReplace) 28 { 29 i += strToBeCharArray.Count() - 1; 30 for (int k = 0; k < strToCharArray.Count(); k++) 31 { 32 newCharList.Add(strToCharArray[k]); 33 } 34 } 35 else 36 { 37 newCharList.Add(originalCharArray[i]); 38 } 39 } 40 else 41 { 42 newCharList.Add(originalCharArray[i]); 43 } 44 } 45 46 resultString = string.Join("", newCharList); 47 return resultString; 48 }
因為有時間限制的要求,我沒有添加注釋,不過代碼量不算多,邏輯也算簡單清晰,沒有注釋也OK啦,缺點是算法復雜度比較高。下面經過本人同意,轉載一下同事Hello Kitty同學對同一問題的實現代碼, 也換一種思路來解決同一個問題。代碼稍多,也添加了一些附加功能,各種注釋也很完備,當然也需要花費更多時間。歡迎博友們有興趣一同討論此話題,請自由留言加以評論! PS:就在剛才還發現了下面代碼的一個bug,就當是隱藏彩蛋了!
1 public class Replace 2 { 3 /// <summary> 4 /// Replace 方法 5 /// </summary> 6 /// <param name="source">原字符串</param> 7 /// <param name="find">需要查找的字符串</param> 8 /// <param name="replace">替換的字符串</param> 9 /// <returns>最終替換成功的字符串</returns> 10 public string Replace(string source, string find, string replace) 11 { 12 // 要查找的字符串大於原來字符串,則不處理,返回原來字符 13 if (find.Length > source.Length) 14 { 15 return source; 16 } 17 18 // 記錄找到多少次 19 int findCount = 0; 20 // 僅用於標記,輔助記錄多少次 21 bool flag = true; 22 // n:source字符串遍歷的數值;j:find字符串遍歷的數值 23 int n = 0, j = 0; 24 // s:查找到字符串的開始索引,e:查找到字符串的結束索引 25 int s = 0, e = 0; 26 27 while (true) 28 { 29 // 判斷字符是否相等 30 if (source[n] == find[j]) 31 { 32 // Source 序列+1 33 n++; 34 // 判斷是否為第一位相匹配 35 if (j == 0) 36 { 37 // 賦值給s,查找到頭的索引 38 s = n; 39 } 40 // 查找到後下一次比較find的下一位 41 j++; 42 // 標記暫時找到前面相同的字符 43 flag = true; 44 } 45 else 46 { 47 // 記錄不完全匹配 48 flag = false; 49 // find的索引歸零 50 j = 0; 51 // Source的索引繼續想加 52 n++; 53 } 54 55 // 已經查找完畢 56 if (j == find.Length) 57 { 58 // 完全匹配 59 if (flag) 60 { 61 // 查找的字符數量+1 62 findCount++; 63 } 64 // 記錄查找的數組結尾索引 65 e = n; 66 // source 索引繼續+1 67 n++; 68 // find的索引歸零 69 j = 0; 70 // 計算生成新字符串,之後繼續循環,直到替換所有字符串 71 source = GetNewString(source, find, replace, s, e); 72 } 73 // Source遍歷完畢,則退出循環 74 if (n >= source.Length) 75 { 76 break; 77 } 78 } 79 // 最終字符串 80 return source; 81 } 82 83 /// <summary> 84 /// 獲得新的字符串 85 /// </summary> 86 /// <param name="source">源字符串</param> 87 /// <param name="find">需要查找的字符</param> 88 /// <param name="replace">需要替換的字符</param> 89 /// <param name="startIndex">查找到的字符開始索引</param> 90 /// <param name="endIndex">查找到的字符結束索引</param> 91 /// <returns>返回替換後的字符串</returns> 92 public string GetNewString(string source, string find, string replace, int startIndex, int endIndex) 93 { 94 // 新字符串的長度 95 int newArrayLength = source.Length + endIndex - startIndex; 96 // 新字符數組 97 char[] newStringArray = new char[newArrayLength]; 98 // 將前半部分復制給新字符串 99 for (int i = 0; i < startIndex - 1; i++) 100 { 101 newStringArray[i] = source[i]; 102 } 103 // 當前臨時開始索引 104 int tempCurrentStartLength = startIndex - 1; 105 // 將需要替換的賦值給新的字符數組 106 for (int i = tempCurrentStartLength; i < tempCurrentStartLength + replace.Length; i++) 107 { 108 newStringArray[i] = replace[i - tempCurrentStartLength]; 109 } 110 // 將之後剩余的字符賦值給新的數組 111 for (int i = endIndex + 1; i < newArrayLength; i++) 112 { 113 newStringArray[i] = source[i - 1]; 114 } 115 // 返回轉換後的字符串 116 return string.Concat(newStringArray); 117 } 118 }