程序员面试金典: 9.13 C和C++ 13.1 用C++方法,打印输入文件的最后K行。

#include <iostream>
#include <stdio.h>
#include <string>
#include <fstream>
#include <sstream>
#include <vector>
using namespace std;

/*
问题:用C++方法,打印输入文件的最后K行。
分析:假设文件一共N行,最后K行,那就是从N-k+1~N。之前打印链表倒数第k个结点可以用两个指针,这里不能用了。
      暴力破解:先读取整个文件确定N,下次每读一行就计数,从第N-k+1行开始存储结果直到第N行。
	  另外一种方法就是:采用回滚数组,节省空间,设一个字符串数组strings[k],长度为k,每次存储新读取的一行到该数组,
	  举例:设共有6行,读取最后4行,各行内容如下
	  1
	  2
	  3
	  4
	  5
	  6

	  那么读取第1行数组中为:[1, , ], 数组元素个数<K,直接存储
	            2           [1,2,],直接存储该行
				3           [1,2,3],直接存储
				4           [1,2,3,4],直接存储
				5           [5,2,3,4],元素个数=K,必须替换掉最先进来的1
				6           [5,6,3,4],替换次最先进来的2
				记录最后一行在数组下标index,则index+1~k-1下标对应的数组元素是前面部分(如上述3,4),再加上0~index下标对应元素是后面部分(如上述的5,6)

输入:
4(倒数第K行)
输出:(这个是在我输入文件共有6行,各行分别为:1,2,3,4,5,6的情况下)
3
4
5
6

关键:
1 采用回滚数组,节省空间,设一个字符串数组strings[k],长度为k,每次存储新读取的一行到该数组,当长度>=k时,采用替换最先进入的行
记录最后一行在数组下标index,则index+1~k-1下标对应的数组元素是前面部分,再加上0~index下标对应元素是后面部分

2 文件操作:读取一行用字符数组infile.getline(line , 1024);,判断是否结束用while(!infile.eof()),判断文件是否打开成功用if(!infile)
*/

void printResult(vector<string>& lines, int endIndex)
{
	if(lines.empty())
	{
		cout << "no result" << endl;
		return;
	}
	int size = lines.size();
	int i;
	for(i = endIndex + 1 ; i < size; i++)
	{
		cout << lines.at(i) << endl;
	}
	for(i = 0 ; i <= endIndex ; i++)
	{
		cout << lines.at(i) << endl;
	}
}

void process()
{
	int k;
	while(cin >> k)
	{
		string fileName("test.txt");
		ifstream infile(fileName);
		if(!infile)
		{
			cout << "file open error" << endl;
			return;
		}
		char line[1024];//读取一行,不能用字符串
		vector<string> lines;
		int replaceIndex = 0;
		while(!infile.eof())
		{
			infile.getline(line , 1024);
			string content(line);
			if(lines.size() < k)
			{
				lines.push_back(content);
			}
			//此时需要将最先进入的那一行替换掉
			else
			{
				if(replaceIndex >= k)
				{
					replaceIndex = 0;
				}
				lines.at(replaceIndex) = content;
				replaceIndex++;
			}
		}
		//关闭文件
		infile.close();
		printResult(lines , replaceIndex - 1);
	}
}

int main(int argc, char* argv[])
{
	process();
	getchar();
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值