Advertisement
nachtvaohal

search system

Jan 28th, 2024 (edited)
106
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Kotlin 3.79 KB | None | 0 0
  1. import java.lang.Integer.min
  2. import java.util.*
  3. import kotlin.collections.HashMap
  4.  
  5. class SearchSystem(
  6.     documents: Array<String>
  7. ) {
  8.     // в value хранится номер документа и количество вхождений слова в этом документе
  9.     // word to { docNumber to wordCountInDocument }
  10.     private val wordStats: MutableMap<String, MutableMap<Int, Int>> = HashMap(documents.size)
  11.  
  12.     init {
  13.         for (docNumber in 1..documents.size) {
  14.             documents[docNumber - 1].asTokenSequence().forEach {
  15.                     if (wordStats[it] == null) {
  16.                         wordStats[it] = mutableMapOf(docNumber to 1)
  17.                     } else {
  18.                         wordStats[it]!!.merge(docNumber, 1) { wordCount, _ -> wordCount + 1 }
  19.                     }
  20.                 }
  21.         }
  22.     }
  23.  
  24.     fun findDocumentNumbers(requests: Array<String>, maxCount: Int): List<List<Int>> {
  25.         return requests.asSequence()
  26.             .map { request -> searchByUniqueWords(request.asTokenSequence().toSet()).entries.toMutableList()
  27.                 .takeTop(maxCount)
  28.                 .map { it.key }
  29.             }
  30.             .filter { it.isNotEmpty() }
  31.             .toList()
  32.     }
  33.  
  34.     private fun searchByUniqueWords(uniqueWords: Set<String>): Map<Int, Int> {
  35.         return wordStats.asSequence()
  36.             .filter { uniqueWords.contains(it.key) }                    // данные только по словам из запроса
  37.             .flatMap { it.value.entries }                               // статистика только по словам из запроса
  38.             .groupBy { it.key }                                         // группировка по номеру документа
  39.             .mapValues { entry -> entry.value.sumOf { it.value } }      // подсчёт суммы вхождений в документе
  40.     }
  41.  
  42.     private operator fun Map.Entry<Int,Int>.compareTo(other: Map.Entry<Int,Int>): Int {
  43.         val countDifference = other.value - this.value
  44.         return if (countDifference == 0) {
  45.             this.key - other.key
  46.         } else {
  47.             countDifference
  48.         }
  49.     }
  50.  
  51.     private fun MutableList<Map.Entry<Int,Int>>.takeTop(maxCount: Int): List<Map.Entry<Int,Int>>{
  52.         if (this.size < 2) {
  53.             return this
  54.         }
  55.         val maxSize = min(this.size, maxCount)
  56.         for (i in 0 until maxSize) {
  57.             var maxItem = this[i]
  58.             var j = i
  59.             while (j < this.size) {
  60.                 if (this[j] < maxItem) {
  61.                     val temp = this[j]
  62.                     this[j] = maxItem
  63.                     maxItem = temp
  64.                 }
  65.                 j++
  66.             }
  67.             this[i] = maxItem
  68.         }
  69.  
  70.         return this.subList(0, maxSize)
  71.     }
  72.  
  73.     private fun String.asTokenSequence(): Sequence<String> {
  74.         val stringTokenizer = StringTokenizer(this)
  75.         return generateSequence {
  76.             if (stringTokenizer.hasMoreTokens()) {
  77.                 stringTokenizer.nextToken()
  78.             } else {
  79.                 null
  80.             }
  81.         }
  82.     }
  83. }
  84.  
  85. fun main() {
  86.     val reader = System.`in`.bufferedReader()
  87.     val writer = System.out.bufferedWriter()
  88.     val documentsCount = reader.readLine().toInt()
  89.     val documents = Array(documentsCount) {
  90.         reader.readLine()
  91.     }
  92.     val requestsCount = reader.readLine().toInt()
  93.     val requests = Array(requestsCount) {
  94.         reader.readLine()
  95.     }
  96.  
  97.     val searchSystem = SearchSystem(documents)
  98.     val results = searchSystem.findDocumentNumbers(requests, 5)
  99.     with(writer) {
  100.         results.forEach {
  101.                 write(it.joinToString(" "))
  102.                 newLine()
  103.                 flush()
  104.             }
  105.     }
  106. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement