算法通关春 —— 字符串转换问题

目录

字符串转换问题

一 转换成小写字母

二 字符串转换整数


字符串转换问题

字符串本身不是一种数据结构,但是由于其本身的特殊性,可以产生一些特定的算法题。

字符串里存放的可以是字母,可以是数字,也可以是特殊字符,字母可以为大写也可以为小写,所以就使得字符串有一类很常见的转换题目,这些题目转换类型变了,但本质不变,都是想办法遍历到字符串中每个字符,然后判断当前元素需不需要转。如果是字符串转数字,则还需要考虑当前元素是不是数字以及转换完之后会不会一处等等。这些问题其实并不复杂,主要是对各种转换可能出现的情况要考虑周全

一 转换成小写字母

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

示例:
输入:s = "HellO, World"
输出:"hello, world"

因为每个字母都有对应的ASCII码,所以我们可以根据ASCII码表来操作字符串即可。

常见ASCII码范围为:A~Z: 65-90, a~z: 97-122,   0-9:48-57

这个题需要先遍历整个字符串 遍历字符串我们可以先把字符串转为 字符数组 ,这样就很方便遍历了,然后再对每一位字符进行判断,如果其ASCII码在A~Z之间,则需要将其ASCII码加上32即可转换为对应的小写字符, 具体实现代码如下:

class Solution {
    public String toLowerCase(String s) {
        int len = s.length();
        char[] chars = s.toCharArray(); // 将字符串转化为字符数组便于遍历
        for(int i = 0; i < len; i++){
            // 通过ACSII码判断遍历到大写字母
            if(chars[i] >= 65 && chars[i] <=90){
                chars[i] += 32;
            }
        }
        // 将转换为小写字母后的字符数组转换为字符串
        String str = new String(chars);
        return str;
    }
}

二 字符串转换整数

本题需要实现一个myAtoi(String s)函数, 使其能将字符串转换成一个32位有符号整数,该函数的转换算法如下:

1)读入字符串并丢弃无用的前导空格

2)检查丢弃前导空格后的第一个字符是否有正负号,如果有则可确定最终结果是正数还是负数,如果两者都不存在,则默认结果为正

3)将前面步骤读入的这些数字转换为整数(即"123" -> 123, "0032" -> 32),如果没有读入数字,则输出为0,记住加入所需符号。

4)如果整数超过32为有符号整数范围 [-2^31, 2^31],则需截断该数,使其保持在范围内,即输出

有符号整数的最大值或者最小值

5) 返回整数作为最终结果

其实该题思路和第一题大差不差,本质上都是遍历字符串中的字符,然后将需要转换的字符转换为整数。只不过这道题需要判断各种特殊情况,以及还要判断是否溢出,通过算法介绍我们主要可以罗列出以下几个重点:

⚪ 第一步:我们需要去掉前置的所有空格

⚪ 第二步:判断第一个字符为 + 或 - 的情况,因此可以设置一个变量sign,1为+,-1为-

⚪ 第三步:转换数字记录到结果中前先判断转换后的数字是否超过int 类型的范围,如果超过需要截取。这里不能将结果res变量设计为long类型。

⚪ 第四步:通过与ASCII码进行比较判断当前字符是否为数字,若是则转换为整数,最前面的0需要将其去掉,这里我们只需将该转换后的数字加到res中,则前面的0就不影响结果了。

具体实现代码及各步的详细解析如下:

class Solution {
    public int myAtoi(String s) {
        int len = s.length();
        char[] chars = s.toCharArray(); // 将字符串转换为字符数组便于遍历
        // 1、去掉前导空格
        int index = 0;
        while(index < len && chars[index] == ' '){
            index++;
        }
        // 2、判断是否全为空格
        if(index == len) return 0;
        // 3、若出现符号字符,仅第一个有效,记录正负号
        int sign = 1; // 初始为+
        if(chars[index] == '+') index++;
        else if(chars[index] == '-') {
            index++;
            sign = -1; // 如果为'-',则记录符号为-1
        }
        // 4、将后序出现的数字进行转换(题目要求不能使用long类型)
        int res = 0;
        while(index < len){
            char cur = chars[index]; // 记录字符的指针
            //4.1 判断不合法(不为0~9)的情况
            if(cur < '0' || cur > '9') break;

            //4.2 解决溢出问题,判断是否越界
            // 提前判断乘以10后是否越界,但res*10可能会越界
            // 所以这里使用与Integer.MAX_VALUE / 10 进行判断,则不会越界
            // 判断正数是否溢出
            if(res > Integer.MAX_VALUE / 10 || (res == Integer.MAX_VALUE / 10
                && (cur - '0')>Integer.MAX_VALUE % 10))
                return Integer.MAX_VALUE;
            // 判断负数是否溢出
            if(res < Integer.MIN_VALUE / 10 || (res == Integer.MIN_VALUE / 10
                && (cur - '0')> -(Integer.MIN_VALUE % 10)))
                return Integer.MIN_VALUE;   

            // 将数字更新到res里, 记住要乘以符号在加进去 
            res = res*10 + sign * (cur - '0');
            index++;       
        }
        return res;
    }
}

你可能感兴趣的:(算法)