【剑指offer】

剑指offer

面试题67:字符串转成整数

LeedCode:LCR 192. 把字符串转换成整数 (atoi)

测试atoi的功能和异常效果

cpp 复制代码
#include <iostream>
#include <cstdlib>

using namespace std;
//测试atoi的各项功能
//atoi:将数字字符串转换成int类型的整数
void test_atoi(const char *str,int expectd)
{
    int ret = atoi(str);
    if(ret == expectd)
    {
        cout<<"Test passed:atoi("<<str<<") = "<<ret<<endl;
    }
    else
    {
        cout<<"Test failed:atoi("<<str<<") = "<<ret<<endl;
    }
}

int main()
{
    //正数 负数 0
    test_atoi("123",123);
    test_atoi("-123",-123);
    test_atoi("0",0);

    //边界
    test_atoi("2147483647",2147483647); //INT_MAX
    test_atoi("-2147483648",-2147483648); //INT_MIN

    //非法输入
    test_atoi("",0);
    test_atoi("abc",0);
    test_atoi("123abc",123);
    test_atoi("abc123",0);

    //混合输入
    test_atoi("123 ",123);
    test_atoi(" 123",123);
    test_atoi(" -123",-123);
    test_atoi("-123 ",-123);

    //溢出 --有符号的上溢和下溢
    test_atoi("2147483656",21474836456);
    test_atoi("-2147483660",-2147483660);
    system("pause");
    return 0;
}

运行效果:

溢出这里atoi函数的操作和LeedCode上的要求不一样,LeedCode上简化了要求,如果上溢那就输出最大的正整数,如果下溢那就输出最小的负整数,具体的计算机溢出可以参照这篇文章:整数溢出详解

计算机中有 4 种溢出情况,以 32 位整数为例。

① 无符号上溢:无符号数 0xffffffff 加 1 会变成 0。

② 无符号下溢:无符号数 0 减去 1 会变成 0xffffffff,即-1。

③ 有符号上溢:有符号正数 0x7fffffff 加 1 变成 0x80000000, 即从 2147483647 变成了-2147483648。

④ 有符号下溢:有符号负数 0x80000000 减去 1 变成 0x7fffffff,即从-2147483648 变成了 2147483647。

因此实现把一个字符串转换成整数这个问题,需要考虑以下几点

  1. ""和" "和"0",三种情况输出的都是0,实际上是有区别的,按照书上说的,atoi是通过全局变量来区分的,如果是非法输入,返回0并把这个全局变量设为一个特殊标记,如果输入是"0",则返回0,不会设置全局变量,可以通过检查全局变量来查看是非法输入还是字符串"0"
  2. 正负号的判断,正负号占一个位置,并且正负号后应当紧接着就是数字,否则也是非法输入,相当于还是识别到了" "
  3. 溢出,int类型是4字节,取值范围是INT_MAX:2147483647 INT_MIN:-2147483648,这个宏定义在<limits.h>这个头文件里,可以包含然后直接用

这里提供了满足LeedCode上要求的代码,其实还有合法非法,以及溢出问题没有考虑到

下面是用C++实现的代码,

cpp 复制代码
class Solution {
public:
    int myAtoi(string str) {
        int res = 0,bndry = INT_MAX/10;
        int i = 0,sign = 1,len = str.size();
        if(len == 0) return 0; //空字符串
        while(str[i] == ' ')
        {
            if(++i == len) return 0; //空格后面全是空格
        }
        if(str[i] == '-') sign = -1; //负号
        if(str[i] == '+' || str[i] == '-') i++; //正号或负号
        for(int j = i;j<len;j++)
        {
            if(str[j] <'0' || str[j] >'9') break; //非数字字符
            //int类型:INT_MAX:2147483647 INT_MIN:-2147483648,尾数为7和8
            if(res > bndry || res == bndry && str[j] >'7')
            {
                return sign == 1 ? INT_MAX : INT_MIN; //溢出
            }
            res = res*10 + (str[j]-'0');
        }
        return sign*res; 
    }
};

用C实现的代码:

c 复制代码
int myAtoi(char* str) {
    assert(str); //空指针判断
    if (*str == '\0') //空串判断
        return 0;
    while (isspace(*str)) { //清除空格
        str++;
    }
    int sign = 1; //判断正负号
    if (*str == '-')
        sign = -1;
    if (*str == '+' || *str == '-')
        str++;
    int ret = 0, bon = INT_MAX / 10;
    while (*str != '\0') {
        if (*str < '0' || *str > '9')
            break;
        if (ret > bon || ret == bon && *str > '7') { //溢出判断
            return sign == 1 ? INT_MAX : INT_MIN;
        }
        ret = ret * 10 + (*str - '0');
        str++;
    }
    return sign * ret;
}

书上的代码:

面试题1:赋值运算符函数

cpp 复制代码
class CMyString
{
public:
	CMyString(char* pData = nullptr);
	CMyString(const CMyString& str);
	~CMyString(void);
private:
	char* m_pData;
};

面试题3:数组中重复的数字

LeedCode:442. 数组中重复的数据

相关推荐
C++ 老炮儿的技术栈34 分钟前
机器人的坐标,像 XYZ 的坐标值,是用单精度浮点还是用双精度浮点?
c语言·c++·人工智能·单片机·c
lhbweilai16 小时前
分析FreeRTOS内核对象API的源码实现(八)
c语言·开发语言·stm32·单片机
艾络迅Acceleronix17 小时前
环境监测终端:STM32+EG800Z AT+ 艾络迅平台实战|多传感器采集联动全流程
c语言·stm32·单片机·嵌入式硬件·物联网·1024程序员节
Zwawa17 小时前
一只按键不只“按下”:短按、长按和连按如何共存
c语言·单片机·嵌入式
wyhwust20 小时前
程序设计基础--C语言输入输出单元测试
c语言·开发语言
another heaven21 小时前
【C/C++ C++ 面向对象架构的五大特点与能力场景:封装、继承、多态、抽象与 RAII(含实战案例)】
c语言·c++·架构
晓蛋21 小时前
什么是C语言
c语言·跨平台·编程语言·高级语言·低级语言
知识分享小能手1 天前
C学习教程,从入门到精通,C语言单片机基础 — 完整知识点手册(19)
c语言·单片机·学习
another heaven1 天前
【C/C++ C++ 新特性中的那些内存优化的特性】
c语言·开发语言·c++
我叫洋洋1 天前
Allegro 画布“垃圾显示“清理指南:把板子调成干净工作台(实战总结)
c语言·c++·单片机·嵌入式硬件·eda·嘉立创