编程之美-2.4-1的数目
1. 简述
给定一个十进制正整数N,写下从1开始,到N的所有整数,然后数一下其中出现的所有'1'的个数。例如:N=2,写下1,2.这样只出现了1个'1',N=12,我们会写下1,2,3,4,5,6,7,8,9,10,11,12,这样1的个数是5。
两个问题:
1. 写一个函数f(N)。返回1到N之间出现的'1'的个数,比如f(12)=5。
2. 满足条件f(N)=N的最大的N是多少?
2. 思路
数论的题目没有兴趣,也没有思路,直接上书上和别人的思路了。第一个问题的思路是把分别计算第i位上1的个数(其中,i=1,2,...,N的最高位),假设N=A*10^i + B*10^(i-1) + C,即A,B和C分别代表第i位的高位数值,当前位数值和低位数值。第i位上1的个数与A,B,C可能都有关。
当B > 1时,([0-A],1,*)<(A,B,C),一共是(A+1)*10^i个1,高位相关。
当B = 1时,([0-(A-1),1,*])<(A,B,C),[A,1,[0-C]] <= (A,B,C),一共是A*10^i+C+1个1,高位低位相关。
当B = 0时,([0-(A-1)],1,*)<(A,B,C),一共是A*10^i个1,高位相关。
对于1的情况,可以推广到x的情况即(2-9),对于0的情况要特殊处理,具体见参考中的文章读《编程之美》有感—1的个数:数字x的个数。
对于第二个题目,算了以后再仔细看了。
3. 代码
给一个可以计算1-N的数中,包含x数字的个数,x取值为1-9,没有涉及x=0的情况。
#include <iostream>
using namespace std;
int find_num(int N, int x) {
int count = 0;
int A,B,C,factor; // A:高位,B:当前位,C:低位
factor = 1;
while(N >= factor) {
A = N / (factor * 10);
B = N / factor % 10;
C = N % factor;
cout << "(A,B,C): " << "(" << A << "," << B << "," << C << ")" << endl;
if(B > x)
count += (A+1) * factor; // (0,x,*)-(A,x,*)
else if(B == x)
count += A * factor + C + 1; // (0,x,*)-(A-1,x,*), (A,x,0)-(A,x,C)
else //
count += A * factor;
factor *= 10;
}
return count;
}
int main() {
int N;
while(true) {
cout << "输入N:";
cin >> N;
int count = find_num(N, 1);
cout << 1 << "到" << N << "中1的个数:";
cout << count << endl;
cout << endl;
}
system("PAUSE");
return 0;
}
输出结果为:
4. 参考
编程之美,2.4节,1的数目。
读《编程之美》有感—1的个数:数字x的个数