一、題目:將字符串轉換為數字
題目:寫一個函數StrToInt,實現把字符串轉換成整數這個功能。當然,不能使用atoi或者其他類似的庫函數。
二、代碼實現
(1)考慮輸入的字符串是否是NULL、空字符串
(2)考慮輸入的字符串是否包含正負號或者是否是只包含正負號
(3)考慮輸入的字符串是否會發生上溢或下溢(正整數的最大值是0x7FFFFFFF,最小的負整數是0x80000000)
(4)考慮如何區分正常返回數字0和返回輸入是否合法的標識
綜上考慮,實現代碼如下,這里使用C#語言描述:
①定義一個ConvertResult的結構體,作為返回值使用
public struct ConvertResult { public ConvertState State; public int Number; } public enum ConvertState { // 輸入不合法 InValid = 0, // 輸入合法 Valid = 1 }
②定義方法主入口,在主入口中判斷輸入是否含有正負號並做對應處理
public static ConvertResult StrToInt(string str) { ConvertResult result = new ConvertResult(); result.State = ConvertState.InValid; result.Number = 0; if (!string.IsNullOrEmpty(str)) { bool minus = false; char[] strArray = str.ToCharArray(); int startIndex = 0; if (strArray[startIndex] == '+') { startIndex++; } else if (strArray[startIndex] == '-') { minus = true; startIndex++; } if (startIndex != strArray.Length) { StrToIntCore(strArray, startIndex, minus, ref result); } } return result; }
③定義核心方法StrToIntCore,將字符串轉換為數字並為ConvertResult實例賦值,在此方法中判斷是否發生上溢或下溢
private static void StrToIntCore(char[] strArray, int index, bool minus, ref ConvertResult result) { long number = 0; while (index < strArray.Length) { if (strArray[index] >= '0' && strArray[index] <= '9') { // 首先需要注意正負號 int flag = minus ? -1 : 1; number = number * 10 + flag * (strArray[index] - '0'); // 正整數的最大值是0x7FFFFFFF,最小的負整數是0x80000000 // 因此需要考慮整數是否發生上溢出或者下溢出 if ((flag == 1 && number > int.MaxValue) || (flag == -1 && number < int.MinValue)) { number = 0; break; } index++; } else { number = 0; break; } } if (index == strArray.Length) { result.State = ConvertState.Valid; result.Number = (int)number; } }
三、單元測試
3.1 測試用例
// 魯棒性測試:NULL指針 [TestMethod] public void StringToIntTest1() { ConvertResult actual = StringHelper.StrToInt(null); Assert.AreEqual(actual.State, ConvertState.InValid); } // 魯棒性測試:空字符串 [TestMethod] public void StringToIntTest2() { ConvertResult actual = StringHelper.StrToInt(""); Assert.AreEqual(actual.State, ConvertState.InValid); } // 功能測試:普通的數字字符串 [TestMethod] public void StringToIntTest3() { ConvertResult actual = StringHelper.StrToInt("123"); Assert.AreEqual(actual.State, ConvertState.Valid); Assert.AreEqual(actual.Number, 123); } // 功能測試:帶正負號的數字字符串 [TestMethod] public void StringToIntTest4() { ConvertResult actual = StringHelper.StrToInt("+123"); Assert.AreEqual(actual.State, ConvertState.Valid); Assert.AreEqual(actual.Number, 123); } // 功能測試:帶正負號的數字字符串 [TestMethod] public void StringToIntTest5() { ConvertResult actual = StringHelper.StrToInt("-123"); Assert.AreEqual(actual.State, ConvertState.Valid); Assert.AreEqual(actual.Number, -123); } // 功能測試:帶正負號的字符串0 [TestMethod] public void StringToIntTest6() { ConvertResult actual = StringHelper.StrToInt("+0"); Assert.AreEqual(actual.State, ConvertState.Valid); Assert.AreEqual(actual.Number, 0); } // 功能測試:帶正負號的字符串0 [TestMethod] public void StringToIntTest7() { ConvertResult actual = StringHelper.StrToInt("-0"); Assert.AreEqual(actual.State, ConvertState.Valid); Assert.AreEqual(actual.Number, 0); } // 特殊輸入測試:非數字字符串 [TestMethod] public void StringToIntTest8() { ConvertResult actual = StringHelper.StrToInt("1a33"); Assert.AreEqual(actual.State, ConvertState.InValid); Assert.AreEqual(actual.Number, 0); } // 特殊輸入測試:有效的最大正整數 0x7FFFFFFF [TestMethod] public void StringToIntTest9() { ConvertResult actual = StringHelper.StrToInt("+2147483647"); Assert.AreEqual(actual.State, ConvertState.Valid); Assert.AreEqual(actual.Number, 2147483647); } [TestMethod] public void StringToIntTest10() { ConvertResult actual = StringHelper.StrToInt("-2147483647"); Assert.AreEqual(actual.State, ConvertState.Valid); Assert.AreEqual(actual.Number, -2147483647); } [TestMethod] public void StringToIntTest11() { ConvertResult actual = StringHelper.StrToInt("+2147483648"); Assert.AreEqual(actual.State, ConvertState.InValid); Assert.AreEqual(actual.Number, 0); } // 特殊輸入測試:有效的最小負整數 0x80000000 [TestMethod] public void StringToIntTest12() { ConvertResult actual = StringHelper.StrToInt("-2147483648"); Assert.AreEqual(actual.State, ConvertState.Valid); Assert.AreEqual(actual.Number, -2147483648); } [TestMethod] public void StringToIntTest13() { ConvertResult actual = StringHelper.StrToInt("+2147483649"); Assert.AreEqual(actual.State, ConvertState.InValid); Assert.AreEqual(actual.Number, 0); } [TestMethod] public void StringToIntTest14() { ConvertResult actual = StringHelper.StrToInt("-2147483649"); Assert.AreEqual(actual.State, ConvertState.InValid); Assert.AreEqual(actual.Number, 0); } // 特殊輸入測試:只有一個正號 [TestMethod] public void StringToIntTest15() { ConvertResult actual = StringHelper.StrToInt("+"); Assert.AreEqual(actual.State, ConvertState.InValid); Assert.AreEqual(actual.Number, 0); } // 特殊輸入測試:只有一個負號 [TestMethod] public void StringToIntTest16() { ConvertResult actual = StringHelper.StrToInt("-"); Assert.AreEqual(actual.State, ConvertState.InValid); Assert.AreEqual(actual.Number, 0); }
3.2 測試結果
(1)測試用例通過情況
(2)代碼覆蓋率統計