You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

不使用数组获取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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 19:14:59