public class Test4 {
// 我的想法是,每一次求一个位置上的1的个数,第一轮先求个位上的1出现的个数,第二轮求十位上1出现的个数,以此类推...这样就能保证每个位置上的1都数了一次,并且不会出现多次重复数的情况。现在以其中的某一轮循环为例:假设现在有一个数 n = abcd(a,b,c,d分别表示0 ~ 9中的任意数)。我们本次循环要数的是b所在位置上1出现的个数。也就是要求满足X1XX这个样子的数的个数。我们可以将abcd分成两个部分,一部分在b前面即a,另一部分在b后面即cd。我们可以很容易的想到这样的关系(用x表示a中的取值,如a=7,x的取值为0 ~ 7,yz表示cd中的取值)
// 1.当x != a时,1个x对应100个yz,即0 ~ 99。比如,当x == 0时,yz可以是00 ~ 99
// 2.当x == a时,情况比较特殊,此时,我们不能保证b一定能取到1,所以要对b进行分情况讨论
//
// 当b > 1时,一个x还是对应100个xy
// 当b == 1时,一个x只能对应cd+1个xy,比如cd=17,那么就有xy的取值为00 ~ 17,18种可能
// 当b < 1时,因为b取不到1,所以这个这时不可能有满足x1xx的数
//
// 这种做法同时也适用于求2 ~ 9出现的次数
public static void main(String[] args) {
System.out.println(dataCount(13,1));
}
public static int dataCount(int n, int target) {
int cur; //每轮循环求cur位置上的1的个数
int result = 0; //统计出现的总次数
int mul = 1; //用来记录cur位置处于那个位置,个位,十位,百位...
int input = n; //保存输入,便于求出去掉cur前的若干个数字后的值
while (n != 0) {
cur = n % 10;
n = n / 10;
result += n * mul;
if (cur > target) {
result += 1 * mul;
} else if (cur == target) {
result += input % mul + 1;
}
mul *= 10;
}
return result;
}
}