首页 > 解决方案 > 在 Kotlin 中计算 MutableMap 中的字符串出现次数

问题描述

我有一个可变映射,包含在 while 循环中添加的元素。x当从输入中给出时结束。我的 hyperskill 任务是打印出现次数最多的元素,但是如果出现次数相同,它会给我出现更快的元素。所以给出:

a,a,a,b,b -> a
c,a,c,a -> c
a,b,c,a -> a

val words = mutableMapOf<Int, String>()
    var x_is_used = false
    var index = 0
    val scan = Scanner(System.`in`)
    while (!x_is_used) {
        var input = scan.next()
        if (input== "x") {
            x_is_used = true
        } else {

            words[index] = input
            index++

        }}

我怎样才能实现它?我尽量不让这篇文章重复。这是从介绍部分到地图、列表和集合的任务。虽然我不是 Kotlin 的新手,但它的文档让我感到困惑。

查看地图文档: https ://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/-map/

引起我注意的是功能.count.filter 但我不知道如何使用它们。

任务图:

在此处输入图像描述

标签: kotlin

解决方案


我认为你存储了太多信息。考虑输入(比如说)a、b、c、a 后您的地图会是什么样子:

3 -> c
1 -> a
4 -> a
2 -> b

(地图通常没有顺序,所以这些对可以是任何顺序。)

如果您想按顺序存储每个输入,那么 List 会更合适。

然而,这个问题并不关心输入值的顺序——它只关心每个值有多少。为了存储它,您可以使用从输入值到出现次数的映射。一旦你有了这个结构,剩下的就应该很简单了。

(如果您正在学习该语言,那么您将通过尝试自己实现它来学习最多,所以我强烈建议您在自己完成某些工作之前不要阅读此答案的其余部分!不幸的是,它似乎没有可以在不丢失所有格式的情况下将代码标记为破坏者,也可以标记多个段落。因此,我将采用老式的方式并留出空隙……)

⠀ ⠀

↓</p>

↓</p>

↓</p>

↓ ⠀

这是一种可能的解决方案:

val wordCounts = mutableMapOf<String, Int>()
val scan = Scanner(System.`in`)
while (true) {
    val input = scan.next()
    if (input == "x")
        break
    wordCounts.merge(input, 1, Int::plus)
}

println(wordCounts.maxByOrNull{ it.value }?.key)

如您所见,这相当简单!

与其维护一个标志变量,不如break在到达终点时退出循环更简单。(在现实世界中,不是使用像“x”这样的特殊值来标记结束,而是在输入结束之前读取可能会更整洁:如果读取文件,那将是文件的结尾;如果直接用户输入,用户将按下文件结尾组合(例如 macOS/Unix 上的 Ctrl+D)来结束。代码将简单地检查null.)

更新地图很简单:

wordCounts[input] = wordCounts[input] + 1

…<em>如果我们知道输入已经存在。为了处理这个问题,你可以这样做:

wordCounts[input] = (wordCounts[input] ?: 0) + 1

…但是merge()一旦你知道它在做什么,这个调用就会稍微简单一些。

要获得最常用的词,您只需在地图中搜索具有最高值(即最大计数)的条目。您可以手动执行此操作,但有一个很好的maxByOrNull()功能可以做到这一点。(请注意,如果输入为空,它可以返回 null,所以我们必须处理它。)

一旦你有了那个条目,你就可以打印它的键,这是最常见的词!


推荐阅读