1. 1的个数
给定一个十进制正整数N,写下从1开始,到 N的所有正数,然后数出其中出现所有1的个数。
常规方法:学过c的几乎都能编出来这种双重循环的程序
#include "stdio.h"
#include "math.h"
#include "time.h"
int main()
{
clock_t c1,c2;
c1=clock();
int N;
int i,j;
N=1234567;
int count=0;
for(i=1;i<=N;i++)
{
j=0;
while(i/(int)pow((double)10,(double)j))
{
if(((i/(int)pow((double)10,(double)j))%10)==1)
count+=1;
j++;
}
}
printf("the number of 1 is %d/n",count);
c2=clock();
printf("the run time is %d/n",c2-c1);
}
改进算法:
描述:将求值分为不同位数上分别求1的个数,最后累加。
比如1234567,要求百位上出现1的数的个数,即cal(1234567,3),要先求出百位之前的数1234,即front(1234567,3),再求百位之后的数67,即back(1234567,3).不难看出百位上的数5,即on(1234567,3)是关键。他为0,1,和其他的时候对应不同的结果,这也此题最重要的规律和算法,实现在cal()中。
#include "stdio.h"
#include "math.h"
#include "time.h"
int num(int a) //return how many numbers the a has
{
int i=0;
while(a/(int)pow((double)10,(double)i))
i++;
return i;
}
int front(int a,int k) //return the number in front of the kth.
{
return a/(int)pow((double)10,(double)k);
}
int back(int a,int k) //return the number back kth.
{
return a%(int)pow((double)10,(double)(k-1));
}
int on(int a,int k) //return the number in the kth.
{
return a/(int)pow((double)10,(double)(k-1))%10;
}
int cal(int a ,int k) //return the number of 1 in the kth
{
int p;
p=on(a,k);
if(p==0)
{
return front(a,k)*(int)pow((double)10,(double)(k-1));
}
else if(p==1)
{
return front(a,k)*(int)pow((double)10,(double)(k-1))+back(a,k)+1;
}
else
{
return (front(a,k)+1)*(int)pow((double)10,(double)(k-1));
}
}
int cal_all(int a) //return all 1 in the a
{
int i;
int count=0;
for(i=1;i<=num(a);i++)
{
count+=cal(a,i);
}
return count;
}
int main()
{
clock_t c1,c2;
c1=clock();
int N=1234567;
printf("all the 1 in N is %d/n",cal_all(N));
c2=clock();
printf("the run time is %d/n",c2-c1);
}
运行时间不知道算是提高了多少倍。。。
Ps:经测试用了math.h里的pow函数和不用pow函数效率相差一个数量级。所以程序设计时,不要为了方便盲目的调用其他库函数。因为link过程比较费时。以下是不用pow函数的实现:
#include "stdio.h"
#include "time.h"
#define time_test 1
int main()
{
#ifdef time_test
clock_t c1,c2;
c1=clock();
#endif
int N;
int i,j;
N=1234567;
int count=0;
for(i=1;i<=N;i++)
{
j=i;
while(j!=0)
{
if(j%10==1)
count++;
j/=10;
}
}
printf("the number of 1 is %d/n",count);
#ifdef time_test
c2=clock();
printf("the run time is %d/n",c2-c1);
#endif
}
而且同样的程序在gcc中能够更高效,体现了一般情况gcc和vc效率的对比