剑指offer(C++)-JZ67:把字符串转换成整数atoi(算法-模拟)

news2024/11/26 4:29:21

作者:翟天保Steven
版权声明:著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处

题目描述:

写一个函数 StrToInt,实现把字符串转换成整数这个功能。不能使用 atoi 或者其他类似的库函数。传入的字符串可能有以下部分组成:

1.若干空格

2.(可选)一个符号字符('+' 或 '-')

3. 数字,字母,符号,空格组成的字符串表达式

4. 若干空格

转换算法如下:
1.去掉无用的前导空格
2.第一个非空字符为+或者-号时,作为该整数的正负号,如果没有符号,默认为正数
3.判断整数的有效部分:
3.1 确定符号位之后,与之后面尽可能多的连续数字组合起来成为有效整数数字,如果没有有效的整数部分,那么直接返回0
3.2 将字符串前面的整数部分取出,后面可能会存在存在多余的字符(字母,符号,空格等),这些字符可以被忽略,它们对于函数不应该造成影响
3.3  整数超过 32 位有符号整数范围 [−231,  231 − 1] ,需要截断这个整数,使其保持在这个范围内。具体来说,小于 −231的整数应该被调整为 −231 ,大于 231 − 1 的整数应该被调整为 231 − 1
4.去掉无用的后导空格

数据范围:

1.0 <=字符串长度<= 100

2.字符串由英文字母(大写和小写)、数字(0-9)、' '、'+'、'-' 和 '.' 组成

示例:

输入:

"4396 clearlove"

返回值:

4396

说明:

6后面的字符不属于有效的整数部分,去除,但是返回前面提取的有效部分

解题思路:

本题考察算法场景模拟。两种解题思路。

1)遍历法

       首先过滤前置空格;再判断正负号;之后判断连续数字,过程中注意正负极限判断;每找到一个新数字,就把之前的数字*10再累加上去,遍历完即可得到答案。复杂度O(n)。

2)状态机

       基于状态转移矩阵对字符串遍历过程的状态进行分析。

       状态分为4种,空格、符号、数字和无效,对应0123,根据题目条件设立矩阵如下:

\begin{bmatrix} 0 & 1 & 2 & 3\\ 3 & 3& 2 & 3\\ 3& 3& 2 & 3 \end{bmatrix}

  1. 起始状态为0,分析第一行:如果碰到空格,那下一个状态还是0;如果碰到符号,则状态转为1;如果碰到数字,则状态转为2;如果碰到无效字符,状态转为3。
  2. 假设状态转为1,分析第二行:如果碰到空格,即+空格,则无效,因此第二行第一列为3;如果又碰到符号,例如+-,也无效,所以第二行第二列为3;如果碰到数字,例如-3,则状态转为2;碰到无效字符状态转为3。
  3. 假设状态转为2,分析第三行:如果碰到空格,例如+8空格或者8空格,后续均无效,因此第三行第一列为3;如果碰到符号,例如+8+或者8+,后续也是均无效,因此第三行第二列为3;如果碰到数字,例如+89或者89,则后续是有效的,因此第三行第三列为2;无效字符同理无效。
  4. 当状态为2时,对数字进行累加和越界判断;当状态为3时,break退出即可。

       总的来说,状态机就是基于题目要求,将可能发生的情形和状态的转变,以矩阵形式表示,进而解题。复杂度O(n)。

测试代码:

1)排序法

#include <climits>
class Solution {
public:
    // 字符串转为整数
    int StrToInt(string s) {
        int sign = 1;
        int idx = 0;
        int size = int(s.size());
        // 前空格过滤,过滤完如果没有后续则退出
        while(idx < size){
            if(s[idx] == ' ')
                idx++;
            else
                break;
        }
        if(idx == size)
            return 0;
        // 判断符号,如果没有后续则退出
        if(s[idx] == '+')
            idx++;
        else if(s[idx] == '-'){
            idx++;
            sign = -1;
        }
        if(idx == size)
            return 0;
        // 继续遍历寻找目标数字
        int result = 0;
        while(idx < size){
            // 遇到非数字退出
            if(s[idx] < '0' || s[idx] > '9')
                break;
            // 判断极限
            if(result > INT_MAX / 10 || (result == INT_MAX / 10 && (s[idx] - '0') >= (INT_MAX % 10)))
                return INT_MAX;
            if(result < INT_MIN / 10 || (result == INT_MIN / 10 && (s[idx] - '0') >= -(INT_MIN % 10)))
                return INT_MIN;
            // 字符转为数字
            result = result * 10 + sign * (s[idx] - '0');
            idx++;
        }
        return result;
    }
};

