你如何实现自己的字符串到整数的转换

Posted

技术标签:

【中文标题】你如何实现自己的字符串到整数的转换【英文标题】:How do you implement your own string to integer conversion 【发布时间】:2016-09-27 12:25:04 【问题描述】:

所以我想通过创建自己的函数而不是使用 stoi/atoi 函数来获取一个字符串,例如 8302 并将其转换为整数。

到目前为止,我尝试过这样做:

int stringToInt(string input)

    int i = 0;
    while(input[i] >= '0' && input[i] <= '9')
    
        input[i] = input[i] * 10 + ......
        i++;
    
return i;

我知道每次找到一个整数时我都需要继续乘以 10,这样我就可以增加它,例如 123 = 1*10*10+2*10+3。但我不知道如何编码。任何人都可以提出一种方法吗?

【问题讨论】:

为什么要将字符串中的每个 ASCII 字符值乘以 10? 您不应该对字符串索引和累加器使用相同的变量。为累加器使用单独的变量。 您返回的是索引而不是转换后的数字。此外,您不会检查字符串的结尾。 @FirstStep 这是一个名为 awesomelipsis 的 c++17 功能。可变参数模板的扩展,它为您自动完成整个程序。只需粘贴到堆栈溢出中。 @FirstStep 看到了吗?已经有 6 个答案:) 【参考方案1】:

以递归方式执行它可能是最简单的。使用以下思路:

8302 = 830 * 10 + 2

即:

    如果字符串中只有一个char - 返回它;否则继续 分隔字符串中的最后一个char 将字符串(没有最后一个字符)转换为整数 - 使用递归 乘以 10 并加上最后一个 char

这里有很多细节:

如何将 1 char 转换为整数? - 从中减去'0' 如何将char 与字符串的其余部分分开? - 使用substr 当您有一个有效的递归解决方案时,您可能希望将其转换为迭代解决方案 - 这会使其更快,但可能不太可读 如何处理 "aaa""123haha" 等无效字符串 - 我的算法无法处理此问题

【讨论】:

OP 应该考虑的其他点:处理负数。湾。如果第 4 步会溢出他的累加器该怎么办(关于如何在不触发溢出的情况下检测到这一点有一些有趣的问题)。 C。结合后两者:在不触发溢出的情况下处理最负数的条目。 我认为这些考虑主要是针对其他可能在未来阅读本文的人; OP提到了“stoi/atoi”,所以他似乎并不关心这些事情,就像atoi doesn't care【参考方案2】:

在您可以定义 char2int 转换之前:

inline int ctoi(char c) 
  switch (c) 
    case '0':
      return 0;
    case '1':
      return 1;
    case '2':
      return 2;
    case '3':
      return 3;
    case '4':
      return 4;
    case '5':
      return 5;
    case '6':
      return 6;
    case '7':
      return 7;
    case '8':
      return 8;
    case '9':
      return 9;
    default:
      throw std::runtime_error("Invalid char conversion");
  

并使用它:

int my_stoi_dec(const std::string& str) 
  int rtn = 0;
  int exp = 1;
  for (auto cp = str.crbegin(); cp != str.crend(); ++cp) 
    char c = *cp;
    if (isdigit(c)) 
      rtn +=  ctoi(c) * exp;
      exp *= 10;
     else if (c == '+') 
      return rtn;
     else if (c == '-') 
      return rtn * -1;
     else 
      throw std::runtime_error("Integer error conversion");
    
  

【讨论】:

你不应该使用幻数。这使得代码不可移植。 @NathanOliver 更好? 是的。这是迄今为止最完整的答案。它不处理下溢/溢出,但我不会对此投反对票。【参考方案3】:

这个非常接近你的尝试:

int toInt(const std::string& input)

  int i = 0;
  for (const auto c : input)
  
    if (c < '0' || c > '9')
      break;
    i = i*10 + c-'0';
  
  return i;

唯一的假设是字符'0''9' 在字符集中直接相邻。 if 语句确保我们在非数字字符处停止。使用c-'0' 将数字字符转换为其整数值。

请记住,这只解析字符串的前几位。不考虑以符号 +- 开头的字符串。

【讨论】:

这是尽可能干净的。您应该在答案中添加解释,因为它似乎最适合按原样使用。【参考方案4】:

一个好方法是找到你的第一个数字,然后从那里开始创建一个多人游戏变量,然后将每个数字乘以十。对于您添加的每个字符,您必须从中减去“0”,因为“0”不等于 int 0。

示例:

 string s = "12346";
 int multiplayer = 1;
 int i = 0;

 int result = 0;

 while (s[i] >= '0' && s[i] <= '9')
 ++i;

--i;
for(i ; i >= 0 ; --i)
   result += (s[i] - '0') * multiplayer;
   multiplayer *= 10;
 

【讨论】:

【参考方案5】:

最好从右到左开始转换。

因此,您将从字符串的末尾开始迭代字符串,并在其开头结束。在每次迭代中,我们将获取字符,将其转换为 int 并乘以它的 multiplier(它在结果整数中的位置),然后将其添加到最终结果中。

这应该可行:

#include <iostream>
#include <string>

int stringToInt(std::string input)

    int result = 0;
    int multiplier = 1;

    for (int i = input.length() - 1; i >= 0; i--) // start from right
    
        if (input[i] - '0' < 0 || input[i] - '0' > 9) // if any character is not an integer, return maximum negative
        
            result = INT16_MIN;
            break;
        

        result += (input[i] - '0') * multiplier; // convert to int, get its position and then add it to result.
        multiplier *= 10; // get next position
    

    return result;


int main()

    std::string MyEx = "123456";
    int MyInt = stringToInt(MyEx);

    std::cout << MyInt;

    return 0;

【讨论】:

从操作码和检查,不能保证所有字符串项都是数字 @HumamHelfawi OP 没有说明这一点。根据他的示例输入,不清楚其中一个字符可能不是整数。我还是添加了它,感谢您指出它。【参考方案6】:
void enforce( bool b ) 
    if ( !b ) 
        throw std::range_error("Not a valid string to convert to integer");
    


int stringToInt(std::string) 
    for ( std::size_t i( 0 ); i != ( last - first ); ++i ) 
        enforce( ( '0' <= first[ i ] ) && ( first[ i ] <= '9' ) );
        result += pow(10,i) * ( first[ i ] - '0' );
    

Source

【讨论】:

10^i 没有做你认为的事情。

以上是关于你如何实现自己的字符串到整数的转换的主要内容,如果未能解决你的问题,请参考以下文章

IEnumerable 类型如何转换成IQueryable类型

输入一个表示整数的字符串,把该字符串转换成整数并输出(实现atoi函数功能)

字符串转化为整数

在C语言中的各种赋值是如何转换的?

c语言如何实现16进制字符串转换为 base64

在delphi中如何实现将剪贴板中的多行字符串中间加上逗号?