• 剑指offer(C++)-JZ67:把字符串转换成整数atoi(算法-模拟)


    作者:翟天保Steven
    版权声明:著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处

    题目描述:

    写一个函数 StrToInt,实现把字符串转换成整数这个功能。不能使用 atoi 或者其他类似的库函数。传入的字符串可能有以下部分组成:

    1.若干空格

    2.(可选)一个符号字符('+' 或 '-')

    3. 数字,字母,符号,空格组成的字符串表达式

    4. 若干空格

    转换算法如下:
    1.去掉无用的前导空格
    2.第一个非空字符为+或者-号时,作为该整数的正负号,如果没有符号,默认为正数
    3.判断整数的有效部分:
    3.1 确定符号位之后,与之后面尽可能多的连续数字组合起来成为有效整数数字,如果没有有效的整数部分,那么直接返回0
    3.2 将字符串前面的整数部分取出,后面可能会存在存在多余的字符(字母,符号,空格等),这些字符可以被忽略,它们对于函数不应该造成影响
    3.3  整数超过 32 位有符号整数范围 [−231,  231 − 1] ,需要截断这个整数,使其保持在这个范围内。具体来说,小于 −231的整数应该被调整为 −231 ,大于 231 − 1 的整数应该被调整为 231 − 1
    4.去掉无用的后导空格

    数据范围:

    1.0 <=字符串长度<= 100

    2.字符串由英文字母(大写和小写)、数字(0-9)、' '、'+'、'-' 和 '.' 组成

    示例:

    输入:

    "4396 clearlove"
    

    返回值:

    4396
    

    说明:

    6后面的字符不属于有效的整数部分,去除,但是返回前面提取的有效部分

    解题思路:

    本题考察算法场景模拟。两种解题思路。

    1)遍历法

           首先过滤前置空格;再判断正负号;之后判断连续数字,过程中注意正负极限判断;每找到一个新数字,就把之前的数字*10再累加上去,遍历完即可得到答案。复杂度O(n)。

    2)状态机

           基于状态转移矩阵对字符串遍历过程的状态进行分析。

           状态分为4种,空格、符号、数字和无效,对应0123,根据题目条件设立矩阵如下:

    \begin{bmatrix} 0 & 1 & 2 & 3\\ 3 & 3& 2 & 3\\ 3& 3& 2 & 3 \end{bmatrix}

    1. 起始状态为0,分析第一行:如果碰到空格,那下一个状态还是0;如果碰到符号,则状态转为1;如果碰到数字,则状态转为2;如果碰到无效字符,状态转为3。
    2. 假设状态转为1,分析第二行:如果碰到空格,即+空格,则无效,因此第二行第一列为3;如果又碰到符号,例如+-,也无效,所以第二行第二列为3;如果碰到数字,例如-3,则状态转为2;碰到无效字符状态转为3。
    3. 假设状态转为2,分析第三行:如果碰到空格,例如+8空格或者8空格,后续均无效,因此第三行第一列为3;如果碰到符号,例如+8+或者8+,后续也是均无效,因此第三行第二列为3;如果碰到数字,例如+89或者89,则后续是有效的,因此第三行第三列为2;无效字符同理无效。
    4. 当状态为2时,对数字进行累加和越界判断;当状态为3时,break退出即可。

           总的来说,状态机就是基于题目要求,将可能发生的情形和状态的转变,以矩阵形式表示,进而解题。复杂度O(n)。

    测试代码:

    1)遍历法

    1. #include <climits>
    2. class Solution {
    3. public:
    4. // 字符串转为整数
    5. int StrToInt(string s) {
    6. int sign = 1;
    7. int idx = 0;
    8. int size = int(s.size());
    9. // 前空格过滤,过滤完如果没有后续则退出
    10. while(idx < size){
    11. if(s[idx] == ' ')
    12. idx++;
    13. else
    14. break;
    15. }
    16. if(idx == size)
    17. return 0;
    18. // 判断符号,如果没有后续则退出
    19. if(s[idx] == '+')
    20. idx++;
    21. else if(s[idx] == '-'){
    22. idx++;
    23. sign = -1;
    24. }
    25. if(idx == size)
    26. return 0;
    27. // 继续遍历寻找目标数字
    28. int result = 0;
    29. while(idx < size){
    30. // 遇到非数字退出
    31. if(s[idx] < '0' || s[idx] > '9')
    32. break;
    33. // 判断极限
    34. if(result > INT_MAX / 10 || (result == INT_MAX / 10 && (s[idx] - '0') >= (INT_MAX % 10)))
    35. return INT_MAX;
    36. if(result < INT_MIN / 10 || (result == INT_MIN / 10 && (s[idx] - '0') >= -(INT_MIN % 10)))
    37. return INT_MIN;
    38. // 字符转为数字
    39. result = result * 10 + sign * (s[idx] - '0');
    40. idx++;
    41. }
    42. return result;
    43. }
    44. };

    2)状态机

    1. class Solution {
    2. public:
    3. // 字符串转为整数
    4. int StrToInt(string s) {
    5. // 状态转移矩阵
    6. vector<vector<int>> states = {
    7. {0,1,2,3},
    8. {3,3,2,3},
    9. {3,3,2,3},
    10. };
    11. // 定义
    12. long result = 0;
    13. long top = INT_MAX;
    14. long bottom = INT_MIN;
    15. int sign = 1;
    16. int size = int(s.length());
    17. // 状态从0开始
    18. int state = 0;
    19. for(int i = 0; i < size; ++i){
    20. // 空格
    21. if(s[i] == ' '){
    22. state = states[state][0];
    23. }
    24. // 正负号
    25. else if(s[i] == '-' || s[i] == '+'){
    26. state = states[state][1];
    27. if(state == 1){
    28. sign = (s[i] == '-') ? -1 : 1;
    29. }
    30. }
    31. // 数字
    32. else if(s[i] >= '0' && s[i] <= '9'){
    33. state = states[state][2];
    34. }
    35. // 非法字符
    36. else{
    37. state = states[state][3];
    38. }
    39. // 状态为2时,表明在连续数字状态,进行数字累加
    40. if(state == 2){
    41. // 数字相加
    42. result = result * 10 + s[i] - '0';
    43. // 越界处理
    44. result = (sign == 1) ? min(result, top) : min(result, -bottom);
    45. }
    46. // 状态为3时,说明后续无效,退出即可
    47. else if(state == 3)
    48. break;
    49. }
    50. return (int)sign * result;
    51. }
    52. };

  • 相关阅读:
    为什么通过CRM软件系统能更好的跟进客户
    Degrade is Upgrade: Learning Degradation for Low-light Image Enhancement论文阅读笔记
    contentDocument contentWindow,canvas 、svg,iframe
    easyscholar配置秘钥连接Zotero-style,更方便的了解文献!
    基于django的在线教育系统
    搭建 AI 图像生成器 (SAAS) php laravel
    【Unity3D】反射和折射
    如何在SOLIDWORKS中更改单位-硕迪科技
    【NOWCODER】- Python:运算符(一)
    java-php-net-python-绥化市北林区房屋拆迁管理信息管理系统计算机毕业设计程序
  • 原文地址:https://blog.csdn.net/zhaitianbao/article/details/132844648