一、题目:将字符串转换为数字

题目:写一个函数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 = ,
// 输入合法
Valid =
}

  ②定义方法主入口,在主入口中判断输入是否含有正负号并做对应处理

    public static ConvertResult StrToInt(string str)
{
ConvertResult result = new ConvertResult();
result.State = ConvertState.InValid;
result.Number = ; if (!string.IsNullOrEmpty(str))
{
bool minus = false;
char[] strArray = str.ToCharArray();
int startIndex = ;
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 = ; while (index < strArray.Length)
{
if (strArray[index] >= '' && strArray[index] <= '')
{
// 首先需要注意正负号
int flag = minus ? - : ;
number = number * + flag * (strArray[index] - '');
// 正整数的最大值是0x7FFFFFFF,最小的负整数是0x80000000
// 因此需要考虑整数是否发生上溢出或者下溢出
if ((flag == && number > int.MaxValue) ||
(flag == - && number < int.MinValue))
{
number = ;
break;
}
index++;
}
else
{
number = ;
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("");
Assert.AreEqual(actual.State, ConvertState.Valid);
Assert.AreEqual(actual.Number, );
} // 功能测试:带正负号的数字字符串
[TestMethod]
public void StringToIntTest4()
{
ConvertResult actual = StringHelper.StrToInt("+123");
Assert.AreEqual(actual.State, ConvertState.Valid);
Assert.AreEqual(actual.Number, );
} // 功能测试:带正负号的数字字符串
[TestMethod]
public void StringToIntTest5()
{
ConvertResult actual = StringHelper.StrToInt("-123");
Assert.AreEqual(actual.State, ConvertState.Valid);
Assert.AreEqual(actual.Number, -);
} // 功能测试:带正负号的字符串0
[TestMethod]
public void StringToIntTest6()
{
ConvertResult actual = StringHelper.StrToInt("+0");
Assert.AreEqual(actual.State, ConvertState.Valid);
Assert.AreEqual(actual.Number, );
} // 功能测试:带正负号的字符串0
[TestMethod]
public void StringToIntTest7()
{
ConvertResult actual = StringHelper.StrToInt("-0");
Assert.AreEqual(actual.State, ConvertState.Valid);
Assert.AreEqual(actual.Number, );
} // 特殊输入测试:非数字字符串
[TestMethod]
public void StringToIntTest8()
{
ConvertResult actual = StringHelper.StrToInt("1a33");
Assert.AreEqual(actual.State, ConvertState.InValid);
Assert.AreEqual(actual.Number, );
} // 特殊输入测试:有效的最大正整数 0x7FFFFFFF
[TestMethod]
public void StringToIntTest9()
{
ConvertResult actual = StringHelper.StrToInt("+2147483647");
Assert.AreEqual(actual.State, ConvertState.Valid);
Assert.AreEqual(actual.Number, );
} [TestMethod]
public void StringToIntTest10()
{
ConvertResult actual = StringHelper.StrToInt("-2147483647");
Assert.AreEqual(actual.State, ConvertState.Valid);
Assert.AreEqual(actual.Number, -);
} [TestMethod]
public void StringToIntTest11()
{
ConvertResult actual = StringHelper.StrToInt("+2147483648");
Assert.AreEqual(actual.State, ConvertState.InValid);
Assert.AreEqual(actual.Number, );
} // 特殊输入测试:有效的最小负整数 0x80000000
[TestMethod]
public void StringToIntTest12()
{
ConvertResult actual = StringHelper.StrToInt("-2147483648");
Assert.AreEqual(actual.State, ConvertState.Valid);
Assert.AreEqual(actual.Number, -);
} [TestMethod]
public void StringToIntTest13()
{
ConvertResult actual = StringHelper.StrToInt("+2147483649");
Assert.AreEqual(actual.State, ConvertState.InValid);
Assert.AreEqual(actual.Number, );
} [TestMethod]
public void StringToIntTest14()
{
ConvertResult actual = StringHelper.StrToInt("-2147483649");
Assert.AreEqual(actual.State, ConvertState.InValid);
Assert.AreEqual(actual.Number, );
} // 特殊输入测试:只有一个正号
[TestMethod]
public void StringToIntTest15()
{
ConvertResult actual = StringHelper.StrToInt("+");
Assert.AreEqual(actual.State, ConvertState.InValid);
Assert.AreEqual(actual.Number, );
} // 特殊输入测试:只有一个负号
[TestMethod]
public void StringToIntTest16()
{
ConvertResult actual = StringHelper.StrToInt("-");
Assert.AreEqual(actual.State, ConvertState.InValid);
Assert.AreEqual(actual.Number, );
}

3.2 测试结果

  (1)测试用例通过情况

  (2)代码覆盖率统计

作者:周旭龙

出处:http://edisonchou.cnblogs.com

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接。

剑指Offer面试题:35.将字符串转换为数字的更多相关文章

  1. 剑指offer 面试题35.复杂链表的复制

    时间O(N),空间O(N) /* struct RandomListNode { int label; struct RandomListNode *next, *random; RandomList ...

  2. C++版 - 剑指Offer 面试题35:第一个只出现一次的字符 解题报告(华为OJ034-找出字符串中第一个只出现一次的字符)

    面试题35:第一个只出现一次的字符 题目:在一个字符串中找到第一个只出现一次的字符.如输入abaccdeff,则输出b.(2006年google的一道笔试题.) 分析: 首先应向确认一下是ASCII字 ...

  3. 剑指Offer面试题:26.字符串的排列

    一.题目:字符串的排列 题目:输入一个字符串,打印出该字符串中字符的所有排列.例如输入字符串abc,则打印出由字符a.b.c所能排列出来的所有字符串abc.acb.bac.bca.cab和cba. 二 ...

  4. 【剑指Offer面试题】 九度OJ1510:替换空格

    c/c++ 中的字符串以"\0"作为结尾符.这样每一个字符串都有一个额外字符的开销. 以下代码将造成内存越界. char str[10]; strcpy(str, "01 ...

  5. 剑指 Offer 20. 表示数值的字符串 + 有限状态自动机

    剑指 Offer 20. 表示数值的字符串 Offer 20 常规解法: 题目解题思路:需要注意几种情况: 输入的字符串前后可能有任意多个空格,这是合法的. 正负号: (1)正负号只能出现一次. (2 ...

  6. 剑指Offer:面试题15——链表中倒数第k个结点(java实现)

    问题描述 输入一个链表,输出该链表中倒数第k个结点.(尾结点是倒数第一个) 结点定义如下: public class ListNode { int val; ListNode next = null; ...

  7. 剑指offer面试题3 二维数组中的查找(c)

    剑指offer面试题三:

  8. 剑指Offer——笔试题+知识点总结

    剑指Offer--笔试题+知识点总结 情景回顾 时间:2016.9.23 12:00-14:00 19:00-21:00 地点:山东省网络环境智能计算技术重点实验室 事件:笔试 注意事项:要有大局观, ...

  9. C++版 - 剑指offer之面试题37:两个链表的第一个公共结点[LeetCode 160] 解题报告

    剑指offer之面试题37 两个链表的第一个公共结点 提交网址: http://www.nowcoder.com/practice/6ab1d9a29e88450685099d45c9e31e46?t ...

  10. C++版 - 剑指offer 面试题23:从上往下打印二叉树(二叉树的层次遍历BFS) 题解

    剑指offer  面试题23:从上往下打印二叉树 参与人数:4853  时间限制:1秒  空间限制:32768K 提交网址: http://www.nowcoder.com/practice/7fe2 ...

随机推荐

  1. Orchard教程索引页

    Orchard官方教程(译)索引 链接标注 原文 则表示未译,其他带有中文标题的表示译文内容. 入门 安装Orchard--Installing Orchard 通过zip包手动安装Orchard-- ...

  2. 为什么说在使用多条件判断时switch case语句比if语句效率高?

    在学习JavaScript中的if控制语句和switch控制语句的时候,提到了使用多条件判断时switch case语句比if语句效率高,但是身为小白的我并没有在代码中看出有什么不同.去度娘找了半个小 ...

  3. activemq 控制面板里的 Number Of Pending Messages、 Messages Enqueued、Messages Dequeued含义

    Number Of Consumers  消费者 这个是消费者端的消费者数量 Number Of Pending Messages 等待消费的消息 这个是当前未出队列的数量.可以理解为总接收数-总出队 ...

  4. github push时,要求密码的问题

    整几次才搞的有点明白: 1 clone 项目 用 SSH: 在github 上如下图 2 C:\Users\<用户名> 下如果有 "_netrc" 文件: 如果含有 如 ...

  5. Linux Shell 数组

    shell 数组一般都是一维数组. 1. 数组的声明 declare -a arr 该命令将声明一个数组arr,实际上不声明也可以直接定义数组. 2. 数组的初始化 arr=(1 2 3):该命令定义 ...

  6. iTunes使用总结

    UDID查询 将设备连接至电脑,打开iTunes至设备摘要页面,鼠标点击"序列号"区域切换显示UDID

  7. OpenCV(三) 之 基本数据结构 CvMat和 IplImage

    OpenCV(三) 之 基本数据结构 CvMat和 IplImage CvMat IplImage OpenCv中基本的数据类型 类型 参数 表示 CvPoint int x,y 像素点 CvPoin ...

  8. Jungle Roads[HDU1301]

    Jungle Roads Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Tota ...

  9. XCode6.3上使用opencv教程(MacOSX 10.10)

    OpenCV 是一个基于(开源)发行的跨平台计算机视觉库,可以运行在Linux.Windows和Mac OS操作系统上.它轻量级而且高效——由一系列 C 函数和少量 C++ 类构成,同时提供了Pyth ...

  10. JS操作Json

    因为我水啊 所以我就要手打一下 熟悉一下 ===== JSON 全称 JavaScript Object Notation(标记) 一种轻量级的数据交互格式,采用完全独立于语言的文本格式 同事JSON ...