在文件中统计给定子字符串出现的次数,Kotlin。

3
我需要编写一个函数,用于计算文本中子字符串出现的次数并返回一个映射(字符串-计数)。
我尝试使用.contains方法制作它,但它无法计算单个单词中的多个出现次数(例如“lalala”中的“la”),现在我不知道该如何解决。请帮忙修改代码。
fun countSubstrings(inputName: String, substrings: List<String>): Map<String, Int> {

    val map = mutableMapOf<String, Int>()
    var tempCounter = 0
    for (i in 0 until substrings.size) {

        for (line in File(inputName).readLines()) {

            for (word in line.split(" ")) {
                if (word.contains(substrings[i], true)) tempCounter++ 
            }
        }
        map.put(substrings[i], tempCounter)
        tempCounter = 0
    }
    return map
}

因此,我希望这个函数可以计算单词、2-3个字符的子字符串甚至是1个字符的子字符串。"最初的回答"

不要使用contains,而是使用fun countSubstring(s: String, sub: String): Int = s.split(sub).size - 1 - DanielM
1
抱歉有些不准确,但是函数的输入和输出是任务的一部分。 - Corus Donnaka
@DanielM:如果匹配可以重叠,例如在“lalala”中有两个“lala”的出现,则您的解决方案返回1是不正确的。 - majk
2个回答

0
使用 indexOf 查找给定起始位置的第一个匹配项的位置,如果没有找到则返回 -1。然后您可以更改起始位置并再次重复此过程。这样就不会出现重叠问题了。
fun countMatches(text: String, template: String): Int {
    var cnt = 0
    var pos = 0
    while (true) {
        pos = text.indexOf(template, pos)
        if (pos != -1) {
            cnt++
            pos++
        } else {
            return cnt
        }
    }
}


fun countSubstrings(inputName: String, substrings: List<String>): Map<String, Int> {
    val mp = substrings.map { it to 0 }.toMap().toMutableMap()
    for (line in File(inputName).readLines()) {
        for (str in substrings) {
            if (str in mp) {
                mp[str] = (mp[str] ?: 0) + countMatches(line.toLowerCase(), str.toLowerCase())
            }
        }
    }
    return mp
}

但是你应该知道两件事:

  1. 时间复杂度为O(n * m),其中n和m是这些字符串的长度。
  2. 这不是非常优雅的解决方案,可能存在更好的解决方案。 但它有效 =)

-1

我的意思是,有StringUtils.html#countMatches,它是Apache Commons的一部分。

 StringUtils.countMatches(null, *)       = 0
 StringUtils.countMatches("", *)         = 0
 StringUtils.countMatches("abba", null)  = 0
 StringUtils.countMatches("abba", "")    = 0
 StringUtils.countMatches("abba", "a")   = 2
 StringUtils.countMatches("abba", "ab")  = 1
 StringUtils.countMatches("abba", "xxx") = 0

也许他们想要一个纯 Kotlin 的解决方案,或者可能有些偏见外部库。这是 Stack Overflow,谁知道呢。 - Andrew White

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接