1~n,1出现的次数

来源:互联网 发布:人工智能与公共安全 编辑:程序博客网 时间:2024/05/19 00:52

主要思想,分别考虑每位(个位,十位,不是二进制的位)为1的情况,特别考虑最高位是1和不是1的情况。

使用递归,如 f(253)=f(200)+f(50)+f(3)

#include <iostream>#include <ctime>using namespace std;int f1(int n){    int i, j, k;    int num_1=0;    for(i=0; i<=n; i++)    {        k = i;        do{            j = k%10;            if(j==1)                num_1++;            k = k/10;        }while(k!=0);    }    return num_1;}int f2(int n){    if(n/10==0)        return n>=1;            int pow=0;               //e.g n=253, pow=3    int high=1;              //high=2    int n1 = n, n2=1, n3;    //n2=100,n3=53    int num_1 = 1;    while(n1)    {        if(n1/10 == 0)            high = n1;        pow++;        n2 *= 10;        n1 /= 10;    }    n2 /= 10;    n3 = n-high*n2;        int i;    //e.g 253    //1在个位,十位百位有10×2(0,1)    //1在十位,个位百位有10×2(0,1)    //1在百位,个位十位有10×10    for(i=1; i<pow-1; i++)    {        num_1 *= 10;    }        //(high==1?(n3+1):n2);是为了处理特殊情况,如12,10,110    //    = 10*2*2             + 100    num_1 = num_1*high*(pow-1) + (high==1?(n3+1):n2);        //递归, f(253) = f(200) + f(53)    num_1 += f2(n3);    return num_1;}int main(void){    // test and verify    // int n=1;    // int k1, k2;    // while(n<10000)    // {        // k1 = f1(n);        // k2 = f2(n);        // if(k1!=k2)        // {            // cout<<n<<","<<k1<<","<<k2<<endl;        // }        // n++;    // }        //compare    long t1 = clock();    f1(1000000000);    long t2 = clock();    cout<<"遍历:"<<t2-t1<<endl;        t1 = clock();    f2(1000000000);    t2 = clock();    cout<<"10进制,递归:"<<t2-t1<<endl;        return 0;}

发现编程之美中有这个,代码为:

long CountOne2(unsigned long n){    long count = 0;    long i = 1;    long current = 0,after = 0,before = 0;    while((n / i) != 0)    {                   current = (n / i) % 10;        before = n / (i * 10);        after = n - (n / i) * i;        if (current > 1)            count = count + (before + 1) * i;        else if (current == 0)            count = count + before * i;        else if(current == 1)            count = count + before * i + after + 1;        i = i * 10;    }    return count;    }

可能思路不一样,上面的代码看不大懂,下面是我对自己的代码的优化:

void init(int n, int& pow, int& tens){pow = 0;tens = 1;while(n/=10){pow++;tens*=10;}}int f(int n, int pow, int tens){if(pow==0)return n>=1;int h = n/tens;int ret = tens/10*h*pow + (h==1?(n%tens+1):tens);return ret + f(n%tens, pow-1, tens/10);}

调用:

init(n, pow, tens);f(n, pow, tens);





原创粉丝点击