不使用数组获取Kotlin程序启动控制台参数的方法求助
问题
我正在做学校项目,要实现两种归并排序算法:一种只能用数组,另一种绝对不能用数组。前者靠fun main(args: Array<String>)拿控制台启动参数(比如敲kotlin JoinFiles1.kt Output.txt Input_1.txt ... Input_n.txt)来处理文件,但后者因为不能用数组,完全不知道该怎么读取控制台传的文件名,试过BufferedReader,但还是没搞明白。
下面是我现在写的基于数组/列表的版本代码:
fun main(args: Array<String>) { // 读取所有输入文件中的单词并合并到列表中 var nficheiros = args.toMutableList() var palavras = mutableListOf<String>() for (nficheiro in nficheiros) { val file = File(nficheiro) file.forEachLine { line -> palavras.add(line) } } mergeSort(palavras) // 去重,只保留每个单词的一个实例 var unicas = mutableListOf<String>() for (palavra in palavras) { if (!unicas.contains(palavra)) { unicas.add(palavra) } } // 将结果写入输出文件 val pw = createWriter(args[0]) unicas.forEach { palavra -> pw.println(palavra) } } // 用于排序字符串可变列表的归并排序算法 fun mergeSort(mList: MutableList<String>) { if (mList.size > 1) { val meio = mList.size / 2 val esq = mList.subList(0, meio) val dir = mList.subList(meio, mList.size) mergeSort(esq) mergeSort(dir) var i = 0 var j = 0 var k = 0 while (i < esq.size && j < dir.size) { if (esq[i] <= dir[j]) { mList[k] = esq[i] i++ } else { mList[k] = dir[j] j++ } k++ } while (i < esq.size) { mList[k] = esq[i] i++ k++ } while (j < dir.size) { mList[k] = dir[j] j++ k++ } } }
解决办法
要在不用数组的前提下读取控制台参数,分两种情况处理:
情况1:允许用main的args但不允许用数组存储数据
如果只是禁止用数组存业务数据或做核心逻辑,那完全可以直接遍历args参数,不用转成列表或数组存储,逐个处理每个文件名就行:
fun main(args: Array<String>) { // 第一个参数是输出文件 val outputFile = args[0] // 从第二个参数开始逐个处理输入文件,不把所有文件名存到数组/列表里 // 注意:这里的palavras如果也不能用列表,得换成自定义链表 var palavras = mutableListOf<String>() for (index in 1 until args.size) { val fileName = args[index] val file = File(fileName) file.forEachLine { line -> palavras.add(line) } } // 后续的归并排序要改成基于链表的实现,不能用列表/数组 // ... }
情况2:完全禁止任何Array类型(包括main的args)
如果要求连main的args数组都不能碰,那可以让用户通过标准输入逐行输入文件名,最后用空行结束输入:
fun main() { // 去掉args参数,不接收数组 println("输入输出文件名:") val outputFile = readln().trim() println("输入输入文件名(每行一个,输空行结束):") // 同样,palavras要换成链表 var palavras = mutableListOf<String>() while (true) { val fileName = readln().trim() if (fileName.isEmpty()) break val file = File(fileName) file.forEachLine { line -> palavras.add(line) } } // 归并排序必须用链表实现 // ... }
关键:无数组的归并排序实现
既然不能用数组,你得把归并排序改成基于链表的版本,比如自定义一个Node类:
class Node(val value: String, var next: Node? = null) fun mergeSort(head: Node?): Node? { if (head?.next == null) return head // 快慢指针找中间节点 var slow = head var fast = head.next while (fast?.next != null) { slow = slow?.next fast = fast.next?.next } val mid = slow?.next slow?.next = null // 拆分链表 val left = mergeSort(head) val right = mergeSort(mid) return merge(left, right) } fun merge(left: Node?, right: Node?): Node? { val dummy = Node("") var current = dummy var l = left var r = right while (l != null && r != null) { if (l.value <= r.value) { current.next = l l = l.next } else { current.next = r r = r.next } current = current.next!! } current.next = l ?: r return dummy.next }
这样整个流程就完全不依赖数组,用链表来存储和排序数据了。
内容的提问来源于stack exchange,提问作者nuno
相关产品推荐
相关产品推荐

