作業系統課程設計 —— 磁碟排程演算法
阿新 • • 發佈:2021-08-30
talk is easy, show the code
import java.util.* import kotlin.math.abs /** * 磁碟排程演算法工廠類, 構造器私有化, 防止外部類例項化 */ class DiskScheduleFactory private constructor() { /** * 磁碟排程演算法介面, 不對外開放 */ private interface DiskScheduling { /** * 磁頭移動路徑資料 * @property moveCount Int * @property allDistance Int * @property lastPosition Int * @constructor */ data class Data(val moveCount: Int, val allDistance: Int, val lastPosition: Int) { /** * 過載 + 號, 方便合併兩部分資料 * @param other Data * @return Data */ operator fun plus(other: Data) = Data( other.moveCount + moveCount, other.allDistance + allDistance, lastPosition ) /** * 將資料以人類能看的方式顯示出來 * @return String */ override fun toString(): String { return "moveCount -> $moveCount allDistance = $allDistance" } } /** * 具體演算法實現方法 * @param visitList IntArray * @param currentPosition Int * @param upList LinkedList<Int> * @param downList LinkedList<Int> */ fun doStuff(visitList: IntArray, currentPosition: Int, upList: LinkedList<Int>, downList: LinkedList<Int>) /** * 遍歷列表輔助方法 * @param visitList IntArray * @param currentPosition Int * @return Data */ fun forEach(visitList: IntArray, currentPosition: Int): Data { var head = currentPosition var currentDistance: Int var allDistance = 0 var moveCount = 0 visitList.forEach { currentDistance = abs(head - it) println("磁頭移動 $head -> $it, 移動距離為 $currentDistance") head = it allDistance += currentDistance moveCount += 1 } return Data(moveCount, allDistance, visitList.last()) } /** * 輸出資料 * @param data Data */ fun outData(data: Data) { println("總共移動了 ${data.moveCount} 下, 移動距離為 ${data.allDistance} 平均移動距離為 ${data.allDistance / data.moveCount}") } } /** * 演算法實現列舉類, 不對外開放 */ private enum class DiskScheduleImpl : DiskScheduling { /** * 先來先服務演算法 */ FirstComeFirstServer { override fun doStuff( visitList: IntArray, currentPosition: Int, upList: LinkedList<Int>, downList: LinkedList<Int> ) { outData(forEach(visitList, currentPosition)) } }, /** * 最短尋道時間演算法 */ ShortestSeekTimeFirst { override fun doStuff( visitList: IntArray, currentPosition: Int, upList: LinkedList<Int>, downList: LinkedList<Int> ) { val allData = forEach(visitList.sortedWith(compareBy { abs(it - currentPosition) }).toIntArray(), currentPosition) outData(allData) } }, /** * 電梯演算法 自下往上 */ SCAN_UP { override fun doStuff( visitList: IntArray, currentPosition: Int, upList: LinkedList<Int>, downList: LinkedList<Int> ) { // 從大到小排序 downList.reverse() // 先往上走 val upData = forEach(upList.toIntArray(), currentPosition) // 再往上走 val downData = forEach(downList.toIntArray(), upData.lastPosition) // 算出總共的 val allData = downData + upData outData(allData) } }, /** * 電梯演算法 自上往下 */ SCAN_DOWN { override fun doStuff( visitList: IntArray, currentPosition: Int, upList: LinkedList<Int>, downList: LinkedList<Int> ) { // 從大到小排序 downList.reverse() // 先往下走 val downData = forEach(downList.toIntArray(), currentPosition) // 再往上走 val upData = forEach(upList.toIntArray(), downData.lastPosition) // 算出總共的 val allData = downData + upData outData(allData) } }, /** * 單項掃描演算法 */ C_SCAN { override fun doStuff( visitList: IntArray, currentPosition: Int, upList: LinkedList<Int>, downList: LinkedList<Int> ) { // 走到頭後歸零 downList.push(0) // 先往上走 val upData = forEach(upList.toIntArray(), currentPosition) // 再往上走 val downData = forEach(downList.toIntArray(), upData.lastPosition) // 算出總共的 val allData = downData + upData outData(allData) } } } /** * 伴生物件, 建立例項的方法 */ companion object { private lateinit var instance: DiskScheduleImpl /** * 根據演算法名獲取相應的演算法物件 * @param algorithm String * @return DiskScheduleFactory */ fun getInstance(algorithm: String): DiskScheduleFactory { runCatching { instance = DiskScheduleImpl.valueOf(algorithm) }.onFailure { throw IllegalArgumentException("演算法不支援!") } return DiskScheduleFactory() } } /** * 代理呼叫演算法 * @param visitList IntArray * @param currentPosition Int */ fun doStuff(visitList: IntArray, currentPosition: Int) { // 升序排序 visitList.sort() val downList = LinkedList<Int>() val upList = LinkedList<Int>() // 分離 上層 與 下層 visitList.forEach { if (it <= currentPosition) downList.add(it) else upList.add(it) } instance.doStuff(visitList, currentPosition, upList, downList) } } object Main { @JvmStatic fun main(args: Array<String>) { // 一共 8 條記錄 val visitDisk = intArrayOf(98, 183, 37, 122, 14, 124, 65, 67) DiskScheduleFactory.getInstance("SCAN_DOWN") .doStuff(visitDisk, 53) } }