質問

私は、関数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 INORDERに機能を分割すべきか?

役に立ちましたか?

解決

あなたは再帰的にそれを解決したい場合は、

は、より簡単なアプローチは、最後のインデックスを返すようになります。

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表現に合わせて十分な大きさのバッファが割り当てられていることを確信する必要があります。良いアイデアは、いくつかの境界チェックが含まれるようになります。

他のヒント

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';  
}  
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は、文字列の末尾のアドレスを返すという特徴を持っています。

アメージングソリューションしかし一つの小さな問題。このコードは、再帰のベースケースので、セグメンテーション違反を受け取り: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);
}
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top