力扣 题目08-字符串转换整数 心得
-
题目
-
题解
吐槽一下:这题规则过多云里雾里的 耽误了不少时间 怪不得有人说面向实例编程
-
我们可以翻译一下规则
-
1.读入字符串并丢弃无用的前导空格=去掉字符串开头的空格
-
2.检查下一个字符(假设还未到字符末尾)为正还是负号,读取该字符(如果有)。 确定最终结果是负数还是正数。 如果两者都不存在,则假定结果为正。
-
=如果数字前面有负号则输出为负数 如果有正号则为正 都没有输出为正
-
3.读入下一个字符,直到到达下一个非数字字符或到达输入的结尾。字符串的其余部分将被忽略。=从数字开始到数字结束 如果中间被字母或者其他符号隔开只取上部分
-
4.将前面步骤读入的这些数字转换为整数(即,"123" -> 123, "0032" -> 32)。如果没有读入数字,则整数为 0 。必要时更改符号(从步骤 2 开始)。
-
=没有数字则为0 而且数字前面也不能有其他符号 除了规则二(也不能出现 +-在一起的情况)
-
5.如果整数数超过 32 位有符号整数范围 [−231, 231 − 1] ,需要截断这个整数,使其保持在这个范围内。具体来说,小于 −231 的整数应该被固定为 −231 ,大于 231 − 1 的整数应该被固定为 231 − 1 。=超过int类型界限时输出对应的界限
-
6.返回整数作为最终结果。
-
我们一条一条来写代码
-
1.去掉字符串开头的空格 创建一个新的字符串 使用一个循环
-
把在找到第一个非空格字符之后把剩下的字符串放入这个新字符串(空格的ASCII码值是32)
-
string quspace = ""; bool kong = true; int i = 0; for (int i = 0; i < s.length(); i++) { if (s[i] != 32) { kong = false; } if (!kong) { quspace = quspace + s[i]; } }
2.其实我们可以写下几个不为0的字符串
-
比如 123 -123 456 +456
-
可以看见开头没有字母 所以第一层判断先筛选开头字母(同样利用ASCll码值 48-57 是0-9 43是+ 45是-)
-
if ((quspace[0] > 47 && quspace[0] < 58)|| quspace[0]== 43|| quspace[0] == 45)
{
}
else { return 0; } -
3.正负问题 先判断第一位是符号还是数字然后再判断是正还是负(fu是正负号 i是如果第一位是符合 那么数字要从第二位开始)
-
if (quspace[0] == 43) { fu = 1; i = 1; }
if (quspace[0] == 45) { fu = -1; i = 1; } -
4.我们找到第一个数字然后向后遍历碰到非数字断开循环即可
-
for (; quspace[i] > 47 && quspace[i] < 58;i++) {}
5.不能出现 ++ -- +-这种 可以使用上方代码解决
-
6.界限问题 正好在上一题中有这样的问题于是我想着可以直接借过来用 结果出现了问题 原因是 INT_MAX / 10 之后精确度降低
-
在INT_MAX附近的值被判断返回最大值或者最小值(比如 2147483648 2147483647 -2147483648 它们/10后与INT_MAX / 10 一样) 这时我们应该更加精确的判断
-
比较它们的个位数
-
if (add * fu > INT_MAX / 10 || (add == INT_MAX / 10 && (quspace[i] - 48) > (INT_MAX % 10))) { return INT_MAX; } if (add* fu < INT_MIN/10 || (add == INT_MIN / 10 && (quspace[i] - 48) > -(INT_MIN % 10))) { return INT_MIN; }
-
7.数字的加法(这里可以参考上一题)
-
add = add * 10 + (quspace[i] - 48);
-
完整代码
-
#include<iostream> using namespace std; class Solution { public: int myAtoi(string s) { string quspace = ""; bool kong = true; int add = 0; int fu = 1; int i = 0; for (int i = 0; i < s.length(); i++) { if (s[i] != 32) { kong = false; } if (!kong) { quspace = quspace + s[i]; } } if ((quspace[0] > 47 && quspace[0] < 58)|| quspace[0]== 43|| quspace[0] == 45) { if (quspace[0] == 43) { fu = 1; i = 1; }if (quspace[0] == 45) { fu = -1; i = 1; } for (; quspace[i] > 47 && quspace[i] < 58;i++) { if (add * fu > INT_MAX / 10 || (add == INT_MAX / 10 && (quspace[i] - 48) > (INT_MAX % 10))) { return INT_MAX; } if (add* fu < INT_MIN/10 || (add == INT_MIN / 10 && (quspace[i] - 48) > -(INT_MIN % 10))) { return INT_MIN; } add = add * 10 + (quspace[i] - 48); } } else { return 0; } return add*fu; } }; int main() { Solution sol; string zifu = "-2147483648"; int shu = sol.myAtoi(zifu); cout << shu; }
-
心得
说实话这题真的是规则过于复制 我中间还直接用了
atoi
函数 后来才明白不能用