从字符串到数字的转换

从字符串到数字

Posted by LY on February 14, 2019

在这里小小推荐下我的个人博客

csdn:雷园的csdn博客

个人博客:雷园的个人博客

简书:雷园的简书

前言

  1. 最近准备把算法慢慢的捡起来,所以准备日更一道算法题目,难度自然是由简入难,所以同学们可以每天都来看看小编的更新。
  2. 日更时间定在每晚20:00,希望大家多多关注啦。
  3. 昨天就欠更了,简直就是打脸。过完年刚开工,比较忙,今天更新两道,上午已更新一道,小编在这里奉上第二道题目!!!!!

实现将字符串转换为整数

  1. 该函数首先丢弃尽可能多的空白字符,直到找到第一个非空白字符。然后,从这个字符开始,取一个可选的初始加号或减号,后面跟着尽可能多的数字,并将它们解释为一个数值。

  2. 字符串可以在组成整数的字符之后包含其他字符,这些字符将被忽略,并且对该函数的行为没有影响。

  3. 如果str中的第一个非空格字符序列不是有效的整数,或者由于str为空或只包含空格字符而不存在这样的序列,则不执行转换。

  4. 如果无法执行有效的转换,则返回零值。

注意:

  1. 只有空格字符’ ‘被认为是空格字符。

  2. 假设我们正在处理一个环境,只能在32位带符号整数存储整数范围:[$-2^{31}$,$2^{31}-1$]。如果数值的范围可表示的值,INT_MAX($2^{31}-1$)或INT_MIN返回($-2^{31}$)。

Example 1:

Input: "42"
Output: 42

Example 2:

Input: "   -42"
Output: -42
Explanation: The first non-whitespace character is '-', which is the minus sign.
             Then take as many numerical digits as possible, which gets 42.

Example 3:

Input: "4193 with words"
Output: 4193
Explanation: Conversion stops at digit '3' as the next character is not a numerical digit.

Example 4:

Input: "words and 987"
Output: 0
Explanation: The first non-whitespace character is 'w', which is not a numerical 
             digit or a +/- sign. Therefore no valid conversion could be performed.

Example 5:

Input: "-91283472332"
Output: -2147483648
Explanation: The number "-91283472332" is out of the range of a 32-bit signed integer.
             Thefore INT_MIN (-2147483648) is returned.

解题思路

  1. 首先我们需要抛弃空格,但是并非所有空格,而是在正负号或者数字之前的所有空格。

  2. 如果我们在遇到正负号或数字前先遇到了其他非空格字符则直接返回结果0。

  3. 在遇到正负号或者数字之后如果遇到再次遇到非数字的其他字符则直接跳出。

  4. 由题我们可以了解到我们的取值范围是[-2147483648,2147483647]。如果我们的结果超过了这个值则我们只需要判断结果的正负并输出边界值-21474836482147483647即可。

  5. 我们无法使用int来存储超过边界值的数字,那考虑到我们将String强转为Int时如果超出边界则会抛出异常,我们可以利用异常处理来解决数值过大或者过小的问题。

  6. 接下来看一下小编的解法,代码中包含了详细的注释

    public class Test {
        public static int myAtoi(String str) {
            int len = str.length(); // 字符串长度
            int bj = 0; // 用于标记是否已经遇到+/-
            int numBj = 0; // 用于标记是否已经遇到数字
            StringBuilder a = new StringBuilder(); // 用户存储结果字符
            for (int i = 0; i < len; i++) {
                char ch = str.charAt(i); // 定义一个char存放当前字符
                if (Character.isSpaceChar(ch)) { // 判断该字符是否为空格
                    if (numBj == 0 && bj == 0)
                        continue;
                    else break;
                } else if ("+".equals(ch + "") || "-".equals(ch + "")) { // 判断字符是否为+/-
                    if (bj == 0) { // 若在此之前没有遇到过+/-号
                        a.append(ch); // 添加到结果字符
                        bj++; // bj自增
                    } else {
                        break;
                    }
                } else if (Character.isDigit(ch)) { // 判断当前字符是否为数字
                    numBj++; // 数字numBj自增
                    bj++; // 符号bj自增
                    a.append(ch); // 将数字添加至结果字符
                } else
                    break;
            }
            // 以下利用String强转为int可能抛出的异常来处理结果范围问题
            try {
                if (a.length() == 0) { // 如果结果字符长度为0则返回数字0
                    return 0;
                } else if (a.length() == 1 && ("+".equals(a.charAt(0) + "") || "-".equals(a.charAt(0) + ""))) {
                    // 如果字符长度为1且仅包含+/-号则直接返回数字0
                    return 0;
                } else {
                    // 否则直接返回强转为int类型的数值。注意这里可能会抛出异常,所以我们在下方catch中进一步处理
                    return Integer.parseInt(String.valueOf(a));
                }
            } catch (Exception e) {
                // 判断是否为负数
                if ("-".equals(a.charAt(0) + "")) {
                    return -2147483648;
                }
                return 2147483647;
            }
        }
       
        public static void main(String[] args) {
            System.out.println(myAtoi("   - 321"));
        }
    }
       
    

    屏幕快照 2019-02-14 下午4.10.28

最后说两句

  1. 所有的题目都有很多种解法,我的一定不是最好的,甚至可以说是比较低端的解法,希望大牛们多多指教!!!
  2. 如果朋友们对算法、编程有很大兴趣的话,可以私信我,大家一同探讨;相互学习、共同进步。
  3. 朋友们如果对这道题目有更好的解法,希望可以在评论中指出,让大家一起讨论学习。
  4. 最后感谢大家的阅读以及关注,谢谢大家!!!