1. 程式人生 > >演算法設計與分析: 1-1 統計數字問題

演算法設計與分析: 1-1 統計數字問題

1-1 統計數字問題

問題描述

一本書的頁碼從自然數1 開始順序編碼直到自然數n。書的頁碼按照通常的習慣編排, 每個頁碼都不含多餘的前導數字0。例如,第6 頁用數字6 表示,而不是06 或006 等。數 字計數問題要求對給定書的總頁碼n,計算出書的全部頁碼中分別用到多少次數字0,1, 2,…,9。
給定表示書的總頁碼的10 進位制整數n (1≤n≤109) 。程式設計計算書的全部頁碼中分別用 到多少次數字0,1,2,…,9。

輸入

每個檔案只有1 行,給出表示書的總頁碼的整數n。

輸出

程式執行結束時,輸出檔案共有10行,在第k行 輸出頁碼中用到數字k-1 的次數,k=1,2,…,10。

Java: version-1

import java.io.*;

public class Main {

    public static void main(String[] args) {
        String input = "/Users/dijk/IdeaProjects/tongjishuziwenti/input.txt";
        String output = "/Users/dijk/IdeaProjects/tongjishuziwenti/output.txt";
        BufferedReader reader = null;
        BufferedWriter writer = null
; int n = 0; int i,j,v; int[] count = new int[10]; try{ //Read page number n from input.txt file reader = new BufferedReader(new FileReader(input)); writer = new BufferedWriter(new FileWriter(output)); String number = null; number = reader.readLine(); if
(number != null){ try{ n = Integer.parseInt(number); }catch (NumberFormatException e){ e.printStackTrace(); } } //Count number 0-9 existed times for (i=1; i<=n; i++){ j=i; do{ v = j%10; j = j/10; count[v]++; }while(j>0); } //Write number 0-9 and its existed times to output.txt for(int k=1; k<=10; k++){ System.out.println(k-1 +":" + count[k-1]); writer.write(k-1 +":" + count[k-1] + "\n"); } reader.close(); writer.close(); }catch(IOException e){ e.printStackTrace(); }finally { if(reader != null){ try{ reader.close(); }catch (IOException e){ e.printStackTrace(); } } if(writer != null){ try{ writer.close(); }catch (IOException e){ e.printStackTrace(); } } } } }

Java: version-2

import java.io.*;

public class Main {

    public static void main(String[] args) {
        String input = "/Users/dijk/IdeaProjects/tongjishuziwenti/input.txt";
        String output = "/Users/dijk/IdeaProjects/tongjishuziwenti/output.txt";
        BufferedReader reader = null;
        BufferedWriter writer = null;
        int n = 0;
        int i,j;
        int[] count = new int[10];

        try{
            //Read page number n from input.txt file
            reader = new BufferedReader(new FileReader(input));
            writer = new BufferedWriter(new FileWriter(output));
            String number = null;
            number = reader.readLine();
            if(number != null){
                try{
                    n = Integer.parseInt(number);
                }catch (NumberFormatException e){
                    e.printStackTrace();
                }
            }

            //Count number 0-9 existed times
            int length = (int) Math.log10(n);//length的值為總頁碼數值n的位數減去1
            int curDigit, higher, lower;
            for(i=0; i<=length; i++){
                //eg: 如果 n=12345, curDigit=3,則higher=12,lower=45
                //則在數字3這個位置:
                //1、大於3的數字(4-9)出現的次數與前面的數字(higher)和該數字所在的位置(百位)有關:12*100=1200
                //2、數字3出現的次數與前面的數字(higher)、後面的數字(lower)和該數字所在的位置(百位)有關:12*100+45+1=1246
                //3、小於3的數字(0、1、2)出現的次數與前面的數字(higher)和該數字所在的位置(百位)有關:(12+1)*100=1300
                curDigit = (n/(int)Math.pow(10,length-i))%10;
                higher = n/(int)Math.pow(10,length-i+1);
                lower = n%(int)Math.pow(10,length-i);

                //equal current digit
                count[curDigit] += lower+1;

                //smaller than current digit
                for(j=0; j<curDigit; j++){
                    count[j] += (int)Math.pow(10,length-i)*(higher+1);
                }

                //equal and bigger than current digit
                for(j=curDigit; j<10; j++){
                    count[j] += (int)Math.pow(10,length-i)*higher;
                }
            }

            //減去多算的0
            for(i=0; i<=length; i++){
                count[0] -= (int)Math.pow(10,i);
            }

            //Write number 0-9 and its existed times to output.txt
            for(int k=1; k<=10; k++){
                System.out.println(k-1 +":" + count[k-1]);
                writer.write(k-1 +":" + count[k-1] + "\n");
            }

            reader.close();
            writer.close();
        }catch(IOException e){
            e.printStackTrace();
        }finally {
            if(reader != null){
                try{
                    reader.close();
                }catch (IOException e){
                    e.printStackTrace();
                }
            }
            if(writer != null){
                try{
                    writer.close();
                }catch (IOException e){
                    e.printStackTrace();
                }
            }
        }
    }
}

分析

由0,1,2,…,9組成的所有m位數。從m個0到m個9共有10m個m位數。在這10m個m位數中,包含數字的總個數是m10m,其中0,1,2,…,9每個數字出現次數相同,則每個數字均為m10m1次。
可以首先把最高位的數字單獨處理,然後再處理剩下的m-1位,最後把那些多餘的0全部去掉。

Java: version-3

import java.io.*;

public class Main {

    public static void main(String[] args) {
        String input = "/Users/dijk/IdeaProjects/tongjishuziwenti/input.txt";
        String output = "/Users/dijk/IdeaProjects/tongjishuziwenti/output.txt";
        BufferedReader reader = null;
        BufferedWriter writer = null;
        int n = 0;
        int i,j,k;
        int[] count = new int[10];

        try{
            //Read page number n from input.txt file
            reader = new BufferedReader(new FileReader(input));
            writer = new BufferedWriter(new FileWriter(output));
            String number = null;
            number = reader.readLine();
            if(number != null){
                try{
                    n = Integer.parseInt(number);
                }catch (NumberFormatException e){
                    e.printStackTrace();
                }
            }

            //Count number 0-9 existed times
            int length = (int) Math.log10(n);//length的值為總頁碼數值n的位數減去1
            int tempNum = n;
            int highestDigit,restNum;
            for(i=0; i<=length; i++){
                highestDigit = tempNum/(int)Math.pow(10,length-i);//獲得最高位上的數字
                restNum = tempNum-highestDigit*(int)Math.pow(10,length-i);//去掉最高位剩下的數值
                count[highestDigit] += restNum+1;

                for(j=0; j<highestDigit; j++){
                    count[j] += (int)Math.pow(10,length-i);
                    for(k=0; k<10; k++){
                        count[k] += (length-i)*(int)Math.pow(10,length-i-1);
                    }
                }

                tempNum = restNum;
            }

            //減去多算的0
            for(i=0; i<=length; i++){
                count[0] -= (int)Math.pow(10,i);
            }

            //Write number 0-9 and its existed times to output.txt
            for(k=1; k<=10; k++){
                System.out.println(k-1 +":" + count[k-1]);
                writer.write(k-1 +":" + count[k-1] + "\n");
            }

            reader.close();
            writer.close();
        }catch(IOException e){
            e.printStackTrace();
        }finally {
            if(reader != null){
                try{
                    reader.close();
                }catch (IOException e){
                    e.printStackTrace();
                }
            }
            if(writer != null){
                try{
                    writer.close();
                }catch (IOException e){
                    e.printStackTrace();
                }
            }
        }
    }
}

Sample input 1

11

Sample output 1

0:1
1:4
2:1
3:1
4:1
5:1
6:1
7:1
8:1
9:1

Sample input 2

123

Sample output 2

0:22
1:57
2:27
3:23
4:22
5:22
6:22
7:22
8:22
9:22

Sample input 3

12345

Sample output 3

0:4664
1:8121
2:5121
3:4721
4:4671
5:4665
6:4664
7:4664
8:4664
9:4664

Reference

王曉東《計算機演算法設計與分析》(第3版)P6

相關推薦

演算法設計分析作業1

                             35. Search Insert Position Description: Given a sorted array and a target value, return the index if the ta

演算法設計分析1演算法概述

第1章 演算法概述(窮舉演算法) 重要人物:Alan Turing(圖靈機)、Donald Knuth(TEX系統) 演算法:解決問題的一種方法或一個過程 特性:有窮性(Finiteness)、確定性(Definiteness)、可行性(effectivenes

演算法設計分析: 4-1 會場安排問題

4-1 會場安排問題 問題描述 假設要在足夠多的會場裡安排一批活動,並希望使用盡可能少的會場。設計一個有效的貪心演算法進行安排。(這個問題實際上是著名的圖著色問題。若將每一個活動作為圖的一個 頂點,不相容活動間用邊相連。使相鄰頂點著有不同顏色的最小著色數

[演算法設計分析]4.1.2倒推法(猴子吃桃+一維陣列楊輝三角形+穿越沙漠)

#include<stdio.h> #include<iostream> using namespace std; void MonkeyPeach(); void Bino

演算法設計分析: 1-1 統計數字問題

1-1 統計數字問題 問題描述 一本書的頁碼從自然數1 開始順序編碼直到自然數n。書的頁碼按照通常的習慣編排, 每個頁碼都不含多餘的前導數字0。例如,第6 頁用數字6 表示,而不是06 或006 等。數 字計數問題要求對給定書的總頁碼n,計算出書的全

演算法設計分析作業題】第二週:1. Two Sum

題目 C++ solution class Solution { public: vector<int> twoSum(vector<int>& nums, int target) { ve

計算機演算法設計分析1-4 金幣陣列問題

問題描述:有m*n枚金幣在桌面上排列成一個m行n列的金幣陣列。每一枚金幣或正面朝上,或背面朝上。用數字表示金幣狀態,0表示正面朝上,1表示背面朝上。 金幣陣列遊戲的規則是:     (1)每次將任一行金幣翻過來放在原來的位置上。     (2)每次可以任選2列,交換這2

《計算機演算法設計分析 第4版 (王曉東) 課後答案[1-9章]》pdf版電子書附下載連結+30個總結JVM虛擬機器的技術文排版好(收藏版)

技術書閱讀方法論 一.速讀一遍(最好在1~2天內完成) 人的大腦記憶力有限,在一天內快速看完一本書會在大腦裡留下深刻印象,對於之後複習以及總結都會有特別好的作用。 對於每一章的知識,先閱讀標題,弄懂大概講的是什麼主題,再去快速看一遍,不懂也沒有關係,但是一定要在不懂的

演算法設計分析基礎【第三版】習題1.1 4

演算法設計與分析基礎 習題1.1 4 設計一個[√n]的演算法,n是任意正整數。除了賦值和比較運算,該演算法只能用到基本的四則運算。 程式碼實現: #include "iostream" using namespace std; double n; doubl

計算機演算法設計分析學習筆記1

基本概念 程式 = 演算法 + 資料結構 演算法描述如何解決一類問題的一種方法,滿足如下性質: -輸入:一類問題的例項 - 輸出:針對例項的解 - 確定性:每條指令無歧義 - 有限性:有限迴圈 程式 不滿足有限性性質, eg. 作業系統為無限

計算機演算法設計分析課本(王曉東著)課後演算法實現題1-3 最多約數問題

問題描述: 正整數x的約數是能整除x的正整數。正整數x的約數個數記為div(x)。例如,1 2 5 10都是10的約數,且div(10)=4。設a和b是2個正整數,a<=b,找出a和b之間約數個數最多的數x。 演算法設計: 對於給定的2個正整數a<=b,計算a和b之間約數個數最多

演算法設計分析之入門篇(1.1演算法概述)——什麼是演算法

 我學習的視訊是網易雲平臺上的由王巨集志老師講的“演算法設計與分析”,這裡記錄學習筆記! 1.計算的定義   2.演算法的定義   3.問題的定義       問題是一種關係,下面這個例子中我們定義出一個我們常見的排序問題,之所以要弄出這種嚴格的定義是因為讓問題更嚴謹

統計數字問題[演算法設計分析]

/* * NumberCount.cpp * Author: MagicYun */ #include <cstdio>#include <cstdlib>#include <iostream> using namespace std; i

演算法設計分析: 5-37 n²-1謎問題

5-37 n²-1謎問題 問題描述 重排九宮是一個古老的單人智力遊戲。據說重排九宮起源於我國古時由三國演義故事“關羽義釋曹操”而設計的智力玩具“華容道”,後來流傳到歐洲,將人物變成數字。原始 的重排九宮問題是這樣的:將數字 1~8 按照任意次序排在 3×

0-1揹包問題的多種演算法設計分析

0-1揹包問題的多種演算法設計與分析 0-1揹包問題描述:給定一組共n個物品,每種物品都有自己的重量wi(i=1~n)和價值vi(i=1~n),在限定的總重量(揹包的容量C)內,如何選擇才能使得選擇物品的總價值之和最高。選擇最優的物品子集放置於給定揹包中,最優子集對應n元解

數字三角形問題(簡單動態規劃)-演算法設計分析

const int maxn=100; int a[maxn][maxn]; int dp[maxn][maxn]; int main() { int n; cin>>n;

『嗨威說』演算法設計分析 - PTA 數字三角形 / 最大子段和 / 編輯距離問題(第三章上機實踐報告)

本文索引目錄: 一、PTA實驗報告題1 : 數字三角形   1.1  實踐題目   1.2  問題描述   1.3  演算法描述   1.4  演算法時間及空間複雜度分析 二、PTA實驗報告題2 : 最大子段和   2.1  實踐題目   2.2  問題描述   2.

演算法設計分析——動態規劃(一)矩陣連乘

動態規劃——Dynamic programming,可以說是本人一直沒有啃下的骨頭,這次我就得好好來學學Dynamic programming. OK,出發! 動態規劃通常是分治演算法的一種特殊情況,它一般用於最優化問題,如果這些問題能夠: 1.能夠分解為規模更小的子問題 2.遞迴的

演算法設計分析——分治法

前言 本文重點回顧了卜老師課堂上關於分治演算法的一些常見的問題。加油吧!ヾ(◍°∇°◍)ノ゙ 分治法(Divide and Conquer) 當面對一個問題的時候,我們可能一下子找不到解決問題的方法。此時,我們可以考慮將問題規模最小化,先看看當問題規模變小以後,我們如何去解決

演算法設計分析04-排序問題

①氣泡排序:量量比較待排序資料元素的大小,發現兩個資料元素的次序相反時進行交換,直到沒有反序的資料元素為止。時間複雜度是O(n*2)。穩定的。下面給出兩種排序演算法,我比較喜歡第二種,因為第二種才能真正解釋冒泡的原理 public class bubble1 {    &n