Menu
CoddyTech

回顾:优先队列

本课属于 Coddy Kotlin 学习旅程的“面向对象编程”单元。第 41 课,共 57 课。

challenge icon

挑战

中等

构建一个适用于任意可排序类型的优先队列。已提供 Prioritized(带有 priority)以及数据类 Job 和 Ticket。

  • TaskQueue<T : Prioritized> 提供 push(item)、pop() 和 peek(),用于移除或返回优先级最高的项(优先级相同时,返回最先推入的项),如果队列为空则返回 null;还提供 size、items()(按弹出顺序排列的只读快照)和 drain(n),后者最多弹出 n 项,并以 List<T> 的形式返回。
  • 泛型函数 countUrgent(queue, min) 接收一个包含任意可排序类型的队列,并返回其中优先级至少达到该值的项数。

提供的代码会读取命令 job build 3、ticket 17 5 ada、pop jobs、peek tickets、drain 2(针对 tickets)或 sizes,打印每条命令的响应,最后打印 urgent: ,后面跟着仍在队列中的紧急任务和票据。

你的代码应写在 TaskQueue.kt、Prioritized.kt、Job.kt 和 Ticket.kt 中。Main.kt 中包含提供的输入输出代码,不能修改。

亲手试试

fun main() {
    // 提供的输入/输出代码:保持原样
    val input = generateSequence(::readLine).toList()
    val jobs = TaskQueue<Job>()
    val tickets = TaskQueue<Ticket>()
    for (cmd in input) {
        val p = cmd.split(" ")
        when (p[0]) {
            "job" -> jobs.push(Job(p[1], p[2].toInt()))
            "ticket" -> tickets.push(Ticket(p[1].toInt(), p[2].toInt(), p[3]))
            "pop" -> println("popped " + (if (p[1] == "jobs") jobs.pop() else tickets.pop()))
            "peek" -> println("next " + (if (p[1] == "jobs") jobs.peek() else tickets.peek()))
            "drain" -> println("drained " + tickets.drain(p[1].toInt()).map { it.customer })
            else -> println("jobs ${jobs.size}, tickets ${tickets.size}")
        }
    }
    println("urgent: ${countUrgent(jobs, 4) + countUrgent(tickets, 4)}")
}

面向对象编程中的所有课

自己练习: Kotlin 在线编辑器