53

家、ロッカーのドア、ホテルの部屋などに番号を付けるために使用される金属製の数字を販売していると想像してください。顧客がドア/家に番号を付ける必要がある場合、出荷する各数字の数を見つける必要があります。

  • 1~100
  • 51~300
  • 1 から 2,000、左側にゼロ

明らかな解決策は、最初の数字から最後の数字までループを実行し、カウンターを左にゼロがある場合とない場合の文字列に変換し、各桁を抽出して、それをインデックスとして使用して 10 個の整数の配列をインクリメントすることです。

整数範囲全体をループすることなく、これを解決するより良い方法があるのではないかと思います。

任意の言語または疑似コードでのソリューションを歓迎します。


編集:

Answers review
John at CashCommonsWayne Conradは、私の現在のアプローチは適切で十分に高速であるとコメントしています。ばかげた例えを使ってみましょう: チェス盤のマスを 1 分以内で数えるタスクが与えられた場合、マスを 1 つずつ数えることでタスクを完了することができますが、より良い解決策は、面と面を数えることです。後で建物内のタイルを数えるように求められる可能性があるため、乗算を行います。
Alex Reisnerは、残念ながら、この問題には関係ないように思われる非常に興味深い数学的法則を指摘しています。
Andresは、私が使用しているのと同じアルゴリズムを提案していますが、部分文字列ではなく %10 操作で数字を抽出しています。
CashCommonsのジョンphordは、必要な桁数を事前に計算し、それらをルックアップ テーブルに格納するか、生の速度のために配列に格納することを提案しています。これは、固定された絶対的な移動不可能な最大整数値がある場合に適したソリューションになる可能性があります。私はそれらのうちの1つを見たことがありません。
高性能マークストレーナは、さまざまな範囲に必要な桁数を計算しました。100万の結果は割合があるように見えますが、他の数の結果は異なる割合を示しています.
ストレーナは、10 の累乗である数の桁数を数えるために使用できる数式をいくつか見つけました。 Robert Harveyは、MathOverflow に質問を投稿した非常に興味深い経験をしました。数学者の 1 人が、数学表記法を使用して解を書きました。
アーロノート数学を使用してソリューションを開発し、テストしました。それを投稿した後、彼は Math Overflow に由来する数式を見直し、そこに欠陥を見つけました (Stackoverflow を指してください:)。
noahlavineはアルゴリズムを開発し、疑似コードで提示しました。

新しい解決策
すべての回答を読み、いくつかの実験を行った後、1 から 10 n -1 までの整数の範囲について次のことがわかりました。

  • 1~9の数字はn×10 (n-1)個必要
  • 数字 0 の場合、先行ゼロを使用しない場合、n*10 n-1 - ((10 n -1) / 9) が必要です
  • 数字 0 の場合、先行ゼロを使用する場合、n*10 n-1 - n が必要です

最初の式はストレーナーによって(おそらく他の人によって)発見され、他の2つは試行錯誤によって発見されました(ただし、他の回答に含まれる場合があります)。

たとえば、n = 6 の場合、範囲は 1 ~ 999,999 です。

  • 1 から 9 の数字には、それぞれ 6*10 5 = 600,000 が必要です
  • 先行ゼロなしの数字 0 の場合、6*10 5 – (10 6 -1)/9 = 600,000 - 111,111 = 488,889が必要です。
  • 数字 0 の場合、先頭にゼロがある場合、6*10 5 – 6 = 599,994が必要です。

これらの数値は、ハイパフォーマンス マークの結果を使用して確認できます。

これらの式を使用して、元のアルゴリズムを改善しました。整数の範囲の最初の数字から最後の数字までループしますが、10 の累乗である数字が見つかった場合は、式を使用して桁数に追加し、1 から 9 までの全範囲の数量をカウントします。または1から99または1から999など。疑似コードのアルゴリズムは次のとおりです。

integer First,Last //範囲内の最初と最後の数字
integer Number //ループ内の現在の番号
integer Power //Power は式の 10^n の n です
integer Nines //Nines は 10^n - 1, 10^5 - 1 = 99999 の結果です
integer Prefix //数値の最初の桁。14,200 の場合、プレフィックスは 142 です
array 0..9 Digits //すべての桁のカウントを保持します