2)状态机

class Solution {
public:
    // 字符串转为整数
    int StrToInt(string s) {
        // 状态转移矩阵
        vector<vector<int>> states = {
            {0,1,2,3},
            {3,3,2,3},
            {3,3,2,3},
        }; 
        // 定义
        long result = 0;
        long top = INT_MAX;  
        long bottom = INT_MIN;
        int sign = 1;
        int size = int(s.length());
        // 状态从0开始
        int state = 0; 
        for(int i = 0; i < size; ++i){
            // 空格
            if(s[i] == ' '){
                state = states[state][0]; 
            }
            // 正负号 
            else if(s[i] == '-' || s[i] == '+'){ 
                state = states[state][1]; 
                if(state == 1){
                    sign = (s[i] == '-') ? -1 : 1;
                }    
            }
            // 数字
            else if(s[i] >= '0' && s[i] <= '9'){
                state = states[state][2]; 
            }   
            // 非法字符
            else{
                state = states[state][3]; 
            }
            // 状态为2时,表明在连续数字状态,进行数字累加
            if(state == 2){
                // 数字相加
                result = result * 10 + s[i] - '0'; 
                // 越界处理
                result = (sign == 1) ? min(result, top) : min(result, -bottom); 
            }
            // 状态为3时,说明后续无效,退出即可
            else if(state == 3)
                break;
        }
        return (int)sign * result;
    }
};

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1020192.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

8种LED显示屏的安装方式

LED显示屏可以根据不同的应用需求和场地条件采用多种安装方式。 LED显示屏的常见安装方式包括&#xff1a; 立柱式&#xff1a;一般多用于大厦门口、大楼大厅等户外场所&#xff0c;可以抵抗风雨侵蚀&#xff0c;更适用于户外广告牌的使用。安装方式有单立柱安装、双立柱安装和…

联合matlab和Arcgis进行netcdf格式的雪覆盖数据的重新投影栅格

图片摘要 本专栏目的是将netcdf格式的雪覆盖数据进行重新投影&#xff0c;需要使用的工具包括matlab和Arcgis&#xff0c;下面进入正题。 1.数据的下载与读取---matlab 最近我需要读取北半球的冰雪覆盖数据&#xff0c;下载的是MODIS/Terra Snow Cover Monthly L3 Global 0.0…

CPU的各种存储器接口

设计电路时往往绕不开要做一些内存或者外存的接口设计&#xff0c;比如接SDRAM、NAND FLASH等等。这些无非是为了扩展原来CPU的内存或者外存资源&#xff0c;方便运行更大的系统。比较常见的就是一些Linux的核心板。I.MX6这个就是很多产品设计中使用的。 那么&#xff0c;在这些…

uniapp 可输入可选择的........框

安装 uniapp: uni-combox地址 vue页面 <uni-combox :border"false" input"selectname" focus"handleFocus" blur"handleBlur" :candidates"candidates" placeholder"请选择姓名" v-model"name"&g…

基于JAVA+SpringBoot+Vue+协同过滤算法+爬虫的前后端分离的租房系统

✌全网粉丝20W,csdn特邀作者、博客专家、CSDN新星计划导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取项目下载方式&#x1f345; 一、项目背景介绍&#xff1a; 随着城市化进程的加快…

Linux下运行Jmeter压测

一、在Linux服务器先安装SDK 1、先从官网下载jdk1.8.0_131.tar.gz&#xff0c;再从本地上传到Linux服务器 2、解压&#xff1a;tar -xzf jdk1.8.0_131.tar.gz&#xff0c;生成文件夹 jdk1.8.0_131 3、在/usr/目录下创建java文件夹&#xff0c;再将 jdk1.8.0_131目录移动到/u…

2023 Google 开发者大会:Web平台新动向

目录 前言一、Open in WordPress playground二、WebGPU三、新的核心 Web 指标INP四、Webview1、Custom Tabs2、JavaScriptEngine 五、Passkeys六、View Transitions API七、Google Chrome开发者工具优化1、覆盖HTTP的响应标头2、改变stack trance 八、Baseline总结 前言 在前不…

会员管理系统实战开发教程07-会员消费

上一篇我们讲解了会员的充值&#xff0c;会员消费和充值的逻辑类似&#xff0c;也是先记录消费金额&#xff0c;然后给会员卡余额减去消费金额&#xff0c;有个逻辑是如果余额不足需要提示信息。 1 创建消费记录表 我们先需要创建表来保存会员的消费记录信息&#xff0c;打开…

讲座2:神经编码与解码

