請打印給定文件的最後n行

首先想到的最笨的辦法就是打開文件,然後遍歷一遍,計算出文件中的行數,然後在從頭開始遍歷文件,在某個位置開始打印從文件中讀出的行。這是一個比較笨的方法,還有一種很巧妙的方法就是應用circular buffer,初次見到這個名稱的人可能感覺很神奇,但是如果知道循環隊列這個概念的話,那麼就不難理解了。如果我們準備打印一個文件的最後n行,我們可以建立一個n+1空間的循環隊列,至於爲什麼是n+1的循環隊列,是爲了表示隊列什麼時候滿,什麼時候是空的。接下來就解決怎麼打印最後n行吧:首先我們把讀出的每行的字符串的首地址放在隊列中,如果隊列已經被填滿了,那麼我們開始進行覆蓋,也就是說第如果隊列用n個空間,那麼當第n+1行到來的時候,我們就把原來存放第一行字符串首地址的隊列某空間用第n+1行的首地址覆蓋掉,依次對之後的行來進行如此的操作,大家很容易發現,到最後隊列中存留下來的就是最後n行的字符串的首地址。

下面給出wikipedia中,講述circular buffer的連接:http://en.wikipedia.org/wiki/Circular_buffer 然後給出我自己寫的代碼:

#include<iostream>
#include<string>
#include<fstream>
using namespace std;

class Queue {
private:
	void **elem;
	int front, rear;
	int size;
public:
	Queue(int _size) {
		size = _size + 1;
		elem = (void**)malloc(size * sizeof(void*));
		memset(elem, 0, size * sizeof(void*));
		front = rear = 0;
	}
	Queue() {
		free(elem);
	}
	void enQueue(void *addr);
	void deQueue(void **addr);
	bool isQueueEmpty();
};

void Queue::enQueue(void *addr) {
	if ((rear + 1) % size == front) {
		free(elem[front]);
		elem[front] = NULL;
		front = (front + 1) % size;
	}
	elem[rear] = addr;
	rear = (rear + 1) % size;
}

void Queue::deQueue(void **addr) {
	if (rear == front)
		return;
	*addr = elem[front];
	elem[front] = NULL;
	front = (front + 1) % size;
}

bool Queue::isQueueEmpty() {
	return rear == front;
}

int main(int argc, char *argv[]) {
	char temp[100];
	Queue q(10);
	ifstream fin;
	fin.open("test.txt", ifstream::in);
	while (fin >> temp) {
		int n = strlen(temp);
		char *s = (char*)malloc(n + 1);
		strcpy(s, temp);
		s[n] = '\0';
		q.enQueue(s);
	}
	while (!q.isQueueEmpty()) {
		char *s = NULL;
		q.deQueue((void**)&s);
		cout << s << endl;
		free(s);
	}
	cin.get();
	return 0;
}


發佈了125 篇原創文章 · 獲贊 115 · 訪問量 56萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章