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)アルゴリズムを実現しようとしています。誰かが私にもっと良い方法を教えてもらえますか?また、静的変数は必要ないと思いますが、それを回避する方法がよくわかりません。静的変数を回避するために、関数を2つに分割する必要がありますか?

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はvoidを返す必要があります。
私はこれをテストしていませんが、うまくいくと思います。
静的変数、ヘルパー関数、追加の引数はありません。
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

1つの小さな問題ですが素晴らしい解決策。n==0このコードは、再帰の基本ケースであるwhenが適切に処理されないため、セグメンテーション違反を受け取ります。私はあなたのプログラムに小さな変更を加えました、そして今それはうまくいきます。

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);
}
于 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 に答える