简体   繁体   English

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

[英]How do you implement your own string to integer conversion

So I want to take a string in such as 8302 and convert this into an integer by creating my own function and not using the stoi/atoi functions.所以我想通过创建我自己的函数而不使用 stoi/atoi 函数来获取一个字符串,例如 8302 并将其转换为整数。

I tried so far by doing:到目前为止,我尝试过:

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

I know i need to keep multiplying by 10 everytime i find an integer so i can increase it eg 123 = 1*10*10+2*10+3.我知道每次找到一个整数时我都需要乘以 10,这样我就可以增加它,例如 123 = 1*10*10+2*10+3。 but i dont know how to code this.但我不知道如何编码。 could anyone suggest a method?有人可以建议一种方法吗?

It might be easiest to do it in a recursive manner.以递归方式执行此操作可能最容易。 Use the following idea:使用以下想法:

8302 = 830 * 10 + 2

That is:那是:

  1. If there is only one char in the string - return it;如果字符串中只有一个char - 返回它; otherwise continue否则继续
  2. Separate the last char in the string分隔字符串中的最后一个char
  3. Convert the string (without the last char) to integer - using recursion将字符串(没有最后一个字符)转换为整数 - 使用递归
  4. Multiply by 10 and add the last char乘以 10 并添加最后一个char

There are a lot of details here:这里有很多细节:

  • how to convert 1 char to an integer?如何将1个char转换为整数? - subtract '0' from it - 从中减去'0'
  • how to separate a char from the rest of the string?如何将char与字符串的其余部分分开? - use substr - 使用substr
  • when you have a working recursive solution, you might want to convert it to an iterative solution - this will make it faster, but maybe less readable当您有一个有效的递归解决方案时,您可能希望将其转换为迭代解决方案 - 这将使其更快,但可能不太可读
  • what to do with invalid strings like "aaa" or "123haha" - my algorithm doesn't handle that如何处理诸如"aaa""123haha"类的无效字符串 - 我的算法无法处理

Before you could define a char2int conversion:在定义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");
  }
}

And use it:并使用它:

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");
    }
  }
}

This one is very close to your attempt:这与您的尝试非常接近:

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;
}

The only assumption is that the characters '0' to '9' lie directly next to each other in the character set.唯一的假设是字符'0''9'在字符集中彼此直接相邻。 The if statement makes sure that we stop at non-digit characters. if语句确保我们在非数字字符处停止。 The digit-characters are converted to their integer value using c-'0' .使用c-'0'将数字字符转换为其整数值。

Please keep in mind that this only parses the first digits of a string.请记住,这只会解析字符串的第一个数字。 Strings that start with a sign + or - are not considered.不考虑以符号+-开头的字符串。

A good way is to find your first digit and go from there make a multiplayer variable and multiply it by ten every digit.一个好方法是找到您的第一个数字,然后从那里创建一个多人游戏变量,然后将每个数字乘以 10。 for every char you add you have to subtract '0' from it as '0' is not equal to int 0.对于您添加的每个字符,您必须从中减去“0”,因为“0”不等于 int 0。

example:例子:

 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;
 }

It is much better that you start your conversion from right to left.从右到左开始转换会好得多。

So you will iterate your string starting from its end, and ending on its beginning.因此,您将从字符串的末尾开始迭代您的字符串,并在其开头结束。 On each iteration, we will take the character, convert it to int and multiply it with its multiplier (its position in the result integer) and then add it to the final result.在每次迭代中,我们将获取字符,将其转换为 int 并将其与其multiplier (其在结果整数中的位置) multiplier ,然后将其添加到最终结果中。

This should work:这应该有效:

#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;
}
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 来源

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM