【问题标题】:Algorithm to parse an int from a string in one pass一次从字符串中解析 int 的算法
【发布时间】:2015-02-11 06:31:23
【问题描述】:

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

我的问题是我不知道如何通过字符串来做到这一点。如果我提前知道输入只包含'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;
}

【问题讨论】:

  • inside if 条件n = n*10 + (c-'0');
  • Pure C, so no libraries 是否包括忽略标准库?
  • @Lashane 那行不通。例如,如果字符串是“123”,那么它将被计算为 1+20+300=321。
  • 这似乎是一个“请为我编写代码”的问题......坦率地说,看起来有问题的代码是别人提供的骨架,你应该填写它...如果是您自己的代码,那么请继续编码,并在您遇到实际问题或错误时询问。当前代码只是不完整,它似乎没有实际问题!
  • @SteveBallmer 它工作。在“123”上,第一次迭代是*i = 0*10 + ('1' - '0'),这是1;第二次迭代将是 *i = 1*10 + ('2' - '0'),这使得 12;第三次迭代将是*i = 12*10 + ('3' - '0'),最终结果是123。

标签: c algorithm parsing


【解决方案1】:

正如一些 cmets 和答案所建议的那样,可能更清楚一点:在添加新数字之前,您必须在每次迭代中将结果“左移”,方法是将其乘以 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

【讨论】:

    【解决方案2】:

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

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

    【讨论】:

      【解决方案3】:

      这是一个工作版本:

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

      输出:

      号码:4,我:2342

      【讨论】:

      • 我不明白反对票的原因。我误解了这个问题吗?
      猜你喜欢
      • 1970-01-01
      • 2016-06-29
      • 1970-01-01
      • 2017-09-26
      • 2011-05-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-10
      相关资源
      最近更新 更多