Kotlin:统计在字符串中出现的`charArray`次数

22

我有两个字符串

val string1 = "Hello"
val string2 = "Hello world"

我需要在 Kotlin 中统计 string1 中每个字母在 string2 中的出现次数。

目前为止,我已经写了这么多代码,但是还卡在正则表达式上了。

val string1_array = string1.toCharArray()
val pattern = Regex("") // Regex pattern here
val matcher = string2

val count = pattern.findAll(matcher).count()

在Kotlin中搜索charArray的适当Regex模式是什么?是否有更好的方法?


1
你不需要使用正则表达式来计算字符串中的字符数。只需使用循环(或任何其他类型的迭代)即可。 - JB Nizet
请问您能否添加您期望的逻辑呢? - jrtapsell
你需要单独计算每个字符吗?例如,有多少个'H',有多少个'e'等等? - stan0
2
以下是使用 Kotlin 集合函数的一行解决方案: val occurrences = string2.filter{ it in string1} .groupingBy { it } .eachCount() - hexkid
7个回答

21

以下是一些可以使用的 String 扩展函数

任何字符的出现次数

使用fold扩展函数:

val string1 = "Hello"
val string2 = "Hello world Hello"

print(
     string2.fold(0) {
         sum: Int, c: Char ->
         if (string1.contains(c))
             sum + 1
         else
             sum
     }   
) 

使用sumBy可以更加简洁:

string2.sumBy { 
    if (string1.contains(it))
        1
    else
        0
}

甚至更短:

string2.count { string1.contains(it) }

或者最短:

string2.count { it in string1 }

每个字符的出现次数

使用forEachMutableMap

val charsMap = mutableMapOf<Char, Int>()

string2.forEach{
    charsMap[it] = charsMap.getOrDefault(it, 0) + 1
}

print(charsMap)

字符串1的所有出现次数

使用windowed扩展函数:

string2.windowed(string1.length){
    if (it.equals(string1))
        1
    else
        0
}.sum()
您可以在String标准库页面浏览更多的String扩展函数。

1
应该返回 sum + 1sum,对吗? - leonardkraemer
@leoderprofi 当然!我忘记它们了。我很快就会为每个字符添加一个映射变量。 - stan0
3
使用窗口搜索整个字符串的方式很好!我稍微更喜欢这样写:string2.windowed(string1.length).filter { it == string1 }.count() - Matt
3
在我看来,这应该是被接受的答案,谢谢你向我介绍窗口函数,我是 Kotlin/FP 的新手。 - Marco

18

您可以使用下面的高阶方法:

val count = string2.count{ string1.contains(it) }
print(count)

13

只需使用Kotlin的集合函数

val occurrences = string2.filter{ it in string1}
                        .groupingBy { it }
                        .eachCount()

8

2

回答实际问题:最简单的正则表达式模式是使用字符类语法"[" + string1 + "]"。请注意,这并不总是表现良好。它适用于所有ASCii字母和数字。特殊字符如\^-?!必须正确转义。有关规则,请参见https://www.regular-expressions.info/charclass.html

fun main(args: Array<String>): Unit {
    val string1 = "Hello"
    val string2 = "Hello world Hello"

    val string1_array = string1.toCharArray()
    val pattern = Regex("[" + string1 + "]") // Regex pattern here
    val matcher = string2

    val count = pattern.findAll(matcher).count()
    print(count)
}

如何解决这个任务:在我看来,完成这个任务的最佳方法是使用filtercount而不是正则表达式,因为你不需要使用任何特殊的语法。

fun main(args: Array<String>): Unit {
        val string1 = "Hello"
        val string2 = "Hello world Hello"
        //returns all chars of string2 contained in string1 as list
        val count = string2.filter { string1.contains(it) }.length
        //an other a bit shorter solution with count
        count = string2.count{ string1.contains(it) }
        print(count)
}

0
val x = name.count({ch->ch=='z'}) //if you want to count 'z'

0

你可以使用第一个字符串中的字符作为映射键,例如:

val string1 = "Hello"
val string2 = "Hello world"

val chars = HashMap<Character, Int>()

for (char in string1) // fill keys
    chars[char] = 0

for (char in string2) // count occurrences
    chars[char]?.let {
        chars[char] = it + 1
    }

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