统计数字问题
(1)、问题描述
一本书的页码从自然数1 开始顺序编码直到自然数n。书的页码按照通常的习惯编排,每个页码都不含多余的前导数字0。例如,第6 页用数字6 表示,而不是06 或006 等。数字计数问题要求对给定书的总页码n,计算出书的全部页码中分别用到多少次数字0,1, 2,…,9。
(2)、算法设计
给定表示书的总页码的10 进制整数n (1≤n≤10 ) 。编程计算书的全部页码中分别用到多少次数字0,1,2,…,9。
- 暴力法
#include<iostream>
using namespace std;
int main(){
int c[10]={0};
int n;
cin>>n;
for(int i=1;i<=n;i++){
int tmp=i;
while(tmp){
c[tmp%10]++;
tmp/=10;
}
}
for(int i=0;i<=9;i++){
cout<<c[i]<<endl;
}
}
- 递归法
5.利用递归重复算出余数m1,最后减去多余的0,中间有0的也要考虑
代码:
#include <iostream>
#include <cmath>
using namespace std;
int c[10];
//获取位数
int get_wei(int n)
{
return int(log10(n))+1;
}
//获取最高位的数字
int get_max(int n)
{
return n/int(pow(10,get_wei(n)-1));
}
//获取余数
int get_yu(int n)
{
return n%int(pow(10,get_wei(n)-1));
}
//获取m位数零的个数
int get_zero(int m)
{
if (m==1)
return 1;
return get_zero(m-1)+int(pow(10,m-1));
}
//总体流程
void solve(int n)
{
for(int i=0;i<10;i++)
{
c[i] =c[i]+ get_max(n)*(get_wei(n)-1)*int(pow(10,get_wei(n)-2));
}
for(int i =0;i<get_max(n);i++)
{
c[i] =c[i]+int(pow(10,get_wei(n)-1));
}
c[get_max(n)] = c[get_max(n)]+get_yu(n)+1;
int t=get_yu(n);//余数
if(t==0){//如果t为0
c[0]+=get_wei(n)-1;//0位加len-1
return ;//返回结果
}
int len=log10(t)+1;
if(len!=get_wei(n)-1){//若像4021这种情况,中间1个0也要相应的处理
c[0]+=(get_wei(n)-len-1)*(t+1);
}
return solve(t);
}
int main()
{
int n;
bool flag = true;
while(flag)
{
for(int i=0;i<10;i++) //存数字赋初值
{
c[i]=0;
}
cout<<"请输入一个页码。以0结束程序:"<<endl;
cin>>n;
if(n==0)
flag =false;
solve(n);
c[0] = c[0]-get_zero(get_wei(n));
cout<<"数字0-9出现的数字分别为:"<<endl;
for(int j=0;j<10;j++)
{
cout<<c[j]<<" ";
}
cout<<endl<<endl;
}
return 0;
}