在一次传递中从字符串解析int的算法

时间:2015-02-11 06:31:24

标签: c algorithm parsing

我正在尝试编写一个从字符串表示中解析整数的函数。

我的问题是我不知道如何通过一次通过字符串来做到这一点。如果我提前知道输入只包含'0''1',...,'9'范围内的字符,并且该字符串的长度为n,那么我当然可以计算

character_1 * 10^(n-1) + character_2 * 10^(n-2) + .... + character_n * 10^0 

但我想处理一般场景,因为我已经提出过了。

我不是在寻找库函数,而是在“纯C”中实现此功能的算法。

这是我开始的代码:

int parse_int (const char * c1, const char * c2, int * i)
{
    /*
        [c1, c2]: Range of characters in the string
               i: Integer whose string representnation will be converted

        Returns the number of characters parsed. 

        Exs. "2342kjsd32" returns 4, since the first 4 characters were parsed.
             "hhsd3b23" returns 0
    */

    int n = 0;
    *i = 0;
    while (c1!= c2)
    {
        char c = *c1;
        if (c >= '0' && c <= '9')
        {

        }
    }
    return n;
}

3 个答案:

答案 0 :(得分:0)

正如一些评论和答案所暗示的那样,可能更清楚一点:你必须&#34;转移&#34;结果&#34;离开&#34;在添加新数字之前,在每次迭代中将其乘以10。

确实,这应该提醒我们Horner's method。如您所知,结果可以写成多项式:

result = c1 * 10^(n-1) + c2 * 10^(n-2) + ... + cn * 10^0 

这个等式可以改写为:

result = cn + 10*(... + 10*(c2 + 10*c1))

这种方法的基础是什么。从你已经看到的公式中,你不需要知道第一个数字的10的幂,直接从一开始就乘以。

以下是一个例子:

#include <stdio.h>

int parse_int(const char * begin, const char * end, int * result) {
    int d = 0;
    for (*result = 0; begin != end; d++, begin++) {
        int digit = *begin - '0';
        if (digit >= 0 && digit < 10) {
            *result *= 10;
            *result += digit;
        }
        else break;
    }
    return d;
}

int main() {
    char arr[] = "2342kjsd32";
    int result;
    int ndigits = parse_int(arr, arr+sizeof(arr), &result);
    printf("%d digits parsed, got: %d\n", ndigits, result);
    return 0;
}

使用sscanf()可以实现同样的目的,对于每个使用C标准库的人来说都很好(也可以处理负数):

#include <stdio.h>

int main() {
    char arr[] = "2342kjsd32";
    int result, ndigits;
    sscanf(arr, "%d%n", &result, &ndigits);
    printf("%d digits parsed, got: %d\n", ndigits, result);
    return 0;
}

输出是(两个实现):

$ gcc test.c && ./a.out
4 digits parsed, got: 2342

答案 1 :(得分:-1)

我认为这是计算解析字符的好方法

int parse(char *str)
{
    int k = 0;
    while(*str)
    {
        if((*str >= '0') & (*str <= '9'))
            break;
        str++;
        k++;
    }
    return k;
}

答案 2 :(得分:-2)

这是一个有效的版本:

#include <stdio.h>

int parse_int (const char * c1, const char * c2, int * i)
{
   /*
      [c1, c2]: Range of characters in the string
             i: Integer whose string representnation will be converted

      Returns the number of characters parsed. 

      Exs. "2342kjsd32" returns 4, since the first 4 characters were parsed.
      "hhsd3b23" returns 0
    */

   int n = 0;
   *i = 0;
   for (; c1 != c2; c1++)
   {
      char c = *c1;
      if (c >= '0' && c <= '9')
      {
         ++n;
         *i = *i * 10 + c - '0';
      }
      else
      {
         break;
      }
   }

   return n;
}

int main()
{
   int i;
   char const* c1 = "2342kjsd32";
   int n = parse_int(c1, c1+10, &i);
   printf("n: %d, i: %d\n", n, i);
   return 0;
}

输出:

n: 4, i: 2342