1. 程式人生 > >使用C++STL中的deque實現作業系統FIFO、LRU頁面置換演算法

使用C++STL中的deque實現作業系統FIFO、LRU頁面置換演算法

#include <iostream>
#include <deque>//雙端佇列所在的標頭檔案
#include <algorithm>//find()函式所在的標頭檔案
using namespace std;
const int LEN = 17;
deque<int> fifo;
deque<int> lru;
int main()
{
    int pages[] = {1,2,5,7,5,7,1,4,3,5,6,4,3,2,1,5,2};//頁面走向
    int success = 0;//命中的次數
    int fail = 0
;//缺頁次數 //FIFO演算法 for(int i = 0;i < LEN;i++){ //查詢物理塊中是否已經存在要訪問的頁面 auto pos=find(fifo.cbegin(),fifo.cend(),pages[i]); [//auto關鍵字詳解](http://blog.csdn.net/liuweiyuxiang/article/details/51534) if( pos != fifo.cend()){ //cout<<"找到了元素 "<<pages[i]<<endl;
success++; }else{ //cout<<"未找到元素 "<<pages[i]<<endl; fail++; if(fifo.size() < 4){//分配4個物理塊 fifo.push_back(pages[i]); }else{ fifo.pop_front(); fifo.push_back(pages[i]); } } } cout
<<"使用FIFO演算法,分配4個記憶體塊時:"<<endl; cout<<"\t缺頁率為:"<<(double)fail/(fail+success)<<endl; cout<<"\t命中率為:"<<(double)success/(fail+success)<<endl; /*使用LRU演算法(使用雙端佇列實現P165特殊的棧。該棧的棧頂元素始終為最近訪問的元素, 這樣棧底元素即為最久未使用的元素,當物理塊用盡時將棧底元素換出即可)*/ success = 0; fail = 0; for(int i = 0;i < LEN;i++){ auto pos = find(lru.cbegin(),lru.cend(),pages[i]); if( pos != lru.cend()){ //cout<<"找到了元素 "<<pages[i]<<endl; success++; lru.erase(pos);//刪除指定位置的元素 lru.push_back(pages[i]);//將該元素重新加入到佇列尾 }else{ //cout<<"未找到元素 "<<pages[i]<<endl; fail++; if(lru.size() < 4){//分配4個物理塊 lru.push_back(pages[i]);//物理塊未滿將該元素重新加入到佇列尾 }else{ lru.pop_front();//物理塊已滿將隊首部元素刪除 lru.push_back(pages[i]);//將新進的元素新增到佇列尾 } } } cout<<"使用LRU演算法,分配4個記憶體塊時:"<<endl; cout<<"\t缺頁率為:"<<(double)fail/(fail+success)<<endl; cout<<"\t命中率為:"<<(double)success/(fail+success)<<endl; return 0; }

小結:

1.雙端佇列常用函式
【標頭檔案】#include<deque>
【函式構造】
deque c 建立一個空的deque。
deque c1(c2) 複製一個deque。
deque c(n) 建立一個deque,含有n個數據,資料均已預設構造產生。
deque c(n, elem) 建立一個含有n個elem拷貝的deque
deque c(beg,end) 建立一個以[beg;end)區間的deque
c.~deque() 銷燬所有資料,釋放記憶體
【成員函式】:
c.assign(beg,end) 將[beg; end)區間中的資料賦值給c。
c.assign(n,elem) 將n個elem的拷貝賦值給c。
c. at(idx) 傳回索引idx所指的資料,如果idx越界,丟擲out_of_range。
c.back() 傳回最後一個數據,不檢查這個資料是否存在。
c.begin() 傳回迭代器中的第一個資料。
c.clear() 移除容器中所有資料。
c.empty() 判斷容器是否為空。
c.end() 指向迭代器中的最後一個數據地址。
c.erase(pos) 刪除pos位置的資料,傳回下一個資料的位置。
c.erase(beg,end) 刪除[beg,end)區間的資料,傳回下一個資料的位置。
c.front() 傳回第一個資料。
get_allocator 使用建構函式返回一個拷貝。
c.insert(pos,elem) 在pos位置插入一個elem拷貝,傳回新資料位置
c.insert(pos,n,elem) 在pos位置插入>n個elem資料。無返回值
c.insert(pos,beg,end) 在pos位置插入在[beg,end)區間的資料。無返回值
c.max_size() 返回容器中最大資料的數量。
c.pop_back() 刪除最後一個數據。
c.pop_front() 刪除頭部資料。
c.push_back(elem) 在尾部加入一個數據。
c.push_front(elem) 在頭部插入一個數據。
c.rbegin() 傳回一個逆向佇列的第一個資料。
c.rend() 傳回一個逆向佇列的最後一個數據的下一個位置。
c.resize(num) 重新指定佇列的長度。
c.size() 返回容器中實際資料的個數。
c.swap(c2) 將c1和c2元素互換。
swap(c1,c2) 將c1和c2元素互換。
【特點】
1、支援隨機訪問,即支援[]以及at(),但是效能沒有vector好。
2、支援兩端操作,push(pop)-back(front),但效能不及list。
【最佳使用情況】
1、需要在兩端插入和刪除元素。
2、無需引用容器內的元素。
3、要求容器釋放不再使用的元素。
2.查詢某個元素是否在雙端佇列中
【標頭檔案】

            include <algorithm>

【find()函式】

        deque<int> lru={1,2,3};
        auto pos = find(lru.cbegin(),lru.cend(),num);