FOR Number = 最初から最後まで
  CALL TallyDigitsForOneNumber WITH Number,1 //各桁のカウントを集計します
                                              // 数値を 1 ずつ増やします
  //最適化の開始。コメントは Number = 1,000 および Last = 8,000 に対するものです。
  累乗 = 数字の末尾にゼロ // 1,000 の場合、累乗 = 3
  IF Power > 0 //数字の末尾が 0 00 000 など
    9 = 10^Power-1 //9 = 10^3 - 1 = 1000 - 1 = 999
    IF Number+Nines <= Last //1,000+999 < 8,000 の場合、フルセットを追加
      Digits[0-9] += Power*10^(Power-1) //数字 0 ~ 9 に 3*10^(3-1) = 300 を加算
      Digits[0] -= -Power //桁 0 を調整します (先行ゼロ式)
      Prefix = Number の最初の桁 //1000 の場合、接頭辞は 1 です
      CALL TallyDigitsForOneNumber WITH Prefix,Nines //それぞれの数を集計します
                                                     //プレフィックスの数字、
                                                     //999ずつインクリメント
      Number += Nines //ループ カウンターを 999 サイクルインクリメントする
    ENDIF
  ENDIF
  //最適化終了
ENDFOR  

サブルーチン TallyDigitsForOneNumber パラメータ 数値、カウント
  繰り返す
    桁数 [ 数値 % 10 ] += カウント
    数 = 数 / 10
  UNTIL番号= 0

たとえば、範囲が 786 から 3,021 の場合、カウンターはインクリメントされます。

  • 786 ~ 790 を 1 ずつ (5 サイクル)
  • 790 から 799 まで 9 ずつ (1 サイクル)
  • 799 から 800 まで 1 つずつ
  • 800から899まで99ずつ
  • 899 から 900 まで 1 つずつ
  • 900から999まで99ずつ
  • 999 か​​ら 1000 まで 1 つずつ
  • 1000年から1999年までの999年まで
  • 1999 年から 2000 年までの 1 つずつ
  • 2000年から2999年までの999年まで
  • 2999年から3000年まで1ずつ
  • 3000~3010まで1ずつ(10サイクル)
  • 3010 年から 3019 年までの 9 回分 (1 サイクル)
  • 3019年から3021年まで1回ずつ(2サイクル)

合計: 28 サイクル 最適化なし: 2,235 サイクル

このアルゴリズムは先行ゼロなしで問題を解決することに注意してください。先行ゼロで使用するには、ハックを使用しました。

先頭にゼロを付けた 700 から 1,000 の範囲が必要な場合は、10,700 から 11,000 のアルゴリズムを使用してから、桁 1 のカウントから 1,000 - 700 = 300 を引きます。

ベンチマークとソースコード

元のアプローチ、%10 を使用した同じアプローチ、およびいくつかの大きな範囲に対する新しいソリューションをテストしたところ、次の結果が得られました。

元の 104.78 秒
%10 で 83.66
10 の累乗で 0.07

ベンチマーク アプリケーションのスクリーンショット: (ソース: clarion.sca.mx )
代替テキスト

完全なソース コードを表示したり、ベンチマークを実行したりしたい場合は、次のリンクを使用してください。

受け入れられた回答

noahlavine の解決策は正しいかもしれませんが、疑似コードをたどることができませんでした。詳細が欠落しているか、完全に説明されていないと思います。

Aaronaught のソリューションは正しいようですが、コードが複雑すぎて私の好みには合いません。

私はストレイナーの答えを受け入れました。なぜなら、彼の考え方が私をこの新しいソリューションの開発に導いたからです。

4

11 に答える 11

10

このような問題には、明確な数学的解決策があります。値が最大桁数までゼロで埋められていると仮定して (そうではありませんが、後でそれを補正します)、その理由を考えてみましょう:

  • 0 ~ 9 の各桁は 1 回出現します
  • 0 ~ 99 の各桁は 20 回発生します (位置 1 で 10 回、位置 2 で 10 回)。
  • 0 ~ 999 の各桁は 300 回発生します (P1 で 100x、P2 で 100x、P3 で 100x)。

任意の数字の明らかなパターンは、範囲が 0 から 10 の累乗までの場合、N * 10 N-1です。ここで、Nは 10 の累乗です。