视频来源&#xff1a; 1、面向类脑视觉的生物视觉编码机制和模型&#xff08;余肇飞&#xff09;https://www.bilibili.com/video/BV1rR4y1K7KW/?spm_id_from333.337.search-card.all.click&vd_source897075bbdd61e45006d749612d05a2ab 2、基于视觉编解码的深度学习类脑机…

7.idea 使用 docker 构建 spring boot 项目

本文目录 step 1&#xff1a;编写 Dockerfile 文件step 2&#xff1a;pom.xml 中添加如下配置step 3&#xff1a;maven仓库 setting.xml <servers> 模块下&#xff0c;添加访问自定义仓库的用户名&#xff0c;密码step 4&#xff1a;使用 maven命令开始 clean、packagest…

蓝牙核心规范(V5.4)10.1-BLE 入门笔记(1)

ble 规范 深入了解蓝牙LE需要熟悉相关的规格。蓝牙LE的架构、程序和协议由一项关键规范完全定义,称为蓝牙核心规范。产品如何使用蓝牙以实现互操作性由两种特殊类型称为配置文件和服务的规范集合所涵盖。图1展示了BLE规范类型及其相互关系。 1.1 蓝牙核心规范 蓝牙核心规范是…

测试行业面临的问题及RunnerGo在工具层面如何解决的

RunnerGo致力于打造成一款企业级全栈测试平台&#xff0c;旨在实现产品生命周期的闭环管理&#xff0c;帮助企业在整个产品生命周期中确保质量、降低风险&#xff0c;并提供卓越的用户体验。采用了较为宽松的Apache-2.0 license开源协议&#xff0c;方便志同道合的朋友一起为开…

VEX —— Noise and Randomness

目录 Noise generators Random number generators Noise generators 噪波生成函数&#xff0c;noise、wnoise、vnoise、onoise、snoise、anoise&#xff1b;每一个函数表示生成噪波的不同算法&#xff1b; 每个噪波相对成本&#xff1a; Perlin noise&#xff08;noise&#…

五十一.DQN原理和实战

值函数近似法 经典强化学习方法的共同点是它们的求解过程都要维持一个值函数表格&#xff0c;策略函数也可以通过一个表格来表示&#xff0c;所以也称这些方法为表格法。表格法要求状态空间和动作空间都是离散的&#xff0c;这类强化学习任务只占所有强化学习任务的很小一部分…

Spring Bean的生命周期和扩展点源码解读

目录 1 Bean的生命周期2 Bean的定义、注册及创建过程3 Bean的注入过程4 Bean的销毁过程5 Bean的生命周期 1 Bean的生命周期 在Spring框架中&#xff0c;Bean对象也有着它的生命周期&#xff0c;然而对于Bean对象的生命周期&#xff0c;我们并不是很清楚&#xff0c;因为Spring帮…

学习pytorch10 神经网络-最大池化的作用

神经网络-最大池化的作用 官方文档参数说明运算演示公式最大池化 代码code 1执行结果code2执行结果 B站小土堆学习视频 https://www.bilibili.com/video/BV1hE411t7RN?p19&spm_id_frompageDriver&vd_source9607a6d9d829b667f8f0ccaaaa142fcb 官方文档 https://pytorch…

UML基础与应用之面向对象

UML&#xff08;Unified Modeling Language&#xff09;是一种用于软件系统建模的标准化语言&#xff0c;它使用图形符号和文本来描述软件系统的结构、行为和交互。在面向对象编程中&#xff0c;UML被广泛应用于软件系统的设计和分析阶段。本文将总结UML基础与应用之面向对象的…

34.KMP算法,拒绝暴力美学

概述 今天我们来聊一聊字符串匹配的问题。 比如有字符串str1 “豫章故那&#xff0c;洪都新府。星分翼轸&#xff0c;地接衡庐。襟三江而带五湖&#xff0c;控蛮荆而引瓯越。”&#xff0c;字符串str2 “襟三江而带五湖”。 现要判断str1是否含有str2&#xff0c;如果有则的…

zabbix介绍及部署(五十一)

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 目录 一、zabbix的基本概述 二、zabbix的构成 1、Server 2、web页面 3、数据库 4、proxy 5、Agent 三、zabbix的监控对象 四、zabbix的常用术语 五、zabbix的工作流程 六、za…

区域气象-大气化学在线耦合模式(WRF/Chem)在大气环境领域实践技术应用

大气污染是工农业生产、生活、交通、城市化等方面人为活动的综合结果&#xff0c;同时气象因素是控制大气污染的关键自然因素。大气污染问题既是局部、当地的&#xff0c;也是区域的&#xff0c;甚至是全球的。本地的污染物排放除了对当地造成严重影响外&#xff0c;同时还会在…