1. 概述
在 Kotlin 开发中,我们经常需要处理数字操作,其中一项常见任务就是 反转一个整数。
本教程将介绍几种在 Kotlin 中反转数字的方法,并重点讲解如何处理一些常见陷阱,比如整数溢出问题。
2. 问题介绍
所谓反转数字,就是将一个整数的各个数字顺序反过来。例如:
- 输入:
12345
➜ 输出:54321
- 输入:
1000
➜ 输出:1
(去除前导零)
⚠️ 本文只讨论 正整数 的反转。负数处理可以在此基础上扩展,但不是本文重点。
我们将使用单元测试验证不同方法的正确性。
3. 使用数学运算(除法和取余)
最直接的方法是使用数学运算,通过循环不断从原始数字中提取个位数,拼接到结果中。
✅ 实现思路
- 初始化
result = 0
- 循环处理原始数字:
- 每次取余
n % 10
获取个位数 - 更新
result = result * 10 + 个位数
n = n / 10
去掉最后一位
- 每次取余
- 直到
n == 0
✅ 示例代码
fun reverseNumber(number: Int): Int {
var n = number
var result = 0
while (n > 0) {
result = 10 * result + n % 10
n = n / 10
}
return result
}
✅ 单元测试
assertEquals(6540321, reverseNumber(1230456))
assertEquals(1, reverseNumber(10000))
4. 改进为扩展函数
Kotlin 支持扩展函数,我们可以将反转函数写成 Int
的扩展方法,提升代码的可读性和调用的流畅性。
✅ 示例代码
fun Int.reverse(): Int {
var n = this
var result = 0
while (n > 0) {
result = 10 * result + n % 10
n = n / 10
}
return result
}
✅ 使用方式
assertEquals(4321, 1234.reverse())
assertEquals(1, 10000.reverse())
5. 处理整数溢出问题
Kotlin 的 Int
最大值是 2147483647
,某些数字反转后可能会超出这个范围,例如:
- 输入:
1234123409
➜ 反转后为9043214321
,超过了Int.MAX_VALUE
✅ 解决方案
将中间结果使用 Long
类型保存,并在每次循环中检查是否溢出。
✅ 示例代码
fun Int.reverse2(): Int {
var n = this
var result = 0L
while (n > 0) {
result = 10 * result + n % 10
require(result <= Int.MAX_VALUE) {
"Cannot reverse ${this@reverse2}! Cause: Int overflow"
}
n = n / 10
}
return result.toInt()
}
✅ 单元测试
assertThrows<IllegalArgumentException> { 1234123409.reverse2() }
6. 使用字符串转换方式
除了数学方法,我们也可以借助字符串操作来实现反转,代码更简洁,但需注意类型转换和溢出问题。
✅ 实现思路
- 将数字转为字符串
- 调用
reversed()
方法反转字符串 - 转回
Long
并检查是否溢出 - 返回
Int
✅ 示例代码
fun Int.reverse3(): Int {
val longNum = "$this".reversed().toLong()
require(longNum <= Int.MAX_VALUE) {
"Cannot reverse $this! Cause: Int overflow"
}
return longNum.toInt()
}
✅ 单元测试
assertEquals(4321, 1234.reverse3())
assertEquals(1, 10000.reverse3())
assertThrows<IllegalArgumentException> { 1234123409.reverse3() }
7. 总结与对比
方法 | 优点 | 缺点 |
---|---|---|
数学运算 | 高效、无额外内存占用 | 代码略复杂 |
扩展函数 | 语法优雅、调用方便 | 本质还是数学方法 |
字符串转换 | 代码简洁、易读 | 效率略低,需注意溢出 |
✅ 推荐:对于大多数场景,使用数学方法配合
Long
类型处理溢出是最稳妥的方式。
完整示例代码已托管在 GitHub:查看源码