文本查詢程序-類

// 文本查詢程序-類.cpp : 定義控制臺(tái)應(yīng)用程序的入口點(diǎn)亦渗。
//

#include "stdafx.h"
#include<string>
#include<iostream>
#include<memory>
#include<sstream>
#include<set>
#include<map>
#include<vector>
#include<algorithm>
#include<iterator>
#include<fstream>

using namespace std;

class QueryResult//儲(chǔ)存查詢結(jié)果并輸出叼架!
{
public:
    using line_no = vector<string>::size_type;
    QueryResult(string s, shared_ptr<set<line_no>> p, shared_ptr<vector<string>> f) :find_word(s), lines(p), file(f) {}
    friend ostream &print(ostream &os, const QueryResult &qr);
    set<line_no>::const_iterator begin()const { return lines->cbegin(); }
    set<line_no>::const_iterator end()const { return lines->cend(); }
    const shared_ptr<vector<string>> get_file()const { return file; }

private:
    string find_word;
    shared_ptr<set<line_no>> lines;
    shared_ptr<vector<string>> file;
};

ostream &print(ostream &os, const QueryResult &qr)
{
    os << qr.find_word << " occurs " << qr.lines->size() << " times" << endl;
    for (auto &num : *(qr.lines))
    {
        os << "\t(line " << num + 1 << ") " << *(qr.file->begin() + num) << endl;
    }
    return os;
}

class TextQuery//讀取文件贸铜,并返回查詢結(jié)果至存儲(chǔ)類聪廉!
{
public:
    using line_no = vector<string>::size_type;
    TextQuery() = default;
    TextQuery(istream &in) { read(in); }
    void read_from_file(istream &in) { read(in); }
    QueryResult query(const string &find_word) const;                       //創(chuàng)建queryresult對(duì)象!

private:
    void read(istream &in);
    shared_ptr<vector<string>> file = make_shared<vector<string>>();            // 如果創(chuàng)建空的只能指針酥馍,必須進(jìn)行綁定(初始化)才可以使用辩昆!為什么不能使用new?
    map<string, shared_ptr<set<line_no>>> wm;                               //共享數(shù)據(jù)旨袒,避免拷貝增加計(jì)算量汁针!
};

QueryResult TextQuery::query(const string &find_word) const
{
    if (wm.find(find_word) == wm.cend())
    {
        return QueryResult(find_word, nullptr, file);
    }
    else
    {
        return QueryResult(find_word, wm.at(find_word), file);
    }
}

void TextQuery::read(istream &in)
{
    string text;
    while (getline(in, text))
    {
        file->push_back(text);
        int n = file->size() - 1;
        istringstream line(text);
        string word;
        while (line >> word)
        {
            auto &lines = wm[word];
            if (!lines)                         //如果為空指針术辐,則重新指向new set<line_no>
                lines.reset(new set<line_no>);
            lines->insert(n);
        }
    }
}

class Query_base
{
    friend class Query;
protected:
    using line_no = TextQuery::line_no;
    virtual ~Query_base() = default;
private:
    virtual QueryResult eval(const TextQuery&) const = 0;
    virtual string rep() const = 0;
};

class WordQuery :public Query_base
{
    friend class Query;
    WordQuery(const string &s) :query_word(s) {}//Query的構(gòu)造函數(shù)要調(diào)用此構(gòu)造函數(shù),因此必須前置施无!
    QueryResult eval(const TextQuery &t)const { return t.query(query_word); }
    string rep()const { return query_word; }
    string query_word;
};

class Query
{
    friend Query operator~(const Query &);
    friend Query operator|(const Query &, const Query&);
    friend Query operator&(const Query &, const Query&);
public:
    Query(const string &s) :q(new WordQuery(s)) {}                      //創(chuàng)建wordQuery指針對(duì)象辉词,用Query_Base指針指向!
    QueryResult eval(const TextQuery &t)const { return q->eval(t); }
    string rep()const { return q->rep(); }

    friend ostream &operator<<(ostream &os, const Query &query);
private:
    Query(shared_ptr<Query_base> query):q(query){}
    shared_ptr<Query_base> q;
};

ostream &operator<<(ostream &os, const Query &query)
{
    return os << query.rep();
}

class NotQuery :public Query_base
{
    friend Query operator~(const Query&);
    NotQuery(const Query &q):query(q){}
    string rep()const { return "~(" + query.rep() + ")"; }
    QueryResult eval(const TextQuery&)const;
    Query query;
};
inline Query operator~(const Query &operand)
{
    return shared_ptr<Query_base>(new NotQuery(operand));
}

class BinaryQuery:public Query_base
{
protected:
    BinaryQuery(const Query &l,const Query &r,string s):lhs(l),rhs(r),opSym(s){}
    string rep()const { return "(" + lhs.rep() + " " + opSym + " " + rhs.rep() + ")"; }
    Query lhs, rhs;
    string opSym;
};

