Kotlin - 字符串中的唯一字符

Kotlin - Unique Characters in String

我的函数应该return一个布尔值,指示输入字符串是否包含所有唯一字符。

例如 "abc" return 为真,"abca" return 为假

fun uniqueCharacters(s: String): Boolean = s.groupBy { it }
    .values
    .stream()
    .allMatch { it.size == 1 }

有没有更有效的方法来解决这个问题?如果我以非功能性方式解决这个问题,我会将所有字符存储在一个 Map 中,其值为该字符到目前为止的计数,如果它大于 1,则 break 和 return false.

不确定如何最好地将其转换为功能性 Kotlin 代码。

您可以使用 all 函数和 Set::add 作为它的谓词

fun main() {
    println("abc".allUnique()) // true
    println("abca".allUnique()) // false
}

fun String.allUnique(): Boolean = all(hashSetOf<Char>()::add)

偷懒了,函数returns找到第一个重复的结果

也许最简单的方法是创建一个 Set 个字符,并检查其大小:

fun String.isUniqueCharacters() = toSet().size == length

(因为这个函数只依赖于字符串的内容,所以把它作为一个扩展函数似乎是合乎逻辑的;这样也更容易调用。)

至于性能,它有效地创建了字符的散列 table,然后检查条目数,即唯一字符数。所以这不是微不足道的。但我想不出更好的方法。

其他方法可能包括:

  • 将字符复制到一个数组,就地排序,然后扫描它比较相邻元素。这将节省一些内存分配,但需要更多处理。

  • 同上,但使用手动编码的排序算法,可以尽早发现重复项和 returns。这将减少 重复的情况下的处理,但代价是更多的编码。 (当 没有 重复项时,手工编码排序可能比库排序慢。)

  • 创建一个包含 65536 个布尔值的数组(每个可能的 Char*),全部初始化为 false,然后扫描每个字符串中的字符检查相应的数组值(如果已经设置则返回 false,否则设置它)。这可能是最快的方法,但需要大量内存。 (初始化数组的成本可能很高。)

一如既往,它归结为权衡内存、处理和编码工作。

(* Unicode 中当然有比这更多的字符,但 Kotlin 内部使用 UTF-16,所以我们只需要 65536。)

另一种方法

fun String.uniqueCharacters(): Boolean = this.toCharArray().distinct().isNotEmpty()