所以长度:
int test1 = 1
长1个字符
int test2 = 37
长2个字符
int test3 = 82342
长5个字符。
我可以使用以下命令找到这些int的字符长度:
int character_len = floor(log10(abs(whatever_vairable_here))) + 1;
我想一直计数int i = 1;
到n
,但是在示例代码中,我只使用了20
)。有没有一种方法可以计算出我将要使用的字符总数,而无需使用第一个while循环来确定必须分配的大小。我正在尝试找出malloc
int total_characters_needed = 0;
int i = 1;
while (i <= 20) {
total_characters_needed += floor(log10(abs(i))) + 1;`
i++;
}
char *my_numbers_as_a_string = malloc(sizeof(char) * total_characters_needed);
i = 1;
while (i <= 20) {
sprintf(my_numbers_as_a_string, "%d", i);
i++;
}
printf("%s\n", my_numbers_as_a_string);
// Should print out:
// 1234567891011121314151617181920
//
// If the above is unread-able its basically
// 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
答案 0 :(得分:2)
要计算从1到n的数字时要写入的位数,请使用类似的
unsigned long digits(unsigned long n)
{
unsigned long total = 0;
for (unsigned long i = 1; i <= n; i *= 10){
total += (1 + n - i);
}
return total;
}
例如,n
为11
时产生的1234567891011
具有13位数字。
该算法的一个缺陷是它可以在足够大的n
上循环,并且截止值取决于平台上unsigned long
的范围。将n
限制为不大于ULONG_MAX / 10 - 1
就足够了。
答案 1 :(得分:2)
这更是一个难题。您要在字符串中存储从1到某个数字 x 的数字序列,因此需要所有字符的总数。 例如,让x = 77867。所以x是5个字符长的数字。可以使用 user10334659 给出的循环来找到。
首先要注意的是,从1到最多4位的数字基本上是填充的,并且与 x 的值无关。因此,我们首先可以计算这些数字的字符数。
因此,从1到最大 y 位数字的所有数字的总字符为:
9 ( 10^0 x 1 + 10^1 x 2 + ... + 10^(y-1) x y )
现在,我们只需要计算从10^(y)
到 x 的总数(这是一个(y + 1)位数字)。对于我们的情况,是10000-77867:#numbers = 67688 =>个字符= 67688x5。
时间复杂度
让最大数量为n。然后可以在 O(log(n))时间内计算 y + 1 。查找从1到 y 数字的字符也需要 O(log(n))时间。最后,在 O(1)时间内找到了从10 ^ y 到n的字符数。
因此,该算法可以找到 O(log(n))时间中的字符总数,而不是朴素的O(n)时间循环。
答案 2 :(得分:2)
以下代码计算从1到n
的所有整数的十进制数字中的位数:
int Digits = 0;
int LeadingZeros = 0;
for (int t = n; 0 < t; t /= 10)
{
++Digits;
LeadingZeros = 10*LeadingZeros + 1;
}
int TotalDigits = Digits * (n+1) - LeadingZeros;
推理:循环计算n
中的位数,并将此数字放入Digits
中。如果我们将所有从0到n
的整数写为带有Digits
位的十进制数字(使用前导零,例如“ 003”),则将使用Digits * (n+1)
位。由此,我们要减去前导零的数量。 (对于零,我们要减去所有零,因此对我们的计数没有净影响。)
对于n
从1到9,只有一个“ 0”要减去,一个减去0。对于n
从10到99,我们要减去“ 01”到“ 09”,以及“ 00”中的两个零。因此,对于10到99,我们减去与n
中的1到9相同的一个前导零,但还要减去十个前导零。类似地,对于n
从100到999,我们减去那些前导零加100,再从0到99减去每个前导零。最终,LeadingZeros的数量是数字相同的111…111为n
。我们可以看到循环在LeadingZeros
中进行了计算,因此使用的总位数为Digits * (n+1) - LeadingZeros
。
在为这些数字准备缓冲区时,应再添加一个字符以终止为空。此外,sprintf(my_numbers_as_a_string, "%d", i);
会将新数字写入my_numbers_as_a_string
的开头。要连接新数字,应规定写入先前数字的末尾。
答案 3 :(得分:0)
仅将数字打印到字符串,然后计算字符串长度?还是太简单了?
int numdigits(int n)
{
char buf[64];
return(sprintf(buf,"%d",n));
}