nachtvaohal

effective quick sort

Jan 15th, 2024 (edited)
59
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Kotlin 4.64 KB | None | 0 0
  1. package sprint3.xb
  2.  
  3. import java.io.BufferedWriter
  4.  
  5. /**
  6.  * ПРИНЦИП РАБОТЫ
  7.  * Алгоритм осуществляет быструю сортировку в соответствии с компаратором, переданным в [less]. Для того чтобы избежать
  8.  * использования дополнительной памяти, используется подход in-place sort. На каждом этапе случайным образом выбирается
  9.  * опорный элемент, и, после перестановок, слева от опорного элемента оказываются значения меньшие его, а справа -
  10.  * значения большие. Далее сортировка осуществляется рекурсивно для обеих частей до тех пор, пока не будет достигнут
  11.  * базовый случай.
  12.  *
  13.  * ДОКАЗАТЕЛЬСТВО КОРРЕКТНОСТИ
  14.  *
  15.  *
  16.  * ВРЕМЕННАЯ СЛОЖНОСТЬ
  17.  * В среднем поиск выполняется со сложностью быстрой сортировки - O(n log n)
  18.  *
  19.  * ПРОСТРАНСТВЕННАЯ СЛОЖНОСТЬ
  20.  * Пространственная сложность O(n), т.к. для поиска используется исходный массив, дополнительная память не требуется.
  21.  *
  22.  * @param subArrayStart индекс начала сортируемой части массива (включительно)
  23.  * @param subArrayEnd индекс конца сортируемой части массива (включительно)
  24.  * @param less компаратор, возвращающий true, если первый аргумент меньше второго аргумента
  25.  */
  26. fun <T : Any> inPlaceQuickSort(array: Array<T>, subArrayStart: Int, subArrayEnd: Int, less: (T, T) -> Boolean) {
  27.     // в ином случае размер сортируемой части подмассива меньше 1, а значит сортировать нечего (базовый случай)
  28.     if (subArrayStart < subArrayEnd) {
  29.         val pivot = array[(subArrayStart..subArrayEnd).random()] // значение опорного элемента
  30.         var left = subArrayStart
  31.         var right = subArrayEnd
  32.         while (left <= right) {
  33.             while (less(array[left], pivot)) {
  34.                 left++
  35.             }
  36.             // в этом месте все элементы list от 0 до left (не включительно) меньше опорного элемента
  37.             while (less(pivot, array[right])) {
  38.                 right--
  39.             }
  40.             // в этом месте все элементы list от right (не включительно) до sublistEnd больше опорного элемента
  41.             if (left <= right) {
  42.                 array[left] = array[right].also { array[right] = array[left] }
  43.                 left++
  44.                 right--
  45.             }
  46.         }
  47.         inPlaceQuickSort(array, subArrayStart, right, less)
  48.         inPlaceQuickSort(array, left, subArrayEnd, less)
  49.     }
  50. }
  51.  
  52. /**
  53.  * Сравнение представлений стажёров.
  54.  *
  55.  * @return true, если [intern1] выше по рейтингу (имеет меньшее - less - значение рейтинга), чем [intern2]
  56.  */
  57. fun less(intern1: Intern, intern2: Intern): Boolean {
  58.     return if (intern1.taskCount != intern2.taskCount) {
  59.         intern1.taskCount > intern2.taskCount
  60.     } else if (intern1.penalty != intern2.penalty) {
  61.         intern1.penalty < intern2.penalty
  62.     } else {
  63.         intern1.name < intern2.name
  64.     }
  65. }
  66.  
  67. /**
  68.  * Представление стажёра.
  69.  */
  70. data class Intern (
  71.     val name: String,
  72.     val taskCount: Int,
  73.     val penalty: Int
  74. )
  75.  
  76. fun main() {
  77.     val reader = System.`in`.bufferedReader()
  78.     val writer = System.out.bufferedWriter()
  79.     val count = reader.readLine().toInt()
  80.     val inputStrings = Array<String>(count) {
  81.         reader.readLine()
  82.     }
  83.     val interns = inputStrings.map { it.split(" ") }
  84.         .map { Intern(name = it[0], taskCount = it[1].toInt(), penalty = it[2].toInt()) }
  85.         .toTypedArray()
  86.     inPlaceQuickSort(interns, 0, interns.lastIndex) {
  87.         intern1, intern2 -> less(intern1, intern2)
  88.     }
  89.     with(writer) {
  90.         interns.forEach {
  91.             handleResult(it.name)
  92.         }
  93.         flush()
  94.     }
  95. }
  96.  
  97. private fun BufferedWriter.handleResult(result: String) {
  98.     write(result)
  99.     newLine()
  100. }
Add Comment
Please, Sign In to add comment