Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 如何计算从1到n范围内0或1的总外观?_C_Algorithm_Numbers - Fatal编程技术网

C 如何计算从1到n范围内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

所以,我想知道在一个数字范围内出现了多少位数字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;

    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
    x
    1
  • 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)
    x
    100
    =
    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
    和mod
    10
    的指数以获得每个数字。(有关更多详细信息,请参阅)
  • 然后我们开始在每个地方计数,数字出现的次数
  • 在每个位置,左边的部分(即除以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。哟