範囲が 10 の累乗でない場合はどうなりますか? 最小の 10 乗から始めて、徐々に上げていきます。対処する最も簡単なケースは、399 のような最大値です。100 の倍数ごとに、各桁が少なくとも20 回出現することがわかっていますが、最上位桁位置に出現する回数を補正する必要があります。これは、数字 0 ~ 3 では正確に 100 になり、他のすべての数字では正確にゼロになります。具体的には、追加する余分な量は、該当する桁に対して10 Nです。

これを数式に入れると、10 の累乗の倍数よりも 1 小さい上限 (399、6999 など) の場合、次のようになります。 M * N * 10 N-1 + iif(d <= M, 10 N , 0)

あとは残りを処理するだけです (これをRと呼びます)。例として 445 を取り上げます。これは、399 に 400 ~ 445 の範囲を加えた結果です。この範囲では、MSD はR回以上発生し、すべての桁 (MSD を含む) も範囲 [0 - R ] と同じ周波数で発生します。

ここで、先頭のゼロを補正する必要があります。このパターンは簡単です。

10 N + 10 N-1 + 10 N-2 + ... + **10 0

更新:このバージョンでは、「パディング ゼロ」、つまり残りを処理する際の中間位置のゼロ ([4 0 0, 4 0 1, 4 0 2, ...]) が正しく考慮されます。パディングゼロを理解するのは少し見にくいですが、修正されたコード (C スタイルの疑似コード) で処理されます。

function countdigits(int d, int low, int high) {
    return countdigits(d, low, high, false);
}

function countdigits(int d, int low, int high, bool inner) {
    if (high == 0)
        return (d == 0) ? 1 : 0;

    if (low > 0)
        return countdigits(d, 0, high) - countdigits(d, 0, low);

    int n = floor(log10(high));
    int m = floor((high + 1) / pow(10, n));
    int r = high - m * pow(10, n);
    return
        (max(m, 1) * n * pow(10, n-1)) +                             // (1)
        ((d < m) ? pow(10, n) : 0) +                                 // (2)
        (((r >= 0) && (n > 0)) ? countdigits(d, 0, r, true) : 0) +   // (3)
        (((r >= 0) && (d == m)) ? (r + 1) : 0) +                     // (4)
        (((r >= 0) && (d == 0)) ? countpaddingzeros(n, r) : 0) -     // (5)
        (((d == 0) && !inner) ? countleadingzeros(n) : 0);           // (6)
}

function countleadingzeros(int n) {
      int tmp= 0;
      do{
         tmp= pow(10, n)+tmp;
         --n;
         }while(n>0);
         return tmp;
         }

function countpaddingzeros(int n, int r) {
    return (r + 1) * max(0, n - max(0, floor(log10(r))) - 1);
}

ご覧のとおり、少し見にくくなっていますが、それでも O(log n) 時間で実行されるため、数十億の数値を処理する必要がある場合でも、すぐに結果が得られます。:-) [0 - 1000000] の範囲で実行すると、High-Performance Mark によって投稿されたものとまったく同じ分布が得られるので、それが正しいとほぼ確信しています。

参考までに、変数の理由はinner、先頭のゼロ関数が既に再帰的であるため、 の最初の実行でのみカウントできるためですcountdigits

更新 2:コードが読みにくい場合に備えて、return ステートメントの各行が何countdigitsを意味するかについての参照を次に示します (インライン コメントを試しましたが、コードがさらに読みにくくなりました)。

  1. 10 の最大累乗までの任意の桁の頻度 (0 ~ 99 など)
  2. 10 の最高乗数 (100-399) の任意の倍数を超える MSD の頻度
  3. 残りの数字の頻度 (400-445、R = 45)
  4. 残りのMSDの追加頻度
  5. 残りの範囲 (404、405...) の中間位置のゼロをカウントします。
  6. 先頭のゼロを 1 回だけ減算する (最も外側のループで)
于 2010-01-14T03:52:52.673 に答える
8

数値が範囲内にあり、開始番号と終了番号があるソリューションが必要であると想定しています。開始番号から開始し、終了番号に到達するまでカウントアップすることを想像してみてください。これは機能しますが、遅くなります。高速なアルゴリズムの秘訣は、10^x の桁を 1 桁上げて他のすべてを同じに保つには、その前のすべての桁を 10^x 回とすべての桁 0 を使用する必要があることを理解することだと思います。 -9 10^(x-1) 回。(ただし、x 番目の桁を超える桁上げがカウントに含まれている可能性があります。以下でこれを修正します。)

