C 如何计算从1到n范围内0或1的总外观?
所以,我想知道在一个数字范围内出现了多少位数字0或1。例如: 我想知道从数字1到100出现了多少个0。答案是,0出现11次。我想把它实现到C,但我不知道怎么做 因此,我想要的第一件事是接收一个输入类型int(假设int为n)。然后,从数字1到n,有多少0出现在这些范围内,有多少1出现在这些范围内。然后打印显示的0和1的总数 这是我尝试过的,但还没有完成C 如何计算从1到n范围内0或1的总外观?,c,algorithm,numbers,C,Algorithm,Numbers,所以,我想知道在一个数字范围内出现了多少位数字0或1。例如: 我想知道从数字1到100出现了多少个0。答案是,0出现11次。我想把它实现到C,但我不知道怎么做 因此,我想要的第一件事是接收一个输入类型int(假设int为n)。然后,从数字1到n,有多少0出现在这些范围内,有多少1出现在这些范围内。然后打印显示的0和1的总数 这是我尝试过的,但还没有完成 #include <stdio.h> int main() { int N, totalZero = 0; sc
#include <stdio.h>
int main()
{
int N, totalZero = 0;
scanf("%d", &N);
for (int i=N; i>0; i--)
{
//statement
}
return 0;
}
#包括
int main()
{
int N,totalZero=0;
scanf(“%d”和“&N”);
对于(int i=N;i>0;i--)
{
//声明
}
返回0;
}
我不知道在for中的//语句中必须执行什么操作。每次剩余的
I/10
=0
或1
#include <stdio.h>
int main(void)
{
int max = 100;
int n0 = 0;
int n1 = 0;
for (int i = 1; i <= max; i++) {
for (int x = i; x != 0; x /= 10) {
switch (x % 10) {
case 0: n0++; break;
case 1: n1++; break;
default: break;
}
}
}
printf("0 appears %d times\n", n0);
printf("1 appears %d times\n", n1);
return 0;
}
#包括
内部主(空)
{
int max=100;
int n0=0;
int n1=0;
对于(int i=1;i作为您的问题:
例如:1..100.“零”数字将出现11次。这意味着:1020305060708090和100(零数字出现的11次)
那么for循环内部的条件是什么:
#include <stdio.h>
#include <conio.h>
void count(int &n)
{
printf("Input n: ");
scanf("%d",&n);
int value=0;
int value2=0;
for(int i=1;i<=n;i++)
{
int x = i;
while (x>0)
{
if(x==100 && x%10==0)
{
x/=10;
if(x==10)
value+=2;
}
else if(x%10==0)
value++;
else if(x%10==1)
value2++;
x/=10;
}
}
printf("\n%d",value);
printf("\n%d",value2);
}
int main()
{
int n;
count(n);
return 0;
}
#包括
#包括
无效计数(整数和整数)
{
printf(“输入n:”);
scanf(“%d”和“&n”);
int值=0;
整数值2=0;
对于(int i=1;i0)
{
如果(x==100&&x%10==0)
{
x/=10;
如果(x==10)
数值+=2;
}
否则如果(x%10==0)
值++;
如果(x%10==1),则为else
value2++;
x/=10;
}
}
printf(“\n%d”,值);
printf(“\n%d”,值2);
}
int main()
{
int n;
计数(n);
返回0;
}
这个问题可以用数学方法解决,而无需对范围内的每个数字进行迭代并计算其位数。
它通过计算特定数字在每个位置出现的次数来工作
例子
让我们举一个例子,从1
到3876
计算7的数量
每个位置出现7次的次数
- 1位:
(0)7、17、27、…、107、…、3867
=387
x1
次
- 10s地点:
(0)70,71,72,73,…,79,170,…,179,…,3770,…,3779
=38
x
10
=380且介于3870,…,3876:7倍,等于387
- 100位:
700,…799,…3700,…3799
=(3+1)
x100
=400
- 1000秒位置:
0
次
总计=387
+387
+400
=1174
,这是所需的结果
代码
我们将cntdigit(N,digit)
定义为一个函数,该函数返回从1
到N
计数的数字出现的次数
long long cntdigit(long long n, int digit)
{
long long j;
long long res = 0;
for(j = 1; n/j; j *= 10) {
long long curdigit = (n / j) % 10;
res += (n / j / 10) * j;
if (curdigit > digit)
res += j;
else if (curdigit == digit)
res += n % j + 1;
if (digit == 0)
res -= j;
}
return res;
}
时间复杂性:
该问题可以解决O(d)
时间复杂度中的任意数字,其中d
是n
的基于10
的位数
说明:
迭代编号n
的所有数字,将其除以10
和mod10
的指数以获得每个数字。(有关更多详细信息,请参阅)
然后我们开始在每个地方计数,数字出现的次数
在每个位置,左边的部分(即除以10的指数的商)是一个数字在一位、十位、百位等位置出现的次数
如果当前数字大于数字
,则我们添加j
(10s指数)以计算从0开始的所有商
如果当前数字等于数字
,则该数字出现在该位置的次数为指数+1的余数
最后,如果要计算的数字是0
,那么我们需要减去商是0
的次数。为什么?,因为我们不想对以0开头的数字计算0。例如,您不想在数字中计算0,01、02、03等等
通过减去b
和a-1
的解,可以很容易地将解扩展到a
到b
之间的范围:
int main()
{
long long a, b;
// Range and digit
scanf("%lld %lld", &a, &b, &digit);
printf("%lld ", cntdigit(b, i) - cntdigit(a-1, i));
return 0;
}
如果您感兴趣,您可以在测试您的解决方案,以了解此问题的一般情况。这看起来像是作业的一部分(无论是家庭作业、书籍还是教程都不重要).当然,你已经得到了解决这项任务所需的所有部分。回顾你的资料,找到他们解释如何将数字分解为数字的地方。我认为这个问题不是重复的。它可以用O(logn)完成时间,而不必迭代并从整数中获取每个数字。但是,它似乎是赋值的一部分。迭代范围内的所有数字并不是解决此问题的最佳方法。@rici我不知道如何有效地解决它。您能告诉我您的方法吗?尝试提供更多有关原因的信息这个问题不是重复的。查找从1到N计数的位数与查找整数中的单个位数不同。也许,主持人/评论员想到了最简单的解决方案,迭代每个数字并查找不相同的单个位数。这是一个算法问题,可以用0来解决我们可以用数学方法来解决这个问题,如图所示:“这意味着:0、10、20、30、40、50、60、70、80、90和100(零数字出现的11倍)”嗯,我看到12个零…换句话说:你的代码不工作,因为它只找到尾随的零。你确定这个代码是正确的吗?这将检查0到100之间的余数&这里的计数只有1。哟