itoa递归

时间:2010-01-03 01:15:05

标签: c recursion itoa

我一直在尝试编写函数itoa递归版本,代码如下所示。

void itoa(int n, char s[])
{
     static int i = 0;

     if(n / 10 != 0)
         itoa(n/10, s);
     else if(n < 0)
         i = 1; /* s[0] is allready taken by - sign */
     else 
         i = 0; /* reset i to 0 */

     if(n < 0) {
          s[0] = '-';
     }

     s[i++] = abs(n % 10) + '0';
     s[i] = '\0';
}

但代码并不理想。它使用static变量,可能没有尽可能快地执行。我正在尝试实现 O(n)算法。有人能告诉我一个更好的方法吗?我也认为静态变量不是必需的,但我不确定如何避免它。我应该将函数分解为两个以避免静态变量吗?

4 个答案:

答案 0 :(得分:3)

如果要以递归方式解决它,更简单的方法可能是返回最后一个索引:

int itoa(int n, char s[])
{
    int i =  0;         

    if(n / 10 != 0)
        i = itoa(n/10, s);
    else if(n < 0)
        s[i++] = '-';

    s[i++] = abs(n % 10) + '0';
    s[i] = '\0';

    return i;
}

您也可以使用指针解决它:

char * itoa(int n, char * s)
{
    char * dest = s;

    if(n / 10 != 0)
        dest = itoa(n/10, dest);
    else if(n < 0)
        *dest++ = '-';

    *dest++ = abs(n % 10) + '0';
    *dest = '\0';

    return dest;
}

但是需要注意的是,这种实现容易出现缓冲区溢出。您需要确定已分配足够大的缓冲区以适合整数的整个ascii表示。一个好主意是包括一些边界检查。

答案 1 :(得分:2)

itoa应该返回无效 我没有对此进行测试,但我相信它会起作用 没有静态变量,没有辅助函数,没有额外的参数 while循环中的冗余整数除法可能是一个弱点。

void itoa(int n, char *s)  
{  
    char c;  
    if (n < 0)  
    {  
        *s++ = '-';  
        itoa(-n, s);  
        return;  
    }  
    c = '0' + n % 10;  
    itoa(n / 10, s);  
    while ( n /= 10 ) s++;  
    *s++ = c;  
    *s = '\0';  
}  

答案 2 :(得分:1)

char* itoa(int n, char s[]) {
  if (n < 0) {
    s[0] = '-';
    return itoa(-n, s+1);
  }
  if (n/10 > 0) {
     s = itoa(n/10, s);
  }
  s[0] = '0' + (n%10);
  s[1] = '\0';
  return &s[1];
}

您还具有itoa返回字符串结尾地址的功能。

答案 3 :(得分:1)

虽然有一个小问题,但仍有惊人的解此代码接收分段错误,因为递归的基本情况:n==0未正确处理时。我对你的程序进行了一些小改动,现在它工作正常。

void itoa(int n,char *s)
{
    char c;
    if (n < 0)
    {
        *s++ = '-';
        itoa(-n, s);
        return;
    }
    if (n==0)
        return;
    c = '0' + n % 10;
    itoa(n/10,s);
    while ( n /= 10 ) s++;
    *s++ = c;
    *s = '\0';
}

现在,对于我自己的2便士,我解决了这个问题而不使用除法,而是使用双指针使值在函数调用之间保持不变。

我的解决方案的唯一缺点是我们需要保留字符数组的起始地址。

void itoa(char**a,int i)
{
    int dig;
    if(i<10) //base case;
    {
        **a=i+48;
        *(++(*a))='\0';
        return;
    }
    dig=i%10;
    itoa(a,i/10);
    **a=dig+48;  //char value + 48 will give me the corresponding value
    *(++(*a))='\0';
    return;
}

int main()
{
    char* t=(char*)malloc(sizeof(char)*5);
    char* save=t;
    int ti=1234;
    itoa(&t,ti);
    printf("%s",save);
}