从1到整数n中1出现的次数

题目:输入一个整数n,求从1到n这n个整数的十进制表示中1出现的次数。例如输入12,从1到12这些整数中包含1的数字有1,10,11和12共出现了5次。
 
不考虑时间效率的解法:
 1 int NumberOf1Between1AndN(unsigned int n)
 2 {
 3  int number=0;
 4  for(unsigned int i=1;i<=n;++i)
 5  number +=NumberOf1(i);
 6  return number;
 7  }
 8 int NumberOf1(unsigned int n)
 9 {
10  int number=0;
11  while(n)
12  {
13   if(n%10==1)
14   number++;
15   n=n/10;
16  }
17 return number;
18 }


从数字规律着手明显提高时间效率:

 1 int Numberof1Between1AndN(int n)
 2 {
 3  if(n<=0)
 4  return 0;
 5  char strN[50];
 6  sprintf(strN,"%d",n);//将整数转换为字符串
 7  return NumberOf1(strN);
 8  }
 9 
10  int NumberOf1(const char* strN)
11 {
12  if(!strN||*strN<'0'||*strN>'9'||*strN=='\0')
13  return 0;
14  int first=*strN-'0';
15  unsigned int length=static_cast<unsigned int>(strlen(strN));
16  if(length==1&&first==0)
17  return 0;
18  if(length==1&&first>0)
19  return 1;
20 
21  int numFirstDigit=0;
22  if(first>1)
23  numberFirstDigit=PowerBase10(length-1);
24  else if(first==1)
25  numFirstDigit=atoi(strN+1)+1;//将字符串转换为整数
26  
27  int numOtherDigits=first*(length-1)*PowerBase10(length-2);
28  int numRecursive=NumberOf1(strN+1);
29 
30  return numFirstDigit+numOtherDigits+numRecursive;
31 }
32 
33 int PowerBase10(unsigned int n)
34 {
35  int result=1;
36  for(unsigned int i=0;i<n;++i)
37  result *=10;
38  return result;
39  }
40  

 

 

 

posted on 2016-05-11 18:21  wxdjss  阅读(164)  评论(0编辑  收藏  举报

导航