これが例です。523 から 1004 まで数えているとします。

  • まず、523 から 524 まで数えます。これは、数字の 5、2、および 4 をそれぞれ 1 回使用します。
  • 次に、524 から 604 まで数えます。右端の数字はすべての数字を 6 循環するため、各数字の 6 つのコピーが必要です。2 桁目は 2 桁目から 0 桁目までをそれぞれ 10 回繰り返します。3 桁目は 6 5 回と 5 100-24 回です。
  • 3 番目に、604 から 1004 まで数えます。右端の数字は 40 サイクルなので、各数字の 40 のコピーを追加します。右から 2 番目の数字は 4 サイクルなので、各数字の 4 つのコピーを追加します。一番左の数字は、7、8、9 をそれぞれ 100 回、さらに 0 を 5 回、100 - 6 を 5 回します。最後の数字は 1 5 回です。

最後のビットを高速化するには、右端の 2 か所について見てください。各桁を 10 + 1 回使用します。一般に、1 + 10 + ... + 10^n = (10^(n+1) - 1)/9 であり、これを使用してカウントをさらに高速化できます。

私のアルゴリズムは、開始番号から終了番号まで (基数 10 のカウントを使用して) カウントアップしますが、上記の事実を使用してすばやく実行します。開始番号の桁を最下位から最上位まで反復し、各桁でカウントアップして、その桁が終了番号の桁と同じになるようにします。各ポイントで、n はキャリーに到達する前に実行する必要があるアップカウントの数であり、m は後で実行する必要がある数です。

ここで、疑似コードが言語としてカウントされると仮定しましょう。それでは、私がすることは次のとおりです。

開始番号と終了番号を数字配列 start[] と end[] に変換します
のコピー数を格納する 10 個の要素を持つ配列 counts[] を作成します
     必要な各桁

開始番号を右から左に繰り返します。i桁目で、
    この桁から取得するために数え上げる必要がある桁数を d とする
        末尾番号の i 桁目まで。(つまり、同等の
        数字 mod 10)
    count の各エントリに d * (10^i - 1)/9 を追加します。
    この桁の右側にあるすべての桁の数値を m とすると、
        n は 10^i - m です。
    開始番号の左から e までの各桁 e に対して
        i 桁目、その桁のカウントに n を追加します。
    for j in 1 から d
        桁上げを含め、i 番目の桁を 1 ずつ増やします
        開始番号の左から e までの各桁
            i 番目の数字、その数字のカウントに 10^i を追加します
    開始番号の左から e までの各桁 e に対して
        i 桁目、その桁のカウントに m を追加します。
    開始番号の i 桁目を末尾の i 桁に設定する
        番号。

ああ、i の値は毎回 1 ずつ増加するため、古い 10^i を追跡し、毎回累乗するのではなく、10 を掛けて新しい値を取得します。

于 2010-01-13T20:01:37.120 に答える
7

数字から数字を取り出すには、mod を実行できない場合にのみ、コストのかかる文字列変換を行う必要があります。数字は、次のような数字から最も迅速にプッシュできます。

feed=number;
do
{ digit=feed%10;
  feed/=10; 
  //use digit... eg. digitTally[digit]++;
  }
while(feed>0)

そのループは非常に高速である必要があり、数字を集計する最も簡単な方法として、最初から最後までの数字のループ内に配置できます。

より高速に移動するには、より広い範囲の数値について、0 から number*10^significance までのすべての数字を集計する最適化された方法を探しています (最初から最後までバゾグルします)

これは、いくつかの単一の有効数字の数字の集計を示す表です..これらには0が含まれていますが、上位の値自体ではありません.-これは見落としでしたが、パターンを確認するのが少し簡単かもしれません(上位の数字がここにありません)これらの集計には末尾のゼロは含まれません。

  1 10 100 1000 10000 2 20 30 40 60 90 200 600 2000  6000

0 1 1  10  190  2890  1  2  3  4  6  9  30 110  490  1690
1 0 1  20  300  4000  1 12 13 14 16 19 140 220 1600  2800
2 0 1  20  300  4000  0  2 13 14 16 19  40 220  600  2800
3 0 1  20  300  4000  0  2  3 14 16 19  40 220  600  2800
4 0 1  20  300  4000  0  2  3  4 16 19  40 220  600  2800
5 0 1  20  300  4000  0  2  3  4 16 19  40 220  600  2800
6 0 1  20  300  4000  0  2  3  4  6 19  40 120  600  1800
7 0 1  20  300  4000  0  2  3  4  6 19  40 120  600  1800
8 0 1  20  300  4000  0  2  3  4  6 19  40 120  600  1800
9 0 1  20  300  4000  0  2  3  4  6  9  40 120  600  1800

