題3:統計數字
阿新 • • 發佈:2019-01-31
題目描述:
計算數字k在0到n中的出現的次數,k可能是0~9的一個值
例如n=12,在 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]中,我們發現1出現了5次 (1, 10, 11, 12)
思路一:我們可以用最簡單的辦法先嚐試一下,遍歷1到n中間的每個整數,對每個整數從低位到高位依次檢查,如果有k出現則計數器自加。
思路一最大的問題就是效率,當n非常大時,就需要很長的執行時間。想要提高效率,就要避開暴力法,從數字中找出規律。
思路二:來自《程式設計之美》
假設有一個5位數N=ABCDE,我們現在來考慮百位上出現2的次數,即:從0到ABCDE的數中,有多少個數的百位上是2。分析完它,就可以用同樣的方法去計算個位,十位,千位,萬位等各個位上出現2的次數。
第一種情況:當百位上的數C小於2時:
1)當百位c為0時,比如說12013,0到12013中哪些數的百位會出現2?我們從小的數起, 200~299, 1200~1299, 2200~2299, … , 11200~11299, 也就是固定低3位為200~299,然後高位依次從0到11,共12個。再往下12200~12299 已經大於12013,因此不再往下。所以,當百位為0時,百位出現2的次數只由更高位決定,等於更高位數字(12)x當前位數(100)=1200個。
2)當百位C為1時,比如說12113。分析同上,並且和上面的情況一模一樣。最大也只能到11200~11299,所以百位出現2的次數也是1200個。
上面兩步綜合起來,可以得到以下結論:
—>當某一位的數字小於2時,那麼該位出現2的次數為:更高位數字x當前位數
第二種情況:當百位上的數C等於2時:
當百位C為2時,比如說12213。那麼,我們還是有200~299, 1200~1299, 2200~2299, … , 11200~11299這1200個數,他們的百位為2。但同時,還有一部分12200~12213,共14個(低位數字+1)。所以,當百位數字為2時,百位出現2的次數既受高位影響也受低位影響,結論如下:
—>當某一位的數字等於2時,那麼該位出現2的次數為:更高位數字x當前位數+低位數字+1
第三種情況:當百位上的數C大於2時:
當百位C大於2時,比如說12313,那麼固定低3位為200~299,高位依次可以從0到12,這一次就把12200~12299也包含了,同時也沒低位什麼事情。因此出現2的次數是: (更高位數字+1)x當前位數。結論如下:
—>當某一位的數字大於2時,那麼該位出現2的次數為:(更高位數字+1)x當前位數
通過上述分析,我們可以得到以下規律:
當某一位的數字小於i時,那麼該位出現i的次數為:更高位數字x當前位數
當某一位的數字等於i時,那麼該位出現i的次數為:更高位數字x當前位數+低位數字+1
當某一位的數字大於i時,那麼該位出現i的次數為:(更高位數字+1)x當前位數
程式碼:
#include<iostream>
using namespace std;
class Solution
{
public:
int digitalCounts1(int n, int k)
{
int count = 0;
for(int i = 1; i <= n; i++)
{
intcurNum = i; //當前數字
while(curNum> 0) //當前數字每一位與1比較
{
int temp = curNum % 10; //取當前數字的個位數
if(temp == k)
count++;
curNum = curNum/10;
}
}
return count;
}
};
class Solution2
{
public:
int digitCounts2(int n, int k)
{
int result = 0;
int base = 1;
while (n/base > 0)
{
int cur = (n/base)%10;
int low = n - (n/base) * base;
int high = n/(base * 10);
if (cur == k)
{
result += high * base + low + 1;
} elseif (cur <k)
{
result += high * base;
} else
{
result += (high + 1) * base;
}
base *= 10;
}
return result;
}
};
int main()
{
Solution st1;
cout<<"--------- 呼叫方法1 -----------"<<endl;
cout<<"1到12中1出現的次數(12, 1)="<< st1.digitalCounts1(12, 1) <<endl;
cout<<"1到20中2出現的次數(20, 2)="<< st1.digitalCounts1(20, 2) <<endl;
cout<<"1到100中9出現的次數(100, 9)="<< st1.digitalCounts1(100, 9) <<endl;
cout<<endl;
cout<<"--------- 呼叫方法2 -----------"<<endl;
Solution2 st2;
cout<<"1到100中9出現的次數(100, 9)="<< st2.digitCounts2(100, 9) <<endl;
cout<<"1到12313中3出現的次數(12313, 3)="<< st2.digitCounts2(12313, 3) <<endl;
system("pause");
return 0;
}