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

来源:互联网 发布:复杂sql 语句编写经验 编辑:程序博客网 时间:2024/06/05 15:35
#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,必须替换掉最先进来的16           [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的情况下)3456关键: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;}

0 0