編集:私の元の考えを片付けます:

0 (含まれる) から poweroTen(notinc) までの集計を示すブルート フォース テーブルから、10 乗の大桁が表示されます。

increments tally[0 to 9] by md*tp*10^(tp-1)
increments tally[1 to md-1] by 10^tp
decrements tally[0] by (10^tp - 10) 
(to remove leading 0s if tp>leadingzeros)
can increment tally[moresignificantdigits] by self(md*10^tp) 
(to complete an effect)

これらの集計調整が各有効桁に適用された場合、集計は 0 から end-1 までカウントされるように変更する必要があります。

調整を反転して、前の範囲 (開始番号) を削除できます。

完全でテスト済みの回答をありがとうAaronaught。

于 2010-01-14T02:35:05.990 に答える
6

これは非常に悪い答えです。投稿するのが恥ずかしいです。Mathematica に、1 から 1,000,000 までのすべての数字で使用されている数字を集計するように依頼しました。先頭に 0 はありません。これが私が得たものです:

0   488895
1   600001
2   600000
3   600000
4   600000
5   600000
6   600000
7   600000
8   600000
9   600000

次にホームセンターで販売するためにスティッキー ディジットを注文するときは、これらの比率で注文してください。間違いはありません。

于 2010-01-14T03:00:51.287 に答える
5

は Math Overflow でこの質問をしましたが、そのような単純な質問をしたことで怒られました。ユーザーの 1 人が私に同情し、もし私がThe Art of Problem Solvingに投稿したら、彼はそれに答えるだろうと言いました。だから私はしました。

彼が投稿した回答は次のとおりです
。 http://www.artofproblemsolving.com/Forum/viewtopic.php?p=1741600#1741600

恥ずかしいことに、私の数学は彼が投稿したものを理解するには不十分です (彼は 19 歳です... とても気のめいるようです)。私は本当にいくつかの数学の授業を受ける必要があります。

明るい面では、方程式は再帰的であるため、数学を理解している人が数行のコードで再帰関数に変換するのは簡単なことです。

于 2010-01-14T00:34:12.937 に答える
3

この質問には受け入れられた答えがあることは知っていますが、私は就職の面接のためにこのコードを書くことを任されており、高速でループを必要とせず、必要に応じて先頭のゼロを使用または破棄できる代替ソリューションを思いついたと思います.

実際には非常に単純ですが、説明するのは簡単ではありません。

最初のn個の数字を列挙すると

     1
     2
     3

     .
     .
     .


     9
    10
    11

通常、最初の部屋番号から最後の部屋番号まで必要な桁数を左から右に数え始めるので、上記の例では 1 が 1 つ、2 が 1 つ、3 が 1 つ... 9 が 1 つ、1 が 2 つ 0 が 1 つになります。 、4つの1など。私が見たほとんどのソリューションは、このアプローチを使用して、速度を上げるためにいくつかの最適化を行いました。

私がしたことは、百、十、単位のように、列を縦に数えることでした。あなたは最大の部屋番号を知っているので、1 つの除算で百の列にある各桁の数を計算し、次に再帰的に 10 の列の数を計算できます。その後、必要に応じて先頭のゼロを減算できます。

Excel を使用して数値を書き出すが、数値の桁ごとに別の列を使用すると視覚化が容易になります。

     A    B    C
     -    -    -
     0    0    1  (assuming room numbers do not start at zero)
     0    0    2
     0    0    3
     .
     .
     .
     3    6    4
     3    6    5
     .
     .
     .

     6    6    9
     6    7    0
     6    7    1

     ^
     sum in columns not rows

したがって、最大の部屋番号が 671 の場合、100 の列には垂直方向に 100 個のゼロがあり、その後に 100 個の 1 が続き、最大 71 個の 6 が続きます。必要に応じて 100 個のゼロを無視します。これらはすべて先頭にあることがわかっているためです。

