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

这篇具有很好参考价值的文章主要介绍了算法通关村第十二关——不简单的字符串转换问题。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前言

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

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

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/力扣官方

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

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

用表格来表示:

’ '(空格) +/- Number 其它
start start signed in_number end
signed end end in_number end
in_number end end in_number end
end end end end end

代码如下:

/**
 * @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)都不太合理:文章来源地址https://www.toymoban.com/news/detail-687975.html

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

到了这里,关于算法通关村第十二关——不简单的字符串转换问题的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 算法通关村十二关 | 字符串前缀问题

    题目:LeetCode14,14. 最长公共前缀 - 力扣(LeetCode) 我们先看公共前缀有什么特点。 第一种方式,竖着比较,如图左边所示,选取数组中第一个字符串的位置,每前进一个就比较各个字符串,看是否相等,只有某一轮遇到不相等,则结束返回结果。 还是这张图         如

    2024年02月11日
    浏览(36)
  • 【LeetCode】《LeetCode 101》第十二章:字符串

    思路及代码: 242 . 有效的字母异位词 思路及代码: 205. 同构字符串 思路及代码: 647. 回文子串 思路及代码: 696 . 计数二进制子串 思路及代码 : 224. 基本计算器 思路及代码: 227. 基本计算器 II 思路与代码: 28 . 找出字符串中第一个匹配项的下标 思路及代码 :409. 最长回文

    2024年02月10日
    浏览(31)
  • 算法通关村十三关 | 数组字符串加法专题

    题目:LeetCode66,66. 加一 - 力扣(LeetCode) 我们只需要从头到尾依次运算,用常量标记是否进位,需要考虑的特殊情况是digits = [9,9,9]的时候进位,我们组要创建长度加1的数组,首位添加为1即可。         给定两个非负形式的字符串num1和num2,计算他们的和以字符串形式返

    2024年02月11日
    浏览(31)
  • 算法第十七天-构造有效字符串的最少插入数

    考虑abc的个数 假设答案有n个\\\"abc\\\"组成,那么需要插入的字符个数为 3 ∗ n − l e n ( s ) 3*n - len(s) 3 ∗ n − l e n ( s ) 。 对于相邻的两个字符x和y(x在y左侧): 如果 x y xy x y ,那么x和y可以在同一个\\\"abc\\\"内,否则一定不在; 如果 x ≥ y xge y x ≥ y ,那么x和y一定不可以在同一个

    2024年01月17日
    浏览(33)
  • C++入门学习(十二)字符串类型

    上一节(C++入门学习(十一)字符型-CSDN博客)中我们学到如何表示和使用一个字符串,本篇文章是字符串(多个字符)。 定义字符串主要有两种方式: 第一种: char str[] = \\\"win\\\";  //char 变量名[] = \\\"字符串\\\" 第二种: #include string string str1 = \\\"winner\\\"; / / 两种方式代码:  注意字符

    2024年01月23日
    浏览(30)
  • 算法通关村第十七关:青铜挑战-贪心其实很简单

    1. 难以解释的贪心算法 贪心学习法则:直接做题,不考虑贪不贪心 贪心(贪婪)算法 是指在问题尽心求解时,在每一步选择中都采取最好或者最优(最有利)的选择,从而希望能够导致结果最好或者最优的算法 贪心算法所得到的结果不一定是最优的结果,但是都是相对近似最

    2024年02月09日
    浏览(30)
  • 算法通关村第十六关:青铜挑战-滑动窗口其实很简单

    1. 滑动窗口基本思想 数组引入双指针的背景: 很多算法会大量移动数组中的元素,频繁移动元素会导致执行效率低下或者超时,使用两个变量能比较好的解决很多相关问题 数组双指针,之前介绍过 对撞型 和 快慢型 两种,滑动窗口思想就是快慢型的特例 滑动窗口 示例:

    2024年02月09日
    浏览(34)
  • 算法通关村第二关——链表反转

    链表反转,就是链表原来是1-2-3-4-5,经过反转处理过后变成5-4-3-2-1 处理链表反转,有两种方式,一个是建立虚拟头结点,一个是直接操作链表反转。  这是执行的流程 最核心的两行就是 直接想我要让她反转,我现在设立了虚拟头结点,那我就要让新加进这个反转链表的结点

    2024年02月13日
    浏览(27)
  • 算法通关村第二关——单链表加一

    LeetCode369 用一个非空单链表来表示一个非负整数,然后将这个整数加一。你可以假设这个整数除了 0 本身,没有任何前导的 0.这个证书的各个数位按照 高位在链表头部、低位在链表尾部 的顺序排列。 计算是从低位开始的,而链表是从高位开始的,所以要处理就必须反转过来

    2024年02月14日
    浏览(32)
  • 算法通关村第二关——终于学会链表

    LeetCode206 给我们单链表的头结点head,请你反转链表,并返回反转后的链表,如图所示: 本题有两种方法,分别为 建立虚拟头结点辅助反转 以及 直接操作链表实现反转 ,两种方法我将逐一分析讲解。 首先从名字分析一下这种方法,虚拟头结点,顾名思义,我们可以建立一个

    2024年02月15日
    浏览(33)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包