请打印给定文件的最后n行

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/zzran/article/details/8920685

首先想到的最笨的办法就是打开文件,然后遍历一遍,计算出文件中的行数,然后在从头开始遍历文件,在某个位置开始打印从文件中读出的行。这是一个比较笨的方法,还有一种很巧妙的方法就是应用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;
}


展开阅读全文

没有更多推荐了,返回首页