class AndQuery:public BinaryQuery
{
    friend Query operator&(const Query&, const Query&);
    AndQuery(const Query &left, const Query &right) :BinaryQuery(left, right, "&") {};
    QueryResult eval(const TextQuery &)const;
};
inline Query operator&(const Query &lhs, const Query &rhs)
{
    return shared_ptr<Query_base>(new AndQuery(lhs, rhs));
}

class OrQuery:public BinaryQuery
{
    friend Query operator|(const Query&, const Query&);
    OrQuery(const Query &left, const Query &right) :BinaryQuery(left, right,"|") {}
    QueryResult eval(const TextQuery &)const;
};
inline Query operator|(const Query &lh, const Query &rh)
{
    return shared_ptr<Query_base>(new OrQuery(lh, rh));
}
QueryResult OrQuery::eval(const TextQuery &text)const
{
    using line_no = vector<string>::size_type;
    auto right = rhs.eval(text), left = lhs.eval(text);
    auto ret_lines = make_shared<set<line_no>>(left.begin(), left.end());
    ret_lines->insert(right.begin(),right.end());       //set.inser(b,e)
    return QueryResult(rep(), ret_lines, left.get_file());

}

QueryResult AndQuery::eval(const TextQuery &text)const
{
    using line_no = vector<string>::size_type;
    auto left = lhs.eval(text), right = rhs.eval(text);
    auto ret_lines = make_shared<set<line_no>>();
    set_intersection(left.begin(), left.end(), right.begin(), right.end(), inserter(*ret_lines, ret_lines->begin()));//插入迭代器inserter
    return QueryResult(rep(),ret_lines,left.get_file());
}

QueryResult NotQuery::eval(const TextQuery &text)const
{
    using line_no = vector<string>::size_type;
    auto result = query.eval(text);
    auto ret_lines = make_shared<set<line_no>>();
    auto beg = result.begin(), end = result.end();
    auto sz = result.get_file()->size();
    for (size_t n = 0; n != sz; ++n)
    {
        if (beg == end || *beg != n)
            ret_lines->insert(n);
        else if (beg != end)
            ++beg;
    }
    return QueryResult(rep(), ret_lines, result.get_file());
}

int main()
{
    string filename = "C:\\Users\\winack\\Documents\\Visual Studio 2017\\Projects\\文本查詢程序-My-繼承猾骡、\\123.txt";
    ifstream file(filename);
    TextQuery info(file);

    Query q = Query("is") & Query("the") | Query("have");
    //cout << q;
    print(cout, q.eval(info));
    q = Query("and");//Query自動(dòng)合成拷貝構(gòu)造函數(shù)瑞躺!
    print(cout, q.eval(info));

    return 0;
}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市兴想,隨后出現(xiàn)的幾起案子幢哨,更是在濱河造成了極大的恐慌,老刑警劉巖嫂便,帶你破解...
    沈念sama閱讀 216,591評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件嘱么,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡顽悼,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,448評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門几迄,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)蔚龙,“玉大人,你說(shuō)我怎么就攤上這事映胁∧靖” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 162,823評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵解孙,是天一觀的道長(zhǎng)坑填。 經(jīng)常有香客問(wèn)我,道長(zhǎng)弛姜,這世上最難降的妖魔是什么脐瑰? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,204評(píng)論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮廷臼,結(jié)果婚禮上苍在,老公的妹妹穿的比我還像新娘。我一直安慰自己荠商,他們只是感情好寂恬,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,228評(píng)論 6 388
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著莱没,像睡著了一般初肉。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上饰躲,一...
    開(kāi)封第一講書(shū)人閱讀 51,190評(píng)論 1 299
  • 那天牙咏,我揣著相機(jī)與錄音臼隔,去河邊找鬼。 笑死眠寿,一個(gè)胖子當(dāng)著我的面吹牛躬翁,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播盯拱,決...
    沈念sama閱讀 40,078評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼盒发,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了狡逢?” 一聲冷哼從身側(cè)響起宁舰,我...
    開(kāi)封第一講書(shū)人閱讀 38,923評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎奢浑,沒(méi)想到半個(gè)月后蛮艰,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,334評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡雀彼,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,550評(píng)論 2 333
  • 正文 我和宋清朗相戀三年壤蚜,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片徊哑。...
    茶點(diǎn)故事閱讀 39,727評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡袜刷,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出莺丑,到底是詐尸還是另有隱情著蟹,我是刑警寧澤,帶...
    沈念sama閱讀 35,428評(píng)論 5 343
  • 正文 年R本政府宣布梢莽,位于F島的核電站萧豆,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏昏名。R本人自食惡果不足惜涮雷,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,022評(píng)論 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望轻局。 院中可真熱鬧份殿,春花似錦、人聲如沸嗽交。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,672評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)夫壁。三九已至拾枣,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背梅肤。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,826評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工司蔬, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人姨蝴。 一個(gè)月前我還...
    沈念sama閱讀 47,734評(píng)論 2 368
  • 正文 我出身青樓俊啼,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親左医。 傳聞我的和親對(duì)象是個(gè)殘疾皇子授帕,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,619評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容