给定一个十进制正整数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>