LeetCode No.8 String to Integer (atoi)

来源:互联网 发布:javascript array 编辑:程序博客网 时间:2024/06/06 11:00

我们都知道在C标准库里有这样一个函数叫atoi,它的参数是const char*,返回值是一个int;

那么在C++标准库里面有一个与之对应的函数叫做stoi,它接受的字符串参数类型变成了const string&;

LeetCode上面的这道题是这个函数的简化版本,这道题看起来简单,但是在实际编程中有很多细节需要处理(涉及Math的问题总是有很多细节需要处理!


一、题目及其分析

实现atoi函数,将字符串转换为其表示的整数(这里为int类型的整数)。

我们知道,涉及Math的问题总是有一些细节需要处理,而这些细节的类型其实也比较固定,对于这道题来说,首先考虑我们输入的字符串究竟是不是表示一个数?

  1. 我们给的字符串可以是这样子:"1234556", "-234", "+234.5", "0123", "0x34FF"等等,那么这些字符串很显然都表示一个数;但是给定的字符串也可以是这个样子:"fdad123",  "dhg", "    fds3454", "1232adf$%", "324   ",这些字符串中有的完全就不是代表数,有的其中有一部分代表数,这种情况我们如何处理?
  2. 如果我们给了一个代表超级大数字的字符串怎么办?比如:"12345566778898990",这个数字已经超出了int类型所能表示的最大范围!

起始处理这些情况的方式是我们自定义的,你可以让函数返回一个合理的值,或者干脆抛出异常~但是我们现在是在LeetCode上做题,必须按照LeetCode设计好的用例来设计我们的函数,那么经过测试了一些用例之后,我们就可以分析出LeetCode是要求我们怎样设计这个函数的~

  1. 我们只处理十进制表示的数字,也就是说我们默认字符串的内容表示了一个十进制的数;
  2. 对于带符号数,输出其带符号值,例如:"-123"输出-123,"+123"输出123,"123"输出123;
  3. 对于数字与其他字符混合出现的字符串,非法情况返回0,那么什么是非法情况呢:最先出现的是除了空格、正负号和数字之外的字符(这里注意小数点,小数点也是非法字符,我们只取小数点之前的数字);对于数字之前与之后的空格,一律跳过处理;对于数字之间的空格,只取第一个空格前的数字;对于数字之后的非法字符,只取数字;数字要连续取,比如:"123a345"应该输出123;
  4. 对于越界情况,输出界值,比如:"12344556787899909090"应该输出INT_MAX,负数同理;
二、算法分析

  1. 处理输入的字符串,确定其是否合法;合法则构建一个新的表示该合法值的字符串,否则返回0;
  2. 按位处理合法字符串,从低位(字符串的末尾)到高位(字符串的开头)依次计算对应的整数值,并将这些结果相加得到表示的数字(每次加上新的数字位时都要判断一下结果的符号是否发生了翻转,如果翻转则表示越界,直接返回界值);
三、代码
int myAtoi(string str){//数字对照表unordered_map digits ={{ '0', 0 },{ '1', 1 },{ '2', 2 },{ '3', 3 },{ '4', 4 },{ '5', 5 },{ '6', 6 },{ '7', 7 },{ '8', 8 },{ '9', 9 }};//处理空字符串if (str.empty()) return 0;//合法字符串起始标记unsigned i = 0;//跳过空格if (str[0] == ' ')while (str[i] == ' ') ++i;//跳过符号信息if (str[i] == '-') ++i;else if (str[i] == '+') ++i;//合法字符串结尾标记unsigned j = i;while (isdigit(str[j]) && str[j] != ' ' && j < str.size()) ++j;//字符串非法情况,返回0if (i == j) return 0;//处理表示负数的字符串,将符号信息加入到字符串中if (i > 0 && str[i - 1] == '-') --i;string integer = str.substr(i, j - i);int result = 0;//处理负数if (integer[0] == '-'){for (int i = integer.size() - 1; i > 0; --i){result -= digits[integer[i]] * (int)pow(10, integer.size() - 1 - i);//表示结果越界if (result > 0){result = INT_MIN;break;}}}//处理正数else{for (int i = integer.size() - 1; i >= 0; --i){result += digits[integer[i]] * (int)pow(10, integer.size() - 1 - i);//表示结果越界if (result < 0){result = INT_MAX;break;}}}return result;}

四、运行结果



原创粉丝点击