<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12
      happyhippy

      這個世界的問題在于聰明人充滿疑惑,而傻子們堅信不疑。--羅素

       

          好久沒更新博客了,今天也來客博一下。
          前兩天在首頁看到題目:給出一個數n,O(1)求解1到n這些數中1出現的次數。

       

          看到這個題目,聯想到另一個題目:給出一個數n,求1到n這些數之和.哇靠,小學算術題,這不是侮辱咱的智商嘛~計算機最擅長干重復的勞動了,于是乎,瀟灑地抖出了下面code,把循環交給計算機去做:

      1Int32 sum = 0;
      2Int32 number = 100;
      3for (Int32 i = 1; i <= number; i++)
      4    sum += i;


          OK,結果是正確的,思路相當地清晰,完了嗎?沒完!為了顯示灑家精通C#,咱把循環改造下:

      1 for (Int32 i = 1; i <= number; sum += i++) ;


          結果依然是正確的,完了嗎?完了!不過是完蛋的“完”.難道我們一定要讓自己的代碼使別人費解,來顯示我們多牛X嗎!難道我們一定要讓計算機拼命地干傻活兒,來證明現在處理器的性能多NB嗎!為什么我們不把能做的做好,剩下的...讓那坨廢鐵干它該干的活兒:

      1 sum = number * (1 + number) / 2;

       

       

          扯遠了,拉回來說“正”題:給出一個數n,求解1到n這些數中1出現的次數。
          最清晰直觀的做法,就是遍歷這N個數,便利N個數中的數位,累計求出1出現的次數;至于所謂的遞歸,沒去看,也懶得去看;這里,我們先分析下這些阿拉伯數字的規律,然后根據出現1的概率來進行求解
      (1) 當n=9時,我們考慮0,1,2...9(共10個數字),我們不難得出結論:字符'0','1'...'9'出現的概率個占1/10(即0.1);
      (2) 當n=99時,我們考慮0,1,2...99(共100個數字),十位上,'1'出現的概率個占1/10;個位上,'1'出現的概率也為1/10, 于是1出現的次數=0.1*100 + 0.1 * 100 = 20;
      (3) 當n=100000000時,我們考慮0,1,2...100000000(共100000001個數字),最高位上,'1'只可能出現1次;其余各位上,'1'出現的概率各占1/10, 于是1出現的次數=1 + (0.1*8) * 100000000 = 80000001;

       

          當然,上面都是列舉的最簡單的例子,但我們不難看出,'1'的出現概率的確是存在規律的。下面我們來看更復雜的例子('0','1'...'9',下面統稱為阿拉伯數字符):設n=XYZ(其中X、Z表示零個或多個阿拉伯數字符,Y為一個阿拉伯數字),這樣XYZ就可以表示任意數字了,例如n=5可以表示為:X=Z="",Y=5;n=123456可以表示成:X="",Y=1,Z=23456或X=12345,Y=6,Z=""等6種方式。
          這里我取這種表達方式,是為了從Y上得出一個通用的統計字符出現概率的計算方法。Y為一個阿拉伯數字,所以其只能取0,1...9中的一個數字,其存在如下三種可能:
      (1) Y<1
      (2) Y=1
      (3) Y>1


          以n=123Y45(X=123,Y在百位上,可以任意取值,Z=45)來分別討論上面的三種情況:
      (1) Y<1:(此時Y只能取0值了),我們可以把區間[0..n]中的n+1個數分成兩段區間來分析,[000000..122999],即[000000..122999],即[000000...(X-1)999],
      [123000..123045],即[X000..XYZ],
          其中第一段區間中Y位(百位)上,共(X * Pow(10, Length(Z)+1))個數字,出現'1'的概率占1/10,而第二段區間中,Y位上出現'1'的概率為0,因此可以得出結論:Y<1時,'1'在該位上出現的數量=0.1 * (X * Pow(10, Length(Z)+1))

      (2) Y=1:(此時Y只能取1值了),我們可以把區間[0..n]中的n+1個數分成三段區間來分析,[000000..122999],即[000000..122999],同(1),Y位上出現'1'的概率為1/10;
      [123000..123099],即[X000..X099],同(1),Y為上出現'1'的概率為0;
      [123100..123145],即[XY00..XYZ],Y上出現'1'的概念為1,此區間工(Z+1)個數字
      因此可以得出結論:Y=1時,'1'在該位上出現的數量=0.1 * (X * Pow(10, Length(Z)+1)) + (Z + 1)

      (3) Y>1:(此時Y只能取2..9中的任意一個值了),我們可以把區間[0..n]中的n+1個數分成四段區間來分析,
      [000000..122999],即[000000..(X-1)999],同(1),Y位上出現'1'的概率為1/10;
      [123000..123099],即[X000..X099],同(1),Y位上出現'1'的概率為0;
      [123100..123199],即[X100..X199],Y上出現'1'的概念為1,此區間共Pow(10, Length(Z))個數字;
      [123200..123Y45],即[X200..XYZ],此時Y恒大于0,Y位上出現'1'的概率為0;
      因此可以得出結論:Y>1時,'1'在該位上出現的數量=0.1 * (X * Pow(10, Length(Z)+1)) + Pow(10, Length(Z))

       

          通過對上面3種情況的分析,我們可以看出,對于任意給定的整數n,我們都可以拆分成XYZ形式,并計算出Y位上'1'出現的數量;將Y從最高向最低位(個位)移動,可以計算出每位上'1'出現的數量,累計求和即為原題中要求的結果。Code如下:

       1//計算[1..number]中,共有多個字符c
       2private static Int64 Calc(Int64 number, char c)
       3{
       4    if (!Char.IsDigit(c) || c == '0')
       5        throw new Exception("暫只支持統計1..9出現的次數");
       6
       7    String s = number.ToString();
       8    Int32 digit = (Int32)c - 48;//將字符轉換成數字(0對應的ASCII碼值為48)
       9    Int64 totalCount = 0;
      10
      11    for (Int32 i = 0; i < s.Length; i++)//忽略掉剛加上的前綴0
      12    {
      13        Int32 num = (Int32)s[i] - 48;
      14        switch (num.CompareTo(digit))
      15        {
      16            case -1://num<digit
      17         String preStr = s.Substring(0, i);
      18         totalCount += (Int64)(0.1 
      19                   * Math.Pow(10, s.Length - i) 
      20                          * (String.IsNullOrEmpty(preStr) ? 0 : Convert.ToInt64(preStr)));
      21                break;
      22            case 0//num=digit
      23                String mantissa = s.Substring(i + 1);
      24                totalCount += 1 + (String.IsNullOrEmpty(mantissa) ? 0 : Convert.ToInt64(mantissa));
      25                goto case -1;
      26           case 1//num>digit
      27                totalCount += (Int64)Math.Pow(10, s.Length-i-1);
      28                goto case -1;
      29        }

      30   }

      31   return totalCount;
      32}

      33//調用
      34Int64 count = Calc(number,'1');


          直接從數字n上就可以得出結果,時間復雜度O(1)。
          離開了人腦,“電腦”只是一坨廢鐵,別把啥東西都扔給它干,讓廢鐵干它該干的活兒吧...

       

      延伸思考:
      1. 給出一個正整數n,求解1到n這些數對應的8進制中1出現的次數;
      2. 給出一個正整數n,求解1到n這些數對應的16進制中A出現的次數;

       

      posted on 2008-10-19 23:02  Silent Void  閱讀(2324)  評論(4)    收藏  舉報

      主站蜘蛛池模板: 色婷婷久久综合中文久久一本| 亚洲精品一区二区五月天| 临桂县| 久久九九99这里有视频| 被拉到野外强要好爽| 91福利一区福利二区| 免费无码va一区二区三区| 91精品国产吴梦梦在线观看永久| 日韩精品成人一区二区三| 欧美videosdesexo吹潮| 亚洲av无码一区二区三区网站| 99视频偷窥在线精品国自产拍| 国产三级精品三级色噜噜| 亚洲AV成人片不卡无码| 人妻中出无码中字在线| 国产成人精品一区二三区| 精品无码人妻| 久久亚洲国产品一区二区| 涿州市| 久久精品国产99久久久古代| 思思久99久女女精品| 秋霞无码久久久精品| 毛片内射久久久一区| 国产97人人超碰CAO蜜芽PROM| 精品国产色情一区二区三区| 成人国产精品日本在线观看| 亚洲av区一区二区三区| 国产熟睡乱子伦视频在线播放| 亚洲人成电影网站色mp4| 国产农村老熟女国产老熟女 | 亚洲精品久综合蜜| 内射囯产旡码丰满少妇| 午夜国产理论大片高清| 久久国产精品成人免费| 欧美videos粗暴| 日韩精品一区二区亚洲专区| 国产色a在线观看| 亚洲熟妇av综合一区二区| 麻豆tv入口在线看| 久久精品国产99精品亚洲| 亚洲午夜福利AV一区二区无码|