剑指Offer面试题:35.将字符串转换为数字
一、题目:将字符串转换为数字
题目:写一个函数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)代码覆盖率统计
正文到此结束