LRU置換演算法(Java)
題目:
2 表示頁面的容量
1 1 表示第一個位置處的key=1 value=1
2 2 表示第二個位置處的key=2 value=3
3 3 通過LRU演算法置換策略 最近最少使用 那麼就將key=1 value=1 置換為 key=3 value=3
1 查詢key等於1的value
-1 -1表示不能存在
使用集合表示頁,使用類物件來表示頁面。
時間戳 | t1 |
t2 |
t3 | t4 | t5 | t6 | t7 | t8 | t9 |
頁面序列 | (1,1) | (2,2) | (3,3) | (4,4) | (5,5) | (2,6) | (7,7) | (3,8) | (9,9) |
(1,1)(t1) | (1,1)(t1) | (3,3)(t3) | (3,3)(t3) | (5,5)(t5) | (5,5)(t5) | (7,7)(t7) | (7,7)(t7) | (9,9)(t9) | |
(2,2)(t2) | (2,2)(t2) | (4,4)(t4) | (4,4)(t4) | (2,6)(t6) | (2,6)(t6) | (3,8)(t8) | (3,8)(t8) |
站在Java的角度簡單的分析一下:
我們可以採用集合來表示頁,集合中的類物件表示頁面,集合的容量(實際控制的長度)為頁的容量。此時我們設計的類需要以下幾個屬性:時間戳,鍵,值。
在這裡我們把時間戳設定成整數自增 表示時間自增。
大體思路就是:
{
首先我們設計的是無限迴圈,而且題目要求的使單行輸入一個數字時結束輸入,此時在頁中查詢時候存在key等於最後一個數字 的值 如果存在那麼 就輸出這個值。
就是這個終止條件我也思考了半天, 首先輸入一行 用空格拆分成字串陣列,如陣列的長度不等於2 那就迴圈結束,並且記錄最後一個key值。
}
1.首先有一個頁面需要快取。
這個頁面在頁中存在,如果存在那麼就更改時間戳為當前時間戳
這個頁面在頁中不存在,結果就是置換或者新增到頁中。
如果這個頁此時已經飽和了,那麼就需要置換出最近最少使用的頁,根據時間戳排序,將標號最小的時間戳與當前資訊置換
否則,向頁中繼續新增就可以了。
2. 將之前記錄的key值 與頁中的key值比較存在返回value 否則返回-1;
package 演算法;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Scanner;
/**
* 時間戳作為key值 頁面,頁面序列作為value值
* @author NullChen
*/
public class LRU置換演算法的設計 {
class Record implements Comparable<Record>{
private int tmp;
private int key;
private int value;
public Record(int tmp, int key, int value) {
super();
this.tmp = tmp;
this.key = key;
this.value = value;
}
public int getTmp() {
return tmp;
}
public void setTmp(int tmp) {
this.tmp = tmp;
}
public int getKey() {
return key;
}
public void setKey(int key) {
this.key = key;
}
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
}
//比較鍵值 來比較時候包含
@Override
public boolean equals(Object obj) {
return this.getKey()==((Record)obj).getKey();
}
@Override
public int compareTo(Record o) {
return this.tmp-o.tmp;
}
@Override
public String toString() {
return "Record [tmp=" + tmp + ", key=" + key + ", value=" + value + "]";
}
}
public static void main(String[] args) {
LRU置換演算法的設計 lru = new LRU置換演算法的設計();
//使用list集合來模仿頁面 list集合的大小來表示快取的容量
//LRU 就是最近最少使用策略 如果這個key不存在 那麼就新增到集合中或者替換最近最遠使的 否在就替換已經存在的key
Scanner scnner =new Scanner(System.in);
//輸入快取的容量
int capy = scnner.nextInt();
//時間錘
int tmp = 0;
//頁面
List<Record> page = new ArrayList<Record>();
//要查詢的key
int checkKey = 0;
while(true) {
tmp++;
//如果要滿足終止條件 那麼就應該 輸入一行
Scanner scanner =new Scanner(System.in);
String data = scanner.nextLine();
//拆分
String[] keyValue = data.split(" ");
int key = 0,value=0;
if(keyValue.length == 2) {
key = Integer.parseInt(keyValue[0]);
value = Integer.parseInt(keyValue[1]);
}else {
checkKey = Integer.parseInt(keyValue[0]);
break;
}
//判斷在頁面中是否存在
Record record = lru.new Record(tmp, key, value);
boolean isContain = page.contains(record);
//在集合中存在 那麼就需要替換時間戳
if(isContain) {
Record isEx = page.get(page.indexOf(record));
isEx.setTmp(tmp);
}else {
//在集合中不存在
if(tmp<=capy) {
//頁面沒有被填充滿
page.add(record);
}else {
//根據時間戳給list集合排序 將最小的調製第1個 每次替換第一個就行了
Collections.sort(page);
//替換時間戳最小的
Record re = page.get(0);
re.setKey(key);
re.setValue(value);
re.setTmp(tmp);
}
}
}
//檢視一下 page 中此時的集合
for (Record record : page) {
System.out.println(record);
}
boolean isHaving = false ;
String msg ="";
//在 集合中 查詢鍵為checkKey的值 沒有返回-1 存在 返回值
for (Record record : page) {
if(record.getKey() == checkKey) {
isHaving = true;
msg=""+record.getValue();
break;
}
}
if(isHaving) {
System.out.println(msg);
}else {
System.out.println(""+(-1));
}
}
}