Skip to content

Instantly share code, notes, and snippets.

@hustlijian
Created March 20, 2014 13:10
Show Gist options
  • Save hustlijian/9663384 to your computer and use it in GitHub Desktop.
Save hustlijian/9663384 to your computer and use it in GitHub Desktop.
text query class of <c++ primer>: input a file, and query the word occur lines
#include <iostream>
#include "TextQuery.h"
using namespace std;
int main(int argc, char const* argv[])
{
TextQuery text;
if (argc <2) {
cout << argv[0] << " filename" << endl; //usage: ./main filename
return -1;
}
ifstream input(argv[1]);
text.read_file(input);
cout << "input query string: " << endl;
string word;
while(cin >> word){
set<line_no> lines = text.run_query(word);
set<line_no>::size_type counts = lines.size();
cout << "element occurs " << counts << " times" << endl;
for (set<line_no>::iterator it = lines.begin();
it != lines.end(); it++) {
cout << "\t(line " << *it+1 << ") " << text.text_line(*it) << " " << endl;
}
cout << endl <<"input query string(end of ctrl+d): ";
}
return 0;
}
CC = g++
CFLAGS = -g -Wall
DIR_BIN = .
INCS_HEAD := .
LIB_PATH := #-L /usr/lib
LIBS := #-lpthread
SOURCE := $(wildcard ./*.cpp)
OBJS := $(patsubst %.cpp, %.o, $(SOURCE))
OUTPUT= main
%.o:%.cpp
$(CC) $(CFLAGS) $(addprefix -I, $(INCS_HEAD)) -c $< -o $@
all: ${OUTPUT}
main: $(OBJS)
$(CC) $(CFLAGS) $(addprefix -I,$(INCS_HEAD)) $(LIB_PATH) -o $@ $^ $(LIBS)
clean:
-rm -f $(OBJS)
-rm -f ${OUTPUT}
#include "TextQuery.h"
std::set<line_no> TextQuery::run_query(const std::string &str) const
{
std::map<std::string, std::set<line_no> >::const_iterator it =
word_map.find(str);
if(it != word_map.end()) { // found
return it->second;
}
return std::set<line_no>();
}
std::string TextQuery::text_line(line_no line)const
{
return lines_of_text[line];
}
void TextQuery::store_file(std::ifstream& is)
{
std::string temp;
while(getline(is, temp)) {
lines_of_text.push_back(temp);
}
}
void TextQuery::build_map(void)
{
for(line_no i=0; i != lines_of_text.size(); i++){
std::istringstream stream(lines_of_text[i]);
std::string word;
while (stream >> word) {
word = cleanup_str(word);
if (word_map.count(word)<1){ // not found
word_map[word] = std::set<line_no>();
}
word_map[word].insert(i);
}
}
}
std::string TextQuery::cleanup_str(const std::string &str)
{
std::string ret;
for(std::string::const_iterator it = str.begin();
it != str.end(); it++){
if (!ispunct(*it)) ret += tolower(*it);
}
return ret;
}
#ifndef TEXT_QUERY
#define TEXT_QUERY
#include <fstream>
#include <sstream>
#include <string>
#include <map>
#include <set>
#include <vector>
typedef std::vector<std::string>::size_type line_no;
class TextQuery {
public:
void read_file(std::ifstream &is){
store_file(is);
build_map();
}
std::set<line_no> run_query(const std::string&) const;
std::string text_line(line_no) const;
TextQuery (){}
~TextQuery (){}
private:
void store_file(std::ifstream&);
void build_map(void);
std::vector<std::string> lines_of_text;
std::map< std::string, std::set<line_no> > word_map;
static std::string cleanup_str(const std::string &);
};
#endif
@hustlijian
Copy link
Author

$ ./main TextQuery.cpp

input query string(end of ctrl+d): void
element occurs 2 times
(line 18) void TextQuery::store_file(std::ifstream& is)
(line 26) void TextQuery::build_map(void)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment