算法通关村第十二关——不简单的字符串转换问题

news2024/12/23 13:57:49

前言

字符串是我们在日常开发中最常处理的数据,虽然它本身不是一种数据结构,但是由于其可以包含所有信息,所以通常作为数据的一种形式出现,由于不同语言创建和管理字符串的方式也各有差异,因此针对不同语言特征又产生了很多问题。

常见的字符串转换题目,也就是在大小写字母、数字、特殊字符这几种类型之间进行。但是在转换过程中需要处理几种特殊情况,比如当前元素能否进行转换,如果是字符串转换为数字还要考虑当前元素是不是数字,转换之后是否会溢出等。

1.转换成小写字母

力扣709题,给你一个字符串 s ,将该字符串中的大写字母转换成相同的小写字母,返回新的字符串。

分析:在计算机中,每个字符都有相应的ASCII码。我们可以根据码表操作字符串,常见的ASCII码范围:

0-9 48-57
A-Z 65-90
a-z 97-122

遍历整个字符串,对每一位字符串加以判断,如果字符串的编码值在65-90之间,就需要在原来了的ASCII值上利用按位或运算| 32就可以转换为对应小写。

代码如下:

// 使用内置函数
function toLowerCase(s) {
  return s.toLowerCase();
}

// 自行实现
let toLowerCase = function (s) {
  const res = [];
  for (let charOfWord of s) {
    if (charOfWord.charCodeAt() >= 65 && charOfWord.charCodeAt() <= 90) {
      // 使用按位或位运算表示加法
      charOfWord = String.fromCharCode(charOfWord.charCodeAt() | 32);
    }
    res.push(charOfWord);
  }
  return res.join("");
};

2.字符串转换为整数(atoi)

力扣8题,请你来实现一个 myAtoi(string s) 函数,使其能将字符串转换成一个 32 位有符号整数(类似 C/C++ 中的 atoi 函数)。

函数 myAtoi(string s) 的算法如下:

  1. 读入字符串并丢弃无用的前导空格
  2. 检查下一个字符(假设还未到字符末尾)为正还是负号,读取该字符(如果有)。 确定最终结果是负数还是正数。 如果两者都不存在,则假定结果为正。
  3. 读入下一个字符,直到到达下一个非数字字符或到达输入的结尾。字符串的其余部分将被忽略。
  4. 将前面步骤读入的这些数字转换为整数(即,“123” -> 123, “0032” -> 32)。如果没有读入数字,则整数为 0 。必要时更改符号(从步骤 2 开始)。
  5. 如果整数数超过 32 位有符号整数范围 [−231, 231 − 1] ,需要截断这个整数,使其保持在这个范围内。具体来说,小于 −231 的整数应该被固定为 −231 ,大于 231 − 1 的整数应该被固定为 231 − 1
  6. 返回整数作为最终结果。

注意:

  • 本题中的空白字符只包括空格字符 ' '
  • 除前导空格或数字后的其余字符串外,请勿忽略 任何其他字符。

分析:

参考:Gatsby/力扣官方

这里用到了自动机的解法,用图来表示:

在这里插入图片描述

用表格来表示:

’ '(空格)+/-Number其它
startstartsignedin_numberend
signedendendin_numberend
in_numberendendin_numberend
endendendendend

代码如下:

/**
 * @param {string} s
 * @return {number}
 */
var myAtoi = function(s) {
	// 自动机类
	class Automaton {
		constructor() {
			// 执行阶段:默认是开始阶段
			this.state = 'start';
			// 正负符号:默认是正数
			this.sign = 1;
			// 数值,默认是0
			this.answer = 0;
			/*
			关键点:
			状态和执行的阶段的对应表
			含义:[执行阶段, [空格], [正负号], [数值], [其它]]
			*/
			this.map = new Map([
				['start',['start', 'signed', 'in_number', 'end']],
				['signed', ['end', 'end', 'in_number', 'end']],
				['in_number', ['end', 'end', 'in_number', 'end']],
				['end', ['end', 'end', 'end', 'end']],
			]);
		}
	

		// 获取状态的索引
		getIndex(char) {
			if (char === ' ') {
				return 0;
			} else if (char === '-' || char === '+') {
				return 1;
			} else if (isNumeric(char)) {
				return 2;
			} else {
				return 3;
			}
		}

		/*
		关键点:
		字符转换执行函数
		*/
		get(char) {
			const MIN_VALUE = -Math.pow(-2, 31);
			const MAX_VALUE = Math.pow(2, 31) - 1;
			/*
			易错点:
			每次传入字符,都要变更自动机的执行阶段
			*/
			this.state = this.map.get(this.state)[this.getIndex(char)];
			if (this.state === 'in_number') {
				/*
				小技巧:
				在JS中,对字符串类型做减法操作,可以得到一个数值型(Number)的值
				
				易错点:本处需要利用括号来提高四则运算的优先级
				*/
				this.answer = this.answer * 10 + (char - 0);

				// 易错点:在进行负数比较时,需要将INT_MIN变为正数
				this.answer = (this.sign === 1 ? Math.min(this.answer, MAX_VALUE) : Math.min(this.answer, MIN_VALUE));
			} else if (this.state === 'signed') {
				/*
				优化点:
				对于一个整数来说,非正即负,
				所以正负号的判断,只需要一次。
				所以可以降低其判断的优先级
				*/
				this.sign = (char === '+' ? 1 : -1);
			}
		}
	}

	// 判断传进来的字符串是不是数字
	function isNumeric(s) {
	  return /^-?\d+(\.\d+)?$/.test(s);
	}

	// 生成自动机实例
	let automaton = new Automaton();

	// 遍历每个字符
	for (let char of s) {
		// 依次进行转换
		automaton.get(char);
	}

	// 返回值,整数 = 正负 * 数值
	return automaton.sign * automaton.answer;
};

在判断传入的字符是不是数字时,最好用正则表达式来判断,这样比较准确。

typeof Number(char) === 'number'!isNaN(char)都不太合理:

  1. typeof Number(char) === 'number': 这部分判断使用了typeof操作符,它会将Number(char)的结果判定为'number'。然而,Number(char)在转换无法转换为有效数字的字符串时会返回NaN,而typeof NaN也是'number',因此这部分判断并不能准确地判断传入的字符串是否是一个有效的数字。
  2. !isNaN(char): 这部分判断使用了isNaN函数,它用于检查一个值是否为NaN。然而,isNaN函数在判断非数字类型的值时也会返回false,比如空字符串、布尔值、对象等。这也就意味着,如果传入的是非数字但却不是NaN的值,这部分判断同样会得出错误的结论。

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

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

相关文章

自助式数据分析平台:JVS智能BI功能介绍(一)数据源

一、数据源配置 数据源概述 数据源是JVS-智能BI支持多种数据形态的基础&#xff0c;核心的目标是将不同的数据来源通过统一接入&#xff0c;实现将不同的数据实现统一的数据加工、数据应用。目前JVS-智能BI主要支持3种形态的数据&#xff1a;数据库、API、离线文件。 ​界面介…

C#,《小白学程序》第十一课:阶乘(Factorial)的计算方法与代码

1 文本格式 /// <summary> /// 阶乘的非递归算法 /// </summary> /// <param name"a"></param> /// <returns></returns> private int Factorial_Original(int a) { int r 1; for (int i a; i > 1; i--) { …

M2DGR数据集各相机话题名与外参名的对应关系

M2DGR数据集除了视觉惯性器件、天向相机&#xff0c;还有6个安装在同一平面、参数一致的鱼眼相机。 本文对这6个相机的安装位置、外参、topic话题进行区分。 安装图&#xff1a; 6个鱼眼相机 fish-eye camera装载在同一层。 外参情况 fish-eye camera在calibration_results…

如何使用FormKit构建Vue.Js表单

表单是现代网页开发的重要组成部分&#xff0c;创建表单通常是一项耗时且繁琐的任务。这就是FormKit的用武之地&#xff1b;它是一个功能强大的现代表单构建库&#xff0c;旨在帮助开发人员轻松高效地创建表单。 在本文中&#xff0c;我们将探讨使用FormKit的好处&#xff0c;并…

PostgreSQL问题记录:column “...“ does not exist

在PostgreSQL中&#xff0c;不论是在pgAdmin中&#xff0c;还是在命令行控制台里面&#xff0c;在SQL语句中表示属性值的总会遇到ERROR: column “…” does not exist这样的错误&#xff0c;比如下面的语句&#xff1a; 解决方案&#xff1a;将 “txt2txt” 的双引号改成单引…

前端三大Css处理器之Less

Less是Css预处理器之一&#xff0c;分别有Sass、Less、Stylus这三个。 Lesshttps://lesscss.org/ Less是用JavaScript编写的&#xff0c;事实上&#xff0c;Less是一个JavaScript库&#xff0c;他通过混合、变量、嵌套和规则设置循环扩展了原生普通Css的功能。Less的少数…

安捷伦Agilent E8362C网络分析仪

产品概述 Agilent E8362C网络分析仪提供通用网络分析&#xff0c;带有可选软件和/或硬件&#xff0c;可根据您的应用进行定制&#xff0c;如多端口、脉冲射频等。 Agilent E8362C网络分析仪的显示窗口数量不限&#xff0c;可以调整大小和重新排列&#xff0c;每个窗口最多有24…

乐理-笔记

