有个4位数,千位数等于(这个4位数中0的个数),百位数为1的个数,十位数为2的个数,个位数为3的个数。求符合这个规则的所有4位数。
如果改为7位数,最高位为0的个数,次高位为1的个数,依次类推,结果又如何?
由于数学功底有限,用数学方法始终想不出思路来。(路过的数学牛人帮忙一下哦)
只想出了一个笨招:遍历1000到9999的所有数,一个个判断是否符合要求。与其苦思冥想不得巧妙数学解,不如用这个笨方法花一两分钟编个程序让计算机算算。
def find(int digitCount) {
((10 ** (digitCount - 1))..(10 ** digitCount - 1)).findAll {
final digits = it.toString().padLeft(digitCount, "0").collect { it.toInteger() }
(0..<digits.size()).every { digits[it] == digits.count(it) }
}
}
assert [1210, 2020] == find(4)
assert [3211000] == find(7)
程序使用函数式思维,提高代码的可读性和简洁性。虽然方法笨了点,但程序简单,2分钟完成代码编写,计算机只需几秒即可算出答案。
这里也得到一个收获:不要只注重算法和运行效率,有时候开发效率也很重要,甚至更加经济。
觉得运行效率不高的话,可以采用多核编程。我的计算机是四核的,运行效率可以提高四倍。如下代码所示:
import static groovyx.gpars.GParsPool.withPool
def findParallel(int digitCount) {
((10 ** (digitCount - 1))..(10 ** digitCount - 1)).findAllParallel {
final digits = it.toString().collect { it.toInteger() }
(0..<digits.size()).every { digits[it] == digits.count(it) }
}
}
withPool {
println findParallel(7)
}
单线程版本花了53.192 s,多核版本花了16.864 s,运行效率提升3倍多。
这里用的线程池为Fork/Join Poll (GParsPool),效率较高。如果改为Executor Pool,也就是将第一行的import中GParsPool改为GParsExecutorsPool,则运行需要45.775 s。
---------------------- 本博客所有内容均为原创,转载请注明作者和出处 -----------------------
作者:刘文哲
联系方式:liuwenzhe2008@qq.com
博客:http://blog.csdn.net/liuwenzhe2008