首页 新闻 会员 周边

应用递归函数,字符串转换为数字

0
悬赏园豆:5 [已解决问题] 解决于 2012-05-31 20:33

编写一个递归函数,把一个数字字符串转化为一个整数。函数原型为:void StringToInteger(char *str, int *number);,例如若字符串str = "12345",则调用函数后*number = 12345。。

c
半分微醉的主页 半分微醉 | 初学一级 | 园豆:60
提问于:2012-05-31 19:46
< >
分享
最佳答案
0

首先:因为你一定要用递归函数,按这个声明来实现,所以才有我给你的答案。但实际上这种递归实现是“多此一举,效率非常低下”的,这一点请务必注意。在实际应用中,这种需求可以通过atoi或者strtol一类的库函数/API实现。如果自己实现也一定不可能写成递归函数。。

可以给你两个版本,这两个版本都是考虑到第一个参数认为是const char*的情况,即不改动原来的字符串。

这是第一个版本:以下头文件酌情引用:

#include <math.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>

 

void StringToInteger(char* str, int* number)
{
    int len, temp = 0;
    if(str == NULL || (len = strlen(str)) == 0)
    {
        *number = 0;
        return;
    }
    if(len == 1)
    {
        *number = *str - '0';
        return;
    }
    StringToInteger(str + 1, &temp);
    *number = (*str - '0') * (int)pow(10, len - 1) + temp;
}

 

 

=================这是第二个版本================

version2
void StringToInteger(char* str, int* number)
{
    int len, temp = 0;
    if(str == NULL || (len = strlen(str)) == 0)
    {
        *number = 0;
        return;
    }
    if(len == 1)
    {
        *number = *str - '0';
        return;
    }
    char* substr = strdup(str);
    substr[len - 1] = 0;
    StringToInteger(substr, &temp);
    free(substr);
    *number = str[len - 1] - '0' + temp * 10;
}

 

测试代码:

int main(int argc, char* argv[])
{
 int n;
 char str[] = "12345";
 StringToInteger(str, &n);
 printf("n= %ld\n", n);
 return 0;
}

收获园豆:5
hoodlum1980 | 小虾三级 |园豆:559 | 2012-05-31 20:00

如果说第一个参数是可写的缓冲区,而且调用方不介意函数改动它,则下面的版本3是基于上面的版本2,但效率要好过版本2。

void StringToInteger(char* str, int* number)
{
    int len, temp = 0;
    if(str == NULL || (len = strlen(str)) == 0)
    {
        *number = 0;
        return;
    }
    if(len == 1)
    {
        *number = *str - '0';
        return;
    }
    *number = str[len - 1] - '0';
    str[len - 1] = 0;
    StringToInteger(str, &temp);
    *number += temp * 10;
}

但你调用的时候只能按照下面的方式:

char str[] = "12345";
 StringToInteger(str, &n);

 

而下面的调用是对版本3错误的(但对版本1和2可以):

StringToInteger("12345", &n);

 

如果你的函数定义形式可以改一下,增加一个参数的话,我认为下面的方式是比较好的。也无需改动第一个参数。那些判断比较我这里就去掉了。

void StringToInteger(const char* str, int* number, int len)
{    
    if(len == 1)
    {
        *number = *str - '0';
    }
    else
    {
        int temp;
        StringToInteger(str, &temp, len - 1);
        *number = str[len - 1] - '0' + temp * 10;
    }
}

可以这样调用:

 int n;

char* str = "12345";
 StringToInteger(str, &n, strlen(str));
 printf("n= %ld\n", n);

hoodlum1980 | 园豆:559 (小虾三级) | 2012-05-31 20:06

我不是打酱油的,而是个初学者,所以你说的大部分不懂,但给了我很大的启示,十分感谢!

半分微醉 | 园豆:60 (初学一级) | 2012-05-31 20:34

@半分微醉: 坑爹啊,留作业跑这抄答案来了。。。

