计算文件Kotlin中给定子字符串的出现次数

时间:2019-05-26 16:08:19

标签: dictionary kotlin substring

我必须编写一个函数,该函数计算子字符串在文本中出现多少次并返回映射(字符串-计数)

我尝试使用.contains做到这一点,但是它不能将一个单词(“ laalala”中的“ 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个字符的子字符串。

2 个答案:

答案 0 :(得分:0)

我的意思是,有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

答案 1 :(得分: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. 这不是很好的解决方案,可能存在更好的解决方案。但这有效=)