我一直在尝试编写函数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)算法。有人能告诉我一个更好的方法吗?我也认为静态变量不是必需的,但我不确定如何避免它。我应该将函数分解为两个以避免静态变量吗?
答案 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);
}