我想我笑 | 园豆:202 (菜鸟二级) | 2012-06-03 18:59

@hoodlum1980: 哥们对于你写的这个程序我由衷的佩服,小弟还有一些疑惑,不知能否加个qq当面探讨一下qq919943272

我想我笑 | 园豆:202 (菜鸟二级) | 2012-06-04 17:24

他写的有很多很多余! 

半分微醉 | 园豆:60 (初学一级) | 2012-06-05 18:25

版本2 不调用strdup的版本。这样就不需要额外分配内存,当然缺点是变成和版本3一样,str必须可写。而不能是只读的字符串常量。

void StringToInteger(char* str, int* number)
{
    char ch;
    int len, temp = 0;
    if(str == NULL || (len = strlen(str)) == 0)
    {
        *number = 0;
        return;
    }
    if(len == 1)
    {
        *number = *str - '0';
        return;
    }
    ch = str[len - 1];
    str[len - 1] = 0;
    StringToInteger(substr, &temp);
    str[len - 1] = ch;
    *number = str[len - 1] - '0' + temp * 10;
}
hoodlum1980 | 园豆:559 (小虾三级) | 2013-05-05 01:25

最后我在给出一个从非递归函数,等效转换到递归函数的代码,这个我认为可能才是比较好的答案,因为前面都是从递归思维去做的,而这个代码是从最直观的的非递归函数转换到递归函数的思路去做的,所以它的代码比较简洁,而且也对第一个参数str是否可写没有要求。

#include <string.h>
#include <stdio.h>
void StringToInteger(char *str, int *number)
{
    static int base;
    if(*str == 0)
    {
        base = 1;
        *number = 0;
    }
    else
    {
        StringToInteger(str + 1, number);
        *number += (*str - '0') * base;
        base *= 10;
    }
}
int main(int argc, char* argv[])
{
    int number;
    StringToInteger("56789", &number);
    printf("number = %ld\n", number);
    return 0;
}

 

这个版本将比以上所有“递归思维”得到的解法从代码上看更好,但是不太直观,所以理解起来不如前面那些版本代码容易。

hoodlum1980 | 园豆:559 (小虾三级) | 2013-05-05 01:39

如果题目不对递归函数的声明做要求,则可以不用 static 变量,而是把base这个值用指针进行传递,则代码如下:

01  int StrToInt(char *str, int *base)
02  {
03      if(str[1] == 0)
04      {
05          *base = 1;
06          return *str - '0';
07      }
08      else
09      {
10          int tmp = StrToInt(str + 1, base);
11          *base *= 10;
12          return (*str - '0') * (*base) + tmp;
13      }
14  }
15 
16  int main(int argc, char* argv[])
17  {
18      int number, base;
19      number = StrToInt("12345", &base);
20      printf("number = %ld\n", number);
21      return 0;
22  }
hoodlum1980 | 园豆:559 (小虾三级) | 2013-05-05 19:25
其他回答(1)
0

尼玛成少雷的学生吧。。。

我想我笑 | 园豆:202 (菜鸟二级) | 2012-06-03 18:55

尼亚丫的不是!

支持(0) 反对(0) 半分微醉 | 园豆:60 (初学一级) | 2012-06-05 18:22

@半分微醉: 你呀的就是,我这正做着c语言呢,上网查查资料,正好发现和我遇到的问题一样,我这还感叹呢,真巧啊,真巧啊,真巧啊,真巧...越看这题越眼熟,再一对,尼玛坑爹啊,连最后标点两个句号都一样,这不是坑我吗,还有我雷哥...

支持(0) 反对(0) 我想我笑 | 园豆:202 (菜鸟二级) | 2012-06-05 20:16

@我想我笑:我说不是就不是。 有点大脑好不好,这么大的学校,那就非得是成少雷的学生吗?

还有,我怎么坑你和你雷哥了。

神马呀!

支持(0) 反对(0) 半分微醉 | 园豆:60 (初学一级) | 2012-06-06 10:38
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册