16 Feb 2018
使用数组递增输出数字
一、题目
输入数字n,按顺序打印出从1到n位最大十进数的数值。比如输入3,则打印出1、2、3一直到最大三位数即999。
二、解题思路
这个题目看起来似乎很简单,但是事实上这个题目包含了一个隐藏很深的陷阱。当输入的位数非常大的时候,就可能会出现数据溢出。【大数问题】
递归实现
- 创建一个长度为n的数组,下标[0,1,2…(n - 1)]代表[最高位…最低位]。
- 创建一个递归循环,当下标没有大于n的时候,就递归调用;当大于等于的时候就开始打印数字。
循环实现
- 实现一个可以在数组内加1(包含进位)运算的方法。
Kotlin实现
fun main(args: Array<String>) {
// 测试
printNumByLoop(3)
printNumByLoop2(3)
// 边界测试
printNumByLoop(-1)
printNumByLoop2(-1)
printNumByLoop(0)
printNumByLoop2(0)
}
/**
* 使用递归的方式输出数字
*
* @param bits 位数
* */
fun printNumByLoop(bits: Int) {
if (bits < 1) throw RuntimeException("位数不能小于1")
val array = IntArray(bits)
/**
* 输出数字
*
* @param array 数字的数组
* */
fun printNum(array: IntArray) {
var index = 0 // 找第一个非零的元素
while (index < array.size && array[index] == 0) index++
for (i in index until array.size) print(array[i])
if (index < array.size) println() // 换行
}
fun printNumByLoop(index: Int, array: IntArray) {
if (index >= array.size) printNum(array)
else for (i in 0..9) {
// 初始化,从0开始初始化
array[index] = i
// 初始化下一位
printNumByLoop(index + 1, array)
}
}
printNumByLoop(0, array)
}
/**
* 非递归实现
*
* @param bits 数字的最大位数
*/
fun printNumByLoop2(bits: Int) {
// 输入值必须大于0
if (bits < 1) throw RuntimeException("位数不能小于1")
// 创建一个长度为n的数组
val arr = IntArray(bits)
// 为数组元素赋初始值
for (i in arr.indices) arr[i] = 0
/**
* 加1
*
* @param arr 待加数组
* @return 判断最高位是否有进位,如果有进位就返回true
*/
fun addOne(arr: IntArray): Boolean {
// 保存进位值,因为每次最低位加1
var carry = 1
// 数组的最高位的下标为0,最低位的下标为arr.size - 1
var index = arr.size
do {
--index
arr[index] += carry // 加上进位
carry = arr[index] / 10 // 计算高位的进位
arr[index] %= 10
} while (carry != 0 && index > 0)
// 如果index=0说明已经处理了最高位,carry>0说明最高位有进位,返回true
return carry > 0 && index == 0
}
// 求结果,如果最高位没有进位就一直进行处理
while (addOne(arr)) {
var index = 0 // 找到非零的位置
while (index < arr.size && arr[index] == 0) index++
for (i in index until arr.size) print(arr[i]) // 开始输出
if (index < arr.size) println() // 换行
}
}
输出结果
1
……省略……
999
Exception in thread "main" java.lang.RuntimeException: 位数不能小于1
at KDemo9Kt.printNumByLoop(KDemo9.kt:18)
at KDemo9Kt.main(KDemo9.kt:8)
Til next time,
LinkWorld
at 00:00