From bc7c19857df8fd3dd775ecb24f8557c545085751 Mon Sep 17 00:00:00 2001 From: mban Date: Mon, 13 May 2024 18:54:44 +0900 Subject: [PATCH] =?UTF-8?q?ImmutableStringRollingHash=E5=AE=9F=E8=A3=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../string/ImmutableStringRollingHash.kt | 27 ++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/src/main/kotlin/string/ImmutableStringRollingHash.kt b/src/main/kotlin/string/ImmutableStringRollingHash.kt index 3af5323..09ab710 100644 --- a/src/main/kotlin/string/ImmutableStringRollingHash.kt +++ b/src/main/kotlin/string/ImmutableStringRollingHash.kt @@ -1,11 +1,16 @@ package string -class ImmutableStringRollingHash(private val radix: Long) { +import kotlin.random.Random + +class ImmutableStringRollingHash { companion object { private const val MOD = (1L shl 61) - 1 private const val MASK31 = (1L shl 31) - 1 private const val MASK30 = (1L shl 30) - 1 + // 文字列最大長、適宜変更すること + private const val MAX_LENGTH = 5000000 + private fun multiply(l: Long, r: Long): Long { val au = l shr 31 val ad = l and MASK31 @@ -24,4 +29,24 @@ class ImmutableStringRollingHash(private val radix: Long) { return ((num % MOD) + MOD) % MOD } } + + private val radix = Random.nextLong(MOD) + private val p = LongArray(MAX_LENGTH + 1) { 1 } + + init { + for (i in 0 until MAX_LENGTH) { + p[i + 1] = multiply(p[i], radix) + } + } + + fun createGetHash(s: String) = createGetHash(s.toCharArray()) + + fun createGetHash(array: CharArray): (Int, Int) -> Pair { + val len = array.size + val table = LongArray(len + 1) { 0 } + for (i in array.indices) { + table[i + 1] = safeMod(multiply(radix, table[i]) + array[i].code) + } + return { begin, end -> safeMod(table[end] - multiply(p[end - begin], table[begin])) to end - begin } + } } \ No newline at end of file