1

我一直在尝试编写函数的递归版本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

4 回答 4

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 表示。一个好主意是包括一些边界检查。

于 2010-01-03T01:33:01.483 回答
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';  
}  
于 2010-10-15T04:16:13.667 回答
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';
}

现在为了我自己的两便士,我没有使用除法而是使用双指针来解决这个问题,以便在函数调用之间保持值。

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

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);
}
于 2011-09-18T15:20:31.263 回答
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 返回字符串结尾地址的功能。

于 2010-01-03T01:35:34.283 回答