Kotlin中多行数据的最优读取方法及不规则行规范处理问询
Kotlin 高效读取规则/不规则整数行的优化方案
一、每行固定3个整数的最优实现
如果确定输入每行都是3个整数,你可以用更符合Kotlin风格的批量处理方式,兼顾可读性与性能:
懒加载序列处理(适合小到中等数据量)
val data = generateSequence { readlnOrNull() } .take(n) .map { line -> // 处理任意空白分隔,避免多空格导致的空元素问题 val nums = line.split("\\s+".toRegex()).map(String::toInt) val (a, b, c) = nums Triple(a, b, c) } .toList()
generateSequence配合readlnOrNull可安全处理输入结束的情况,take(n)精准获取指定行数,最终转成Triple列表方便后续批量操作。
缓冲流读取(适合大数据量)
数据量较大时,BufferedReader能显著提升读取速度:
BufferedReader(InputStreamReader(System.`in`)).use { reader -> val data = List(n) { val nums = reader.readLine().split("\\s+".toRegex()).map(String::toInt) val (a, b, c) = nums Triple(a, b, c) } }
use块自动关闭流,无需手动处理资源释放,List(n)的初始化方式比传统for循环更简洁。
二、每行2或3个整数的简洁实现
针对不规则输入格式,可借助Kotlin语法特性避免繁琐的if判断:
方法1:用getOrElse直接处理默认值
val data = generateSequence { readlnOrNull() } .take(n) .map { line -> val nums = line.split("\\s+".toRegex()).map(String::toInt) val x = nums[0] val y = nums[1] val z = nums.getOrElse(2) { 0 } // 无第三个元素时取默认值0 Triple(x, y, z) } .toList()
一行代码完成默认值赋值,省去冗余条件判断。
方法2:扩展List解构支持默认值
如果需要复用解构逻辑,给List<Int>扩展第三个解构组件,自带默认值:
// 全局扩展函数,可放在工具类中 operator fun List<Int>.component3(): Int = getOrElse(2) { 0 } // 使用时直接解构,和规则格式写法几乎一致 for (i in 0 until n) { val nums = readln().split("\\s+".toRegex()).map(String::toInt) val (x, y, z) = nums // 直接使用x、y、z,z默认是0 }
这种方式让代码风格统一,无需额外处理逻辑,可读性拉满。
方法3:缓冲流批量处理版本
适配大数据量场景的写法:
BufferedReader(InputStreamReader(System.`in`)).use { reader -> val data = List(n) { val nums = reader.readLine().split("\\s+".toRegex()).map(String::toInt) Triple(nums[0], nums[1], nums.getOrElse(2) { 0 }) } }
额外优化点
- 用
"\\s+".toRegex()代替' '作为分隔符,可处理任意数量的空格、制表符等空白字符,避免输入格式不规范导致的转换错误。 - 若输入可能存在空行,可在
map前添加.filter { it.isNotBlank() }过滤无效行。
内容的提问来源于stack exchange,提问作者bublik
相关产品推荐
相关产品推荐

