給定一個十進制正整數N,寫下從1開始,到N的所有整數,然后數一下其中出現的所有“1”的個數.
暴力解法
最簡單的辦法就是遍歷,分別統計每個數字出現的次數:
<pre><code>` func sumls(num:Int) -> Int {
var count:Int = 0
for i in 1...num {
var temp:Int = i
while temp != 0 {
count += temp % 10 == 1 ? 1 : 0
temp /= 10
}
}
return count
}`</code></pre>
數學解法
數學解法需要比較常的分析,忽略證明過程,簡單給出邏輯如下:
對于數abcde,c這位出現1的次數分以下情況:
1.若c == 0,結輪是 ab * 100;
2.若c == 1,結論是(ab)* 100 + de + 1;
3.若c > 1,結論是(ab + 1)* 100;
<pre><code>` func sumlsSimple(num:Int) -> Int {
if num <= 0 {
return 0
}
var factor = 1
var lowNum:Int = 0
var curNum:Int = 0
var highNum:Int = 0
var count:Int = 0
let n:Int = num
while n / factor != 0 {
lowNum = n - (n / factor) * factor
curNum = (n / factor) % 10
highNum = n / (factor * 10)
if curNum == 0 {
count += highNum * factor
} else if curNum == 1 {
count += highNum * factor + lowNum + 1
} else {
count += (highNum + 1) * factor
}
factor *= 10
}
return count
}`</code></pre>
通用解法
假設求解的不是1的數目,而是其他數字呢,限制范圍1~9,第二種解法稍微修改即可.
<pre><code>` func sumlsCommon(num:Int,target:Int) -> Int {
if num <= 0 || (target < 1 || target > 9){
return 0
}
var factor = 1
var lowNum:Int = 0
var curNum:Int = 0
var highNum:Int = 0
var count:Int = 0
let n:Int = num
while n / factor != 0 {
lowNum = n - (n / factor) * factor
curNum = (n / factor) % 10
highNum = n / (factor * 10)
if curNum < target {
count += highNum * factor
} else if curNum == target {
count += highNum * factor + lowNum + 1
} else {
count += (highNum + 1) * factor
}
factor *= 10
}
return count
}`</code></pre>
測試代碼:
<pre><code>var maxNum:Int = 123 var statisResult:Int = statis.sumls(num: maxNum) var statisResult2:Int = statis.sumlsSimple(num: maxNum) var statisResult3:Int = statis.sumlsCommon(num: maxNum, target: 2) print("FlyElephant--1...\(maxNum)中1的個數---\(statisResult)---\(statisResult2)") print("FlyElephant--1...\(maxNum)中2的個數---\(statisResult3)")
</code></pre>