统计数字问题(Java语言实现)

来源:互联网 发布:淘宝介入处理流程 编辑:程序博客网 时间:2024/06/07 01:55

        问题描述:一本书的页码从自然数1 开始顺序编码直到自然数n。书的页码按照通常的习惯编排,每个页码都不含多余的前导数字0。例如,第6 页用数字6 表示,而不是06 或006 等。数字计数问题要求对给定书的总页码n,计算出书的全部页码中分别用到多少次数字0,1,2,…,9。 

       算法设计:给定表示书的总页码的10 进制整数n (1≤n≤10^9) 。计算书的全部页码中分别用到多少次数字0,1,2,…,9。

       数据输入:输入数据由文件名为input.txt的文本文件提供。每个文件只有1行,给出表示书的总页码的整数n。

       结果输出:将计算结果输出到文件output.txt中。输出文件共有10行,将第k行输出页码中用到数字k-1的次数,k=1,2,…10。

输入文件示例                  输出文件示例

input.txt                     output.txt

11                                1

                                   4

                                   1

                                   1

                                   1

                                   1

                                   1

                                   1

                                   1

                                   1

    分析与解答:考察由0,1,2,…,9组成的所有的n位数,从n个0到n个9共有10^n个n位数。在这10^n个n位数中,0,1,2,…,9每个数字使用次数相同,设为f(n)。f(n)满足如下递归式:

                                     

        由此可知,f(n) = n × 10^(n-1)

        据此,可以从高位向低位进行统计,再减去多余的0的个数即可。



package com.algorithm.johnchang.ch1;import java.io.BufferedReader;import java.io.FileOutputStream;import java.io.FileReader;import java.io.IOException;import java.io.PrintStream;//import java.util.Scanner;/** * 统计数字问题 给定表示书的总页码的十进制整数m(1<= m <= 10的9次方), 计算书的全部页码中分别用到多少次数字0,1,2,……,9 *  * @author John.Chang *  * @version 1.0 */public class StatisticsProblem {// 保存最终结果的数组private int[] result;/** * Constructor,初始化结果数组 */public StatisticsProblem() {this.result = new int[10];}/** * 求解整数幂 *  * @param a *            底数 * @param b *            指数 * @return a的b次方 */public static int power(int a, int b) {return (int) Math.pow(a, b);}/** * 用递归来求解所有n位数中每个数字出现的次数 *  * @param n *            位数 * @return 10的n次方个n位数中每个数字出现的次数 */public static int func1(int n) {if (n == 0) {return 0;}if (n == 1) {return 1;} else {return 10 * func1(n - 1) + power(10, n - 1);}}/** * 直接使用递推表达式求解所有n位数中每个数字出现的次数 *  * @param n *            位数 * @return 10的n次方个n位数中每个数字出现的次数 */public static int func2(int n) {return n * power(10, n - 1);}/** * 给定书的总页码的十进制整数,计算每个数字出现的次数 *  * @param num *            书的总页码整数 */public void statistic(int num) {// 获取整数m的位数int length = String.valueOf(num).length();// 从高位向低位进行统计,再减去多余的0的个数for (int i = length; i > 0; i--) {// 计算出第i位(从低位向高位)对应的数bitnumint a = power(10, i);int b = power(10, i - 1);int bitnum = (num % a) / b;int j;// 计算比bitnum小的数字出现的次数for (j = 0; j < bitnum; j++) {// 计算比bitnum小的数字在第i位出现的次数result[j] += b;// 当第i位为比bitnum小的数字时,计算所有数字在后面i-1位中出现的次数for (int k = 0; k <= 9; k++) {// result[k] += func1(i - 1);result[k] += func2(i - 1);}}// 计算bitnum在第i位出现的次数result[j] += num % b + 1;// 最后对于数字0需减去多余的0的个数result[0] -= b;}}@SuppressWarnings("resource")public static void main(String[] args) throws IOException {// 从控制台输入获取书的总页码整数num// Scanner scanner = new Scanner(System.in);// int num = scanner.nextInt();// 从input.txt文本文件中读入书的总页码整数numBufferedReader br = new BufferedReader(new FileReader("input.txt"));int num = Integer.parseInt(br.readLine());StatisticsProblem sp = new StatisticsProblem();sp.statistic(num);// 输出统计结果PrintStream ps = new PrintStream(new FileOutputStream("output.txt"));for (int i = 0; i < 10; i++) {// 输出结果到控制台System.out.println(sp.result[i]);// 输出结果到output.txt文本文档中ps.println(sp.result[i]);}}}


0 0
原创粉丝点击