次に、10 の位まで再帰して同じ操作を実行します。10 のゼロの後に 10 の 1 が続き、6 回繰り返され、最後に 2 つの 7 になることがわかっています。ここでも、最初の 10 個のゼロが先頭にあることがわかっているので無視できます。最後に、必要に応じて最初のゼロを無視して、単位を実行します。

したがって、すべてが除算で計算されるループはありません。私は再帰を使用して、最大列 (この場合は数百) に達するまで列を「上」に移動し、その後、合計を下に戻します。

私はこれを C# で書きました。誰かが興味を持ち、ベンチマークのタイミングを行っていない場合は、コードを投稿できますが、最大 10^18 部屋の値については本質的に瞬時です。

ここまたは他の場所で言及されているこのアプローチを見つけることができなかったので、誰かにとって役立つかもしれないと考えました.

于 2015-05-28T14:59:33.183 に答える
1

多くの反復で生の速度が必要な場合は、ルックアップ テーブルを試してください。

  1. 2 次元の配列を作成します: 10 x max-house-number

    int nDigits[10000][10] ;   // Don't try this on the stack, kids!
  1. ゼロからその数値に到達するために必要な桁数を各行に入力します。
    ヒント: 前の行を開始点として使用します。

    n=0..9999:
       if (n>0) nDigits[n] = nDigits[n-1]
       d=0..9:
           nDigits[n][d] += countOccurrencesOf(n,d)   // 
  1. Number of digits "between" two numbers becomes simple subtraction.
       For range=51 to 300, take the counts for 300 and subtract the counts for 50.
       0's = nDigits[300][0] - nDigits[50][0]
       1's = nDigits[300][1] - nDigits[50][1]
       2's = nDigits[300][2] - nDigits[50][2]
       3's = nDigits[300][3] - nDigits[50][3]
       etc.
于 2010-01-15T18:01:59.343 に答える
1

これは正確な質問には答えませんが、ベンフォードの法則に従って最初の桁の分布に注目するのは興味深いことです。たとえば、数字のセットをランダムに選択すると、そのうちの 30% が "1" で始まりますが、これはやや直感に反します。

後続の桁を記述する分布については知りませんが、これを経験的に決定し、任意の範囲の数値に必要な概算桁数を計算するための簡単な式を考え出すことができるかもしれません.

于 2010-01-13T20:15:19.827 に答える
1

「より良い」が「より明確」を意味する場合、私はそれを疑います. それが「より速い」という意味であれば、そのとおりですが、やむを得ない必要性がない限り、より明確なアルゴリズムの代わりにより高速なアルゴリズムを使用することはありません。

#!/usr/bin/ruby1.8

def digits_for_range(min, max, leading_zeros)
  bins = [0] * 10
  format = [
    '%',
    ('0' if leading_zeros),
    max.to_s.size,
    'd',
  ].compact.join
  (min..max).each do |i|
    s = format % i
    for digit in s.scan(/./)
      bins[digit.to_i] +=1  unless digit == ' '
    end
  end
  bins
end

p digits_for_range(1, 49, false) 
# => [4, 15, 15, 15, 15, 5, 5, 5, 5, 5]

p digits_for_range(1, 49, true)
# => [13, 15, 15, 15, 15, 5, 5, 5, 5, 5]

p digits_for_range(1, 10000, false)
# => [2893, 4001, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000]

「犬が遅い」言語として知られる Ruby 1.8 は、上記のコードを 0.135 秒で実行します。これには、インタープリターのロードが含まれます。もっとスピードが必要でない限り、明白なアルゴリズムをあきらめないでください。

于 2010-01-13T21:39:13.103 に答える
0

各桁を分離し (例についてはこちらをご覧ください)、0 から 9 までのエントリを含むヒストグラムを作成し (数字に含まれる数字の数をカウントします)、求められた「数字」の数を掛けることができます。

しかし、あなたが探しているものではない場合、より良い例を挙げていただけますか?

編集:

今、私は問題を抱えていると思います。これを推測できると思います(疑似C):

int histogram[10];
memset(histogram, 0, sizeof(histogram));

for(i = startNumber; i <= endNumber; ++i)
{
    array = separateDigits(i);
    for(j = 0; k < array.length; ++j)
    {
        histogram[k]++;
    }
}

個別の数字は、リンクに機能を実装します。

ヒストグラムの各位置には、各桁の量があります。例えば

histogram[0] == total of zeros
histogram[1] == total of ones

...

よろしく

于 2010-01-13T19:47:05.387 に答える