乐理笔记整理 1、前言2、认识钢琴键盘及音名3、升降号、还原号4、如何区分同一音名的不同键&#xff1f;5、各类音符时值的关系6、歌曲拍号7、拍号的强弱规律8、歌曲速度&#xff08;BPM&#xff09;9、附点音符10、三连音12、唱名与简谱数字13、自然大调&#xff08;白键&…

Docker consul 容器服务自动发现和更新

目录 一、什么是服务注册与发现 二、Docker-consul集群 1.Docker-consul consul提供的一些关键特性 2.registrator 3.Consul-template 三、Docker-consul实现过程 以配置nginx负载均衡为例 先配置consul-agent &#xff0c;有两种模式server和client 四、Docker-cons…

Qt Graphics View

Graphics View框架 在 Qt 中&#xff0c;Graphics View Framework&#xff08;场景视图框架&#xff09;是用于创建和管理可交互的 2D 图形界面的强大工具。它提供了以下主要的类和概念&#xff1a; QGraphicsScene&#xff08;场景&#xff09;&#xff1a;QGraphicsScene 是…

【lucky-canvas插件】在Vue3实现大转盘九宫格老虎机抽奖

目录 前言 一、lucky-canvas介绍 二、lucky-canvas使用&#xff08;Vue3&#xff09; 1. 安装 2. 注册 3. 使用 三、九宫格为例的具体使用 1. 组件使用 2. 常用配置 ① blocks 背景 ② prizes 奖品 ③ buttons 抽奖按钮 3. 回调函数 ① start 开始抽奖前 ② end …

【Flask】from flask_sqlalchemy import SQLAlchemy报错

【可能出现的情况】 1、未安装 Flask-SQLAlchemy&#xff1a; 在使用 flask_sqlalchemy 之前&#xff0c;你需要确保已经通过 pip 安装了 Flask-SQLAlchemy。可以通过以下命令安装它&#xff1a; pip install Flask-SQLAlchemy 2、包名大小写问题&#xff1a; Python 是区分大…

css让多个盒子强制自动等宽

1.width: calc( 100 / n% ) 2.display:flex; flex:1;width:100px; 3.display:grid;grid-template-columns: repeat(auto-fit, minmax(100px, 1fr)); 但是其中某一个内容较长的时候 会破坏1:1:1的平衡 这个时候发现附件名字过长导致不等比例&#xff0c;通过查看阮一峰flex文…

《人生苦短,我学Python》——布尔类型 比较运算 逻辑运算

&#x1f448;前三天&#xff0c;我们学了字符串、整型、浮点型这三种数据类型。今天我们将学习最后一种数据类型&#xff1a;布尔型。简单来说&#xff0c;布尔型就是“真”&#xff08;True&#xff09;和“假”&#xff08;False&#xff09;。下面就让我们来详细看看吧&…

13.动态渲染侧边栏

为什么要动态渲染&#xff1f; 比如我们现在需要以下侧边栏的数据&#xff1a; 如果一个个的去写标签会很麻烦&#xff0c;发现导航栏中的数据分为两类&#xff0c;一类是一级导航&#xff0c;另一位是二级导航&#xff08;有子页&#xff09;&#xff0c;因此直接写两个函数判…

Docker从认识到实践再到底层原理(二-1)|容器技术发展史+虚拟化容器概念和简介

前言 那么这里博主先安利一些干货满满的专栏了&#xff01; 首先是博主的高质量博客的汇总&#xff0c;这个专栏里面的博客&#xff0c;都是博主最最用心写的一部分&#xff0c;干货满满&#xff0c;希望对大家有帮助。 高质量博客汇总 然后就是博主最近最花时间的一个专栏…

20230831工作心得:SQL这块花了挺多时间

1、SQL语句的问题 1、SQL这块花了挺多时间 1、理解业务 要之前自己要查什么数据&#xff0c;再去写SQL&#xff0c;这句话看起来像一句废话&#xff0c;但是很多时候&#xff0c;不知道自己在干嘛。 2、时间 1、需要查询哪个时间字段 表里有很多time有create_time&#…

【2】openGL shader着色器分析三角形填色

源代码在下面。文档查询 > docs.gl 结果展示&#xff1a;使用自己的shader和打印错误描述 该篇主要在上一部分代码的基础上添加了自己写的shader&#xff0c;即着色器。最常用的两个着色器 vertex shader 和 fragment shader&#xff0c;即顶点着色器和片段着色器。 大概…

嵌入式行业——选择比努力重要

嵌入式开发可以说是一个较大的类别&#xff0c;也可以看作是应用技术的一种广义称谓。它在不同的工业和行业场景中应用不同的业务模式和领域。 举个例子&#xff0c;嵌入式技术结合基站通信技术&#xff0c;就构成了华为基站&#xff1b;嵌入式技术结合视频处理/图像处理技术&a…