需求:
1. 打开需要查询的文本文件,将文件的内容以行的方式读出并保存起来,需要记录行号和对应的文本。
2. 把每一行以单词进行拆分,把每个单词及该单词出现的行号记录起来,一个单词可能出现在多行。
3. 处理单词查询功能,返回指定单词出现在文本中的所有行号集合。
4. 遍历得出的行号集合,根据行号从1中返回对应下标的文本。
数据结构
1. 把文本内容保存到一个vector容器对象中,每一行就是vector的一个元素,行号对应于元素的下标。
2. 每个单词所在的行号保存到一个set容器对象中。
3. 把每个单词和其所在的行号关联起来,保存到map容器对象中。
下面是源码实现,包含三个文件,TextQuery.h,TextQuery.cpp,Client.cpp。
TextQuery.h
#ifndef TEXT_QUERY_H
#define TEXT_QUERY_H
#include <vector>
#include <map>
#include <string>
#include <set>
#include <fstream>
using namespace std;
class TextQuery {
public:
typedef vector<string>::size_type lineNo;
void readFile(ifstream &is);
set<lineNo> queryWordLineNos(const string &word) const;
string getText(lineNo num) const;
private:
void storeFile(ifstream &is);
void buildMap();
vector<string> linesText;
map< string,set<lineNo> > wordMap;
};
#endif
TextQuery.cpp
#include <sstream>
#include "TextQuery.h"
void TextQuery::storeFile(ifstream &is) {
string textLine;
while(getline(is,textLine))
linesText.push_back(textLine);
}
void TextQuery::buildMap() {
for(lineNo num = 0; num < linesText.size(); ++num) {
istringstream lineStream(linesText[num]);
string word;
while(lineStream >> word)
wordMap[word].insert(num);
}
}
void TextQuery::readFile(ifstream &is) {
storeFile(is);
buildMap();
}
set<TextQuery::lineNo> TextQuery::queryWordLineNos(const string &word) const {
map< string,set<lineNo> >::const_iterator cit = wordMap.find(word);
if(cit == wordMap.end())
return set<lineNo>();
else
return cit->second;
}
string TextQuery::getText(lineNo num) const {
if(num < linesText.size())
return linesText[num];
else
throw out_of_range("lineNo out of range");
}
Client.cpp
#include <iostream>
#include "TextQuery.h"
ifstream& openFile(ifstream &is,const string &fileName) {
is.close();
is.clear();
is.open(fileName.c_str());
return is;
}
int main(int argc,char **argv) {
if(argc != 2)
throw runtime_error("arguments error");
ifstream is;
if(!openFile(is,argv[1]))
throw runtime_error("open file error");
TextQuery tq;
tq.readFile(is);
while(true) {
cout << "please input word:" << endl;
string word;
cin >> word;
if(!cin || word == "quit") {
cout << "bye" << endl;
break;
}
set<TextQuery::lineNo> lineNos = tq.queryWordLineNos(word);
cout << "fount lines:" << lineNos.size() << endl;
set<TextQuery::lineNo>::iterator it = lineNos.begin();
while(it != lineNos.end()) {
cout << "(" << *it + 1 << ")" << " " << tq.getText(*it) << endl;
++it;
}
}
return 0;
}
text.txt内容:
my name is alexzhou
hello word
my name
is alexzhou
welcome here
welcome beijing
vs2010: 在项目属性里面 配置属性-》调试-》命令参数 里面写上参数:e:\\text.txt 。
程序运行结果如图:
转载请注明来自:Alex Zhou,本文链接:http://codingnow.cn/c-c/637.html