【算法】字符串转int类型思路及代码

news2024/12/29 11:01:20

文章目录

  • 题目
  • 分析
  • 思路
  • 完整代码

题目

给你一个字符串,如何这个字符串符合日常的整形的书写规范,那么我们需要写出将其转化为int类型的方法,并且不能使用Java提供的API,比如parseInt方法。

分析

这道题考察的其实就是parseInt的底层思路实现,相当于是你自己要学会写出一个parseInt方法。
并且考虑到需要将字符串转换为int,那么首先我们要保证,这个字符串符合int类型的格式,并且不会发生溢出。
有如下几种情况需要保证:
1:这个字符串可以为 ‘ - ’开头,但是不能只有一个 ‘ - ’
2:这个字符串开头为0时字符串长度必须也为1
3:不能发生溢出,也就是字符串的值不能大于 2147483647,不能小于 - 2147483648
4:字符串中不能出现除了 ‘ - ’,‘0’ - ‘9’的任何其他非法字符,比如 ‘A’

思路

1:我们可以先编写一个方法,判断这个字符串对应的数据是否符合它是一个数字类型的要求。
方法如下:

 public static boolean isValid(String str) {
        char[] chars = str.toCharArray();
        //1:判断字符串不以 ‘ - ’开头并且也不是数字开头
        if (chars[0] != '-' && (chars[0] < '0' || chars[0] > '9') {
            return false;
        }
        //2:字符串以'-'开头,但是长度为1,或长度不为1,但是chars[1]='0'
        if (chars[0] == '-' && (chars.length == 1 || chars[1] == '0')) {
            return false;
        }
        //3:字符串以0开头,但是长度不为1
        if (chars[0] == '0' && chars.length != 1) {
            return false;
        }
        //4:判断字符串中是否有非法字符
        for (int i = 1; i < chars.length; i++) {
            if (chars[i] > '9' || chars[i] < '0') {
                return false;
            }
        }
        return true;
    }

2:成功判断当前字符串是否是一个合格的整形之后,我们开始具体的转换思路。
首先,根据字符串的正负进行判断,如果是以 ‘ - ’开头,那么从字符串的下标1处开始遍历,否则从0开始遍历。
然后,得到数据的方式其实就是,我们从字符串的左边开始遍历,当前值(初始为0)乘*10+当前位的值即可。
先看下面一段不考虑溢出的代码,你可能会这么写。

  public static int parseInt(String str) {
        int cur = 0;
        int res = 0;
        boolean negative = str.charAt(0) == '-' ? true : false;
        for (int i = negative ? 1 : 0; i < str.length(); i++) {
            cur = str.charAt(i)-'0';
            res = res * 10+cur;
        }
        return negative?-1*res : res;
    }

    public static void main(String[] args) {
        System.out.println(parseInt("-123123"));
    }

对于不考虑溢出的情况,当然可以怎么写,答案也是对的,但是如果我们输入的字符串会溢出,那么我们处理起来会比较棘手,原因如下:
我们输入一个超出int范围的数据,那么就会溢出,从而导致数据的不准确。
在这里插入图片描述
可能你会认为加一个判断即可,但是很明显,在这里,如果我们在已经得到了最后的res之后进行判断,明显是不合理的,因为此时要么已经溢出,要么就是需要将long类型和int类型去比较,不太合理。
因此我们的解决思路是,得到 Integer.MAX_VALUE除以10的哪一个数据,然后这样子就能做到提前比较是否溢出。
代码如下:

 public static int parseInt(String str) {
        int cur = 0;
        int res = 0;
        int maxQ = Integer.MAX_VALUE / 10;
        int maxP = Integer.MAX_VALUE % 10;

        boolean negative = str.charAt(0) == '-' ? true : false;
        for (int i = negative ? 1 : 0; i < str.length(); i++) {
            cur = str.charAt(i) - '0';
            //如果此时res已经大于了int最大值/10,并且此时cur还没有加上去就已经大于了,那么说明肯定溢出,直接返回0
            //如果等于,但是cur大于最后一位,那么也是溢出,也返回
            if (res > maxQ || (res == maxQ && cur > maxP) ||
                    (res == maxQ && negative && cur > maxP + 1)){
                return 0;
            }
            res = res * 10 + cur;
        }
        return negative ? -1 * res : res;
    }

    public static void main(String[] args) {
        System.out.println(parseInt("-2147483649")); // 0 
        System.out.println(parseInt("2147483649")); // 0 
    }

如下代码是Java的Integer提供的字符串转int类型的方法

  public static int parseInt(String s, int radix)
                throws NumberFormatException
    {
        /*
         * WARNING: This method may be invoked early during VM initialization
         * before IntegerCache is initialized. Care must be taken to not use
         * the valueOf method.
         */

        if (s == null) {
            throw new NumberFormatException("null");
        }

        if (radix < Character.MIN_RADIX) {
            throw new NumberFormatException("radix " + radix +
                                            " less than Character.MIN_RADIX");
        }

        if (radix > Character.MAX_RADIX) {
            throw new NumberFormatException("radix " + radix +
                                            " greater than Character.MAX_RADIX");
        }

        int result = 0;
        boolean negative = false;
        int i = 0, len = s.length();
        int limit = -Integer.MAX_VALUE;
        int multmin;
        int digit;

        if (len > 0) {
            char firstChar = s.charAt(0);
            if (firstChar < '0') { // Possible leading "+" or "-"
                if (firstChar == '-') {
                    negative = true;
                    limit = Integer.MIN_VALUE;
                } else if (firstChar != '+')
                    throw NumberFormatException.forInputString(s);

                if (len == 1) // Cannot have lone "+" or "-"
                    throw NumberFormatException.forInputString(s);
                i++;
            }
            multmin = limit / radix;
            while (i < len) {
                // Accumulating negatively avoids surprises near MAX_VALUE
                digit = Character.digit(s.charAt(i++),radix);
                if (digit < 0) {
                    throw NumberFormatException.forInputString(s);
                }
                if (result < multmin) {
                    throw NumberFormatException.forInputString(s);
                }
                result *= radix;
                if (result < limit + digit) {
                    throw NumberFormatException.forInputString(s);
                }
                result -= digit;
            }
        } else {
            throw NumberFormatException.forInputString(s);
        }
        return negative ? result : -result;
    }

完整代码

package com.base.learn.string;

/**
 * @author: 张锦标
 * @date: 2023/5/25 9:57
 * ParseInt类
 */
public class ParseInt {
    public static boolean isValid(String str) {
        char[] chars = str.toCharArray();
        //1:判断字符串不以 ‘ - ’开头并且也不是数字开头
        if (chars[0] != '-' && (chars[0] < '0' || chars[0] > '9')) {
            return false;
        }
        //2:字符串以'-'开头,但是长度为1,或长度不为1,但是chars[1]='0'
        if (chars[0] == '-' && (chars.length == 1 || chars[1] == '0')) {
            return false;
        }
        //3:字符串以0开头,但是长度不为1
        if (chars[0] == '0' && chars.length != 1) {
            return false;
        }
        //4:判断字符串中是否有非法字符
        for (int i = 1; i < chars.length; i++) {
            if (chars[i] > '9' || chars[i] < '0') {
                return false;
            }
        }
        return true;
    }

    public static int parseInt(String str) {
        int cur = 0;
        int res = 0;
        int maxQ = Integer.MAX_VALUE / 10;
        int maxP = Integer.MAX_VALUE % 10;
        //如果此时res已经大于了int最大值/10,并且此时cur还没有加上去就已经大于了,
        // 那么说明肯定溢出,直接返回0
        //如果等于,但是cur大于最后一位,那么也是溢出,也返回
        boolean negative = str.charAt(0) == '-' ? true : false;
        for (int i = negative ? 1 : 0; i < str.length(); i++) {
            cur = str.charAt(i) - '0';
            if (res > maxQ || (res == maxQ && cur > maxP) ||
                    (res == maxQ && negative && cur > maxP + 1)){
                return 0;
            }
            res = res * 10 + cur;
        }
        return negative ? -1 * res : res;
    }

    public static void main(String[] args) {
        String s = "123asd";
        if (!isValid(s)){
            //do something
        }else{
            parseInt(s);
        }
    }
}

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

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

相关文章

亚马逊测评:提升产品排名、权重和销量的秘诀

亚马逊是全球最大的在线零售平台&#xff0c;覆盖了世界各地主要国家和地区&#xff0c;而随着平台商家的不断增加&#xff0c;为了提高自身排名&#xff0c;很多卖家开始寻找人员为他们的店铺和产品进行有偿评价&#xff0c;从而催生了亚马逊测评行业 亚马逊测评&#xff0c;…

笔试强训 Day6

选择题 1.十进制变量i的值为100&#xff0c;那么八进制的变量i的值为&#xff08;&#xff09; A 146 B 148C 144 D 142 本题很简单&#xff1a;100除8&#xff0c;取余数&#xff0c;直到商为零&#xff0c;最后反向的串起余数即可 2.执行下面语句后的输出为&#xff08;&…

从传统开发到低代码:这是一次技术革命

近年来&#xff0c;随着人工智能等新兴技术的快速发展&#xff0c;软件开发行业也在不断演变。传统的软件开发流程需要大量的编程知识和时间&#xff0c;而且往往需要复杂的架构和开发环境。然而&#xff0c;随着低/无代码平台的出现&#xff0c;软件开发变得更加高效、简单和普…

服务(第三十篇)elk-elasticsearch、logstash、kiabana

rsyslog 服务器较少时使用&#xff0c;rsyslog日志收集&#xff0c;统一存放在专门存放日志的收集器中&#xff1b; ELK 简介 ELK平台是一套完整的日志集中处理解决方案&#xff0c;将 ElasticSearch、Logstash 和 Kiabana 三个开源工具配合使用&#xff0c; 完成更强大的用…

产品经历、运营人员必看:高效产品帮助文档撰写指南

产品帮助文档是产品的重要组成部分&#xff0c;它对于产品的用户体验和产品的成功至关重要。帮助文档可以帮助用户更好地理解产品的功能和使用方法&#xff0c;提高用户的满意度和使用效率。同时&#xff0c;帮助文档还可以减轻客服和技术支持的工作负担&#xff0c;提高客服和…

Spring Boot 中如何使用 Spring Security OAuth2 来实现单点登录

Spring Boot 中如何使用 Spring Security OAuth2 来实现单点登录 简介 在现代 Web 应用程序中&#xff0c;单点登录&#xff08;Single Sign-On&#xff0c;简称 SSO&#xff09;是一个非常重要的功能。Spring Security OAuth2 是 Spring Security 框架的一个扩展&#xff0c…

Ubuntu宝塔显示磁盘被占满的解决方法

操作方法&#xff1a; 连接成功 Last login: Sat Mar 25 03:04:00 2023 from 192.168.153.1 rootubuntu:~# lvm lvm> lvextend -l 100%FREE /dev/mapper/ubuntu-vg/ubuntu-lv skip_dev_dir: Couldnt split up device name ubuntu-vg/ubuntu-lv. Size of logical volum…

Windows中的Tomcat服务器安装证书并设置强制https访问

官网参考 阿里云 华为云 获取证书 自己生成证书 这边介绍一个生产开发环境证书的方式&#xff1a;使用 Java 提供的工具&#xff1a;keytool keytool -genkeypair -alias "tomcat" -keyalg "RSA" -keystore "d:\tomcat.keystore" Tomcat服…

Golang变量初始

Golang变量初始 采用文章 本章使用go练习工具 https://tour.go-zh.org/welcome/13.1 为什么需要变量 3.1.1一个程序就是一个世界 3.1.2变量是程序的基本组成单位 不论是使用哪种高级程序语言编写程序,变量都是其程序的基本组成单位&#xff0c;比如一个示意图 3.2 变量的介…

专门用于管理企业与自己客户之间所有信息的客户管理系统

一、开源项目简介 关于 NXCRM NXCRM 是一套基于 Laravel 的 CRM 应用程序。它包含了一个管理中心&#xff0c;可以管理用户、客户、产品、订单、商机&#xff0c;合同&#xff0c;收款&#xff0c;附件&#xff0c;联系人&#xff0c;跟进动态&#xff0c;发票&#xff0c;业…

近年GDC服务器分享合集(二): 《太空工程师》中基于预测物理的多人游戏

客户端-服务端之间的位置同步一直是游戏开发中的一道难题&#xff0c;特别是还涉及到复杂的物理运动时。对于这个话题&#xff0c;来自《太空工程师》游戏的工程师在GDC 2023上为我们带来了他们的分享——《《太空工程师》中基于预测物理的多人游戏》&#xff08;Predicted Phy…

在 openEuler 22.03 上安装 KubeSphere 实战教程

作者&#xff1a;老 Z&#xff0c;中电信数智科技有限公司山东分公司运维架构师&#xff0c;云原生爱好者&#xff0c;目前专注于云原生运维&#xff0c;云原生领域技术栈涉及 Kubernetes、KubeSphere、DevOps、OpenStack、Ansible 等。 前言 导图 知识点 定级&#xff1a;入…

域泛化(Domain Generalization)相关知识学习

文章目录 一、域泛化综述1&#xff09;Domain定义2&#xff09;Domain Generalization&#xff08;DG&#xff09;定义3&#xff09;一些相关领域与DG的区别4&#xff09;领域泛化的方法表示学习领域不变表示学习①基于核的方法&#xff08; kernel-based methods&#xff09;②…

python自动化(一)基础能力:9.yaml文件详解

一、什么是yaml文件 yaml 是专门用来写配置文件的语言——可以用例作为自动化框架的配置文件yaml文件其实也是一种配置文件类型&#xff0c;后缀名是.yaml或.yml都可以个人认为比yaml比json格式更方便 二、yaml语法规则 YAML 语言&#xff08;发音 /ˈjməl/ &#xff09;的设…

电力应急指挥需要哪些终端设备?

在电力应急现场&#xff0c;我们可能会面临很多复杂的情况&#xff0c;当发生电力险情时&#xff0c;现场可能会面临断电、断网、无路等问题。此时应急指挥中心很难第一时间掌控现场情况&#xff0c;指挥中心无法快速做出反应&#xff0c;无法对现场情况做出高效的应急处置决定…

Spring Boot源码中设计模式应用浅析

文章目录 1. 工厂模式1.1 详解 DefaultListableBeanFactory 2. 单例模式1.1 详解 DefaultSingletonBeanRegistry 3. 观察者模式4. 适配器模式5. 模板方法模式 背景&#xff1a;大家好&#xff0c;我是冰点。最近有网友反馈&#xff0c;他在面试过程中被面试官问到&#xff0c;设…

NVDIA GPU参数列表: 3090,4090, A40, A30,V100, A100, A800性能参数

GeForce RTX 4090 GeForce RTX 3090 Ti &#xff08;左&#xff09; GeForce RTX 3090&#xff08;右&#xff09; A40&#xff1a; The NVIDIA A40 accelerates the most demanding visual computing workloads from the data center, combining the latest NVIDIA Ampere …

如何在Spring Boot服务端实现公网远程调试并进行HTTP服务监听?具体涉及到的步骤包括端口映射等

文章目录 前言1. 本地环境搭建1.1 环境参数1.2 搭建springboot服务项目 2. 内网穿透2.1 安装配置cpolar内网穿透2.1.1 windows系统2.1.2 linux系统 2.2 创建隧道映射本地端口2.3 测试公网地址 3. 固定公网地址3.1 保留一个二级子域名3.2 配置二级子域名3.2 测试使用固定公网地址…

Hadoop学习---7、OutputFormat数据输出、MapReduce内核源码解析、Join应用、数据清洗、MapReduce开发总结

1、OutputFormat数据输出 1.1 OutputFormat接口实现类 OutputFormat是MapReduce输出的基类&#xff0c;所以实现MapReduce输出都实现了OutputFormat接口。 1、MapReduce默认的输出格式是TextOutputFormat 2、也可以自定义OutputFormat类&#xff0c;只要继承就行。 1.2 自定…

C++标准库算法std::upper_bound示例

C标准库算法std::upper_bound示例 贺志国 2023.5.25 C标准库算法std::upper_bound使用二分查找算法在已按升序排列的序列中返回指向第一个大于给定值的元素的迭代器&#xff0c;例如&#xff1a;已按升序排列的序列为{100.0, 101.5, 102.5, 102.5, 107.3}&#xff0c;第一个大…