【LeetCode】8 字符串转换整数 (atoi)(字符串)

本文介绍如何实现一个将字符串转换为整数的atoi函数。重点包括处理字符串中的空格、正负号、非数字字符及整数溢出等问题,并提供两种不同的C++实现方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目链接:https://leetcode-cn.com/problems/string-to-integer-atoi/

题目描述

请你来实现一个 atoi 函数,使其能将字符串转换成整数。

首先,该函数会根据需要丢弃无用的开头空格字符,直到寻找到第一个非空格的字符为止。

当我们寻找到的第一个非空字符为正或者负号时,则将该符号与之后面尽可能多的连续数字组合起来,作为该整数的正负号;假如第一个非空字符是数字,则直接将其与之后连续的数字字符组合起来,形成整数。

该字符串除了有效的整数部分之后也可能会存在多余的字符,这些字符可以被忽略,它们对于函数不应该造成影响。

注意:假如该字符串中的第一个非空格字符不是一个有效整数字符、字符串为空或字符串仅包含空白字符时,则你的函数不需要进行转换。

在任何情况下,若函数不能进行有效的转换时,请返回 0。

说明:

假设我们的环境只能存储 32 位大小的有符号整数,那么其数值范围为 [−231, 231 − 1]。如果数值超过这个范围,qing返回 INT_MAX (231 − 1) 或 INT_MIN (−231) 。

示例 1:

输入: "42"
输出: 42

示例 2:

输入: "   -42"
输出: -42
解释: 第一个非空白字符为 '-', 它是一个负号。
     我们尽可能将负号与后面所有连续出现的数字组合起来,最后得到 -42 。

示例 3:

输入: "4193 with words"
输出: 4193
解释: 转换截止于数字 '3' ,因为它的下一个字符不为数字。

示例 4:

输入: "words and 987"
输出: 0
解释: 第一个非空字符是 'w', 但它不是数字或正、负号。
     因此无法执行有效的转换。

示例 5:

输入: "-91283472332"
输出: -2147483648
解释: 数字 "-91283472332" 超过 32 位有符号整数范围。 
     因此返回 INT_MIN (−231) 。

思路

这道题难度不高,主要是要理解题目的要求

题目的要求:

  1. 首先需要丢弃字符串前面的空格;

  2. 然后可能有正负号(注意只取一个,如果有多个正负号,那么说这个字符串是无法转换的,返回0。比如测试用例里就有个“+-2”);

  3. 字符串可以包含0~9以外的字符,如果遇到非数字字符,那么只取该字符之前的部分,如“-00123a66”返回为“-123”

  4. 如果超出int的范围,返回边界值(2147483647-2147483648,INT_MAX和INT_MIN)。

  5. 注意判断是否溢出的条件:

    if(ret >INT_MAX/10 || (ret == INT_MAX/10 && str[i]-'0' >7)
    

    其中一个测试用例就是

    Input:"2147483648"
    Expected:2147483647
    

代码

class Solution {
public:
    int myAtoi(string str) {
    	int ret = 0,i=0;
		char sign = '+'; 	
    	while(str[i]==' ') ++i;
    	if(str[i]=='+'||str[i]== '-'){ // if string has sign
    		if((str[i]=='+'&&str[i+1]=='-') || (str[i]=='-'&&str[i+1]=='+')) // 2 sign
    		return 0;
    		sign = str[i]; // get the sign
    		++i;
		}
    	while(i < str.size()){
    		if(str[i]> '9' || str[i] <'0')
    			break;
    		if(ret >INT_MAX/10 || (ret == INT_MAX/10 && str[i]-'0' >7)){ // if overflow
    			if(sign =='+') return INT_MAX;
    			else if(sign = '-') return INT_MIN;
			}
			ret = ret * 10 + (str[i] -'0');
			++i;
		}
		if(sign == '-') ret = -ret;
		return ret;
    }
};
负数表示

负数的表示范围更大,在计算过程中用负数来表示

class Solution {
public:
    int myAtoi(string str) {
        if(str.empty()) return 0;
        int ret = 0, i = 0;
        bool pos = true;
        while (i <str.size() && str[i] == ' ') ++i;
        if(i>=str.size()) return 0;
        if(str[i] == '+' || str[i] == '-'){
            pos = str[i++] == '+'? true: false;
        }

        while (i < str.size()){
            if(str[i] < '0' || str[i] > '9')
                break;
            if(ret < INT_MIN /10 || (ret == INT_MIN/10 && str[i] - '0' >=8))
                return pos?INT_MAX:INT_MIN;
            ret = ret * 10 - (str[i] - '0');
            ++i;
        }
        return pos? -ret : ret;
    }
};

在这里插入图片描述
LeetCode代码和详细解题报告 Github地址https://github.com/zhengjingwei/LeetCode

资源下载链接为: https://pan.quark.cn/s/9e7ef05254f8 行列式是线性代数的核心概念,在求解线性方程组、分析矩阵特性以及几何计算中都极为关键。本教程将讲解如何用C++实现行列式的计算,重点在于如何输出分数形式的结果。 行列式定义如下:对于n阶方阵A=(a_ij),其行列式由主对角线元素的乘积,按行或列的奇偶性赋予正负号后求和得到,记作det(A)。例如,2×2矩阵的行列式为det(A)=a11×a22-a12×a21,而更高阶矩阵的行列式可通过Laplace展开或Sarrus规则递归计算。 在C++中实现行列式计算时,首先需定义矩阵类或结构体,用二维数组存储矩阵元素,并实现初始化、加法、乘法、转置等操作。为支持分数形式输出,需引入分数类,包含分子和分母两个整数,并提供与整数、浮点数的转换以及加、减、乘、除等运算。C++中可借助std::pair表示分数,或自定义结构体并重载运算符。 计算行列式的函数实现上,3×3及以下矩阵可直接按定义计算,更大矩阵可采用Laplace展开或高斯 - 约旦消元法。Laplace展开是沿某行或列展开,将矩阵分解为多个小矩阵的行列式乘积,再递归计算。在处理分数输出时,需注意避免无限循环和除零错误,如在分数运算前先约简,确保分子分母互质,且所有计算基于整数进行,最后再转为浮点数,以避免浮点数误差。 为提升代码可读性和可维护性,建议采用面向对象编程,将矩阵类和分数类封装,每个类有明确功能和接口,便于后续扩展如矩阵求逆、计算特征值等功能。 总结C++实现行列式计算的关键步骤:一是定义矩阵类和分数类;二是实现矩阵基本操作;三是设计行列式计算函数;四是用分数类处理精确计算;五是编写测试用例验证程序正确性。通过这些步骤,可构建一个高效准确的行列式计算程序,支持分数形式计算,为C++编程和线性代数应用奠定基础。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值