如何确定一个数字中有多少个字符?

时间:2018-09-11 13:07:42

标签: c string while-loop char int

所以长度:

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

4 个答案:

答案 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;  
} 

例如,n11时产生的1234567891011具有13位数字。

该算法的一个缺陷是它可以在足够大的n上循环,并且截止值取决于平台上unsigned long的范围。将n限制为不大于ULONG_MAX / 10 - 1就足够了。

答案 1 :(得分:2)

这更是一个难题。您要在字符串中存储从1到某个数字 x 的数字序列,因此需要所有字符的总数。 例如,让x = 77867。所以x是5个字符长的数字。可以使用 user10334659 给出的循环来找到。

首先要注意的是,从1到最多4位的数字基本上是填充的,并且与 x 的值无关。因此,我们首先可以计算这些数字的字符数。

  1. 1-9:个位数。 #numbers = 9。 =>字符= 9 x 1
  2. 10-99:2个字符。 #numbers = 90. =>字符= 90 x 2
  3. 100-999:3个字符。 #个数字=900。=>字符= 900 x 3
  4. 1000-9999:4个字符。 #个数字=9000。=>字符= 9000 x 4

因此,从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));
}