前一阵遇到一个如标题的算法题,是将原有字符串的某些片段替换成指定的新字符串片段,例如将源字符串: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 }