IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> C++primer(第五版)第十二章编程题 -> 正文阅读

[C++知识库]C++primer(第五版)第十二章编程题

练习12.2
/******************************************************************************
 * 编写你自己的StrBlob类,包含const版本的front和back。
 *****************************************************************************/

#include <iostream>
#include <memory>
#include <vector>

using std::cout;
using std::initializer_list;
using std::make_shared;
using std::out_of_range;
using std::shared_ptr;
using std::string;
using std::vector;

using size_type = vector<string>::size_type;

class StrBlob
{
private:
    shared_ptr<vector<string>> data;
    void check(size_type i, const std::string &msg) const;

public:
    StrBlob();
    StrBlob(initializer_list<string> il);
    size_type size() const { return data->size(); }
    bool empty() const { return data->empty(); }
    void push_back(const string &t) { data->push_back(t); }
    void pop_back();
    string &front();
    string &back();
    const string &front() const;
    const string &back() const;
};

StrBlob::StrBlob() : data(make_shared<vector<string>>()) {}

StrBlob::StrBlob(initializer_list<string> il) : data(make_shared<vector<string>>(il)) {}

void StrBlob::check(size_type i, const string &msg) const
{
    if (i >= data->size())
        throw out_of_range(msg);
}

string &StrBlob::front()
{
    check(0, "front on empty StrBlob");
    return data->front();
}

const string &StrBlob::front() const
{
    check(0, "front on empty StrBlob");
    return data->front();
}

string &StrBlob::back()
{
    check(0, "back on empty StrBlob");
    return data->back();
}

const string &StrBlob::back() const
{
    check(0, "back on empty StrBlob");
    return data->back();
}

void StrBlob::pop_back()
{
    check(0, "pop_back on empty StrBlob");
}

int main()
{
    StrBlob b1;
    StrBlob b2 = {"a", "an", "the"};
    b1 = b2;
    b2.push_back("about");
    cout << "size of b1: " << b1.size() << "\nsize of b1: " << b2.size() << "\n";
    return 0;
}
练习12.6
/******************************************************************************
 * 编写函数,返回一个动态分配的int的vector。将此vector传递给另一个函数,这个函数读取标准输
 * 入,将读入的值保存在vector元素中。再将vector传递给另一个函数,打印读入的值。记得在恰当的
 * 时刻delete vector。
 *****************************************************************************/

#include <iostream>
#include <vector>
#include <memory>

using std::cin;
using std::cout;
using std::vector;

vector<int> *creat_vector(void)
{
    return new vector<int>;
}

void read_to_vector(vector<int> *pv)
{
    int num = 0;
    while (cin >> num)
    {
        pv->push_back(num);
    }
}

void print_vector(const vector<int> *pv)
{
    for (const auto &num : *pv)
        cout << num << "\t";
    cout << "\n";
}

int main()
{
    vector<int> *pv = creat_vector();
    read_to_vector(pv);
    print_vector(pv);
    return 0;
    delete pv;
    return 0;
}
练习12.7
/******************************************************************************
 * 重做上一题,这次使用shared_ptr而不是内置指针。
 *****************************************************************************/

#include <iostream>
#include <vector>
#include <memory>

using std::cin;
using std::cout;
using std::make_shared;
using std::shared_ptr;
using std::vector;

shared_ptr<vector<int>> creat_vector(void)
{
    return make_shared<vector<int>>();
}

void read_to_vector(shared_ptr<vector<int>> pv)
{
    int num = 0;
    while (cin >> num)
    {
        pv->push_back(num);
    }
}

void print_vector(const shared_ptr<vector<int>> pv)
{
    for (const auto &num : *pv)
        cout << num << "\t";
    cout << "\n";
}

int main()
{
    shared_ptr<vector<int>> pv = creat_vector();
    read_to_vector(pv);
    print_vector(pv);
    return 0;
}
练习12.14
/******************************************************************************
 * 编写你自己版本的用shared_ptr管理connection的函数。
 *****************************************************************************/

#include <memory>
#include <iostream>

using std::cout;
using std::shared_ptr;
using std::string;

struct destination
{
    string infodes;
};
using connection = struct Connection
{
    string infocon;
} *;

connection connect(destination *p)
{
    connection q = new Connection;
    return q;
};

void disconnect(connection q) { delete q; }

void end_connection(connection *p) { disconnect(*p); }

void f(destination &d)
{
    connection c = connect(&d);
    shared_ptr<connection> p(&c, end_connection);
}

int main()
{
    destination d;
    f(d);
    return 0;
}
练习12.15
/******************************************************************************
 * 重写第一题的程序,用lambda(参见10.3.2节,第346页)代替end_connection函数。
 *****************************************************************************/

#include <memory>
#include <iostream>

using std::cout;
using std::shared_ptr;
using std::string;

struct destination
{
    string infodes;
};
using connection = struct Connection
{
    string infocon;
} *;

connection connect(destination *p)
{
    connection q = new Connection;
    return q;
};

void disconnect(connection q) { delete q; }

void f(destination &d)
{
    connection c = connect(&d);
    shared_ptr<connection> p(&c, [](connection *q)
                             { disconnect(*q); });
}

int main()
{
    destination d;
    f(d);
    return 0;
}
练习12.16
/******************************************************************************
 * 如果你试图拷贝或赋值unique_ptr,编译器并不总是能给出易于理解的错误信息。编写包含这种错误的
 * 程序,观察编译器如何诊断这种错误。
 *****************************************************************************/
#include <memory>

using std::unique_ptr;

int main()
{
    unique_ptr<int> ut;
    auto pt = ut;
    ut = pt;
    return 0;
}
练习12.19
/******************************************************************************
 * 定义你自己版本的StrBlobPtr,更新StrBlob类,加入恰当的friend声明及begin和end成员。
 *****************************************************************************/

#include <iostream>
#include <memory>
#include <vector>

using std::cout;
using std::initializer_list;
using std::make_shared;
using std::out_of_range;
using std::runtime_error;
using std::shared_ptr;
using std::string;
using std::vector;
using std::weak_ptr;

using size_type = vector<string>::size_type;

class StrBlobPtr;

class StrBlob
{
private:
    shared_ptr<vector<string>> data;
    void check(size_type i, const std::string &msg) const;

public:
    friend class StrBlobPtr;
    StrBlob();
    StrBlob(initializer_list<string> il);
    StrBlobPtr begin();
    StrBlobPtr end();
    size_type size() const { return data->size(); }
    bool empty() const { return data->empty(); }
    void push_back(const string &t) { data->push_back(t); }
    void pop_back();
    string &front();
    string &back();
    const string &front() const;
    const string &back() const;
};

class StrBlobPtr
{
private:
    shared_ptr<vector<string>> check(size_t, const string &) const;
    weak_ptr<vector<string>> wptr;
    size_t curr;

public:
    StrBlobPtr() : curr(0) {}
    StrBlobPtr(StrBlob &a, size_t sz = 0) : wptr(a.data), curr(sz) {}
    string &deref() const;
    StrBlobPtr &incr();
};

StrBlob::StrBlob() : data(make_shared<vector<string>>()) {}

StrBlob::StrBlob(initializer_list<string> il) : data(make_shared<vector<string>>(il)) {}

void StrBlob::check(size_type i, const string &msg) const
{
    if (i >= data->size())
        throw out_of_range(msg);
}

string &StrBlob::front()
{
    check(0, "front on empty StrBlob");
    return data->front();
}

const string &StrBlob::front() const
{
    check(0, "front on empty StrBlob");
    return data->front();
}

string &StrBlob::back()
{
    check(0, "back on empty StrBlob");
    return data->back();
}

const string &StrBlob::back() const
{
    check(0, "back on empty StrBlob");
    return data->back();
}

void StrBlob::pop_back()
{
    check(0, "pop_back on empty StrBlob");
}

shared_ptr<vector<string>> StrBlobPtr::check(size_t i, const string &msg) const
{
    auto ret = wptr.lock();
    if (!ret)
        throw runtime_error("unbound StrBlobPtr");
    if (i >= ret->size())
        throw out_of_range(msg);
    return ret;
}

string &StrBlobPtr::deref() const
{
    auto p = check(curr, "dereference past end");
    return (*p)[curr];
}

StrBlobPtr &StrBlobPtr::incr()
{
    check(curr, "increment past end of StrBlobPtr");
    ++curr;
    return *this;
}

StrBlobPtr StrBlob::begin()
{
    return StrBlobPtr(*this);
}
StrBlobPtr StrBlob::end()
{
    auto ret = StrBlobPtr(*this, data->size());
    return ret;
}

int main()
{
    StrBlob b1 = {"a", "an", "the"};
    StrBlobPtr sbp(b1, 0);
    cout << sbp.deref() << "\t" << sbp.incr().deref() << "\n";
    return 0;
}
练习12.20
/******************************************************************************
 * 编写程序,逐行读入一个输入文件,将内容存入一个Strblob中,用一个StrBlobPtr打印出StrBlob
 * 中的每个元素。
 *****************************************************************************/

#include <iostream>
#include <memory>
#include <vector>
#include <fstream>

using std::cerr;
using std::cout;
using std::getline;
using std::ifstream;
using std::initializer_list;
using std::make_shared;
using std::out_of_range;
using std::runtime_error;
using std::shared_ptr;
using std::string;
using std::vector;
using std::weak_ptr;

using size_type = vector<string>::size_type;

class StrBlobPtr;

class StrBlob
{
private:
    shared_ptr<vector<string>> data;
    void check(size_type i, const std::string &msg) const;

public:
    friend class StrBlobPtr;
    StrBlob();
    StrBlob(initializer_list<string> il);
    StrBlobPtr begin();
    StrBlobPtr end();
    size_type size() const { return data->size(); }
    bool empty() const { return data->empty(); }
    void push_back(const string &t) { data->push_back(t); }
    void pop_back();
    string &front();
    string &back();
    const string &front() const;
    const string &back() const;
};

class StrBlobPtr
{
private:
    shared_ptr<vector<string>> check(size_t, const string &) const;
    weak_ptr<vector<string>> wptr;
    size_t curr;

public:
    StrBlobPtr() : curr(0) {}
    StrBlobPtr(StrBlob &a, size_t sz = 0) : wptr(a.data), curr(sz) {}
    string &deref() const;
    StrBlobPtr &incr();
};

StrBlob::StrBlob() : data(make_shared<vector<string>>()) {}

StrBlob::StrBlob(initializer_list<string> il) : data(make_shared<vector<string>>(il)) {}

void StrBlob::check(size_type i, const string &msg) const
{
    if (i >= data->size())
        throw out_of_range(msg);
}

string &StrBlob::front()
{
    check(0, "front on empty StrBlob");
    return data->front();
}

const string &StrBlob::front() const
{
    check(0, "front on empty StrBlob");
    return data->front();
}

string &StrBlob::back()
{
    check(0, "back on empty StrBlob");
    return data->back();
}

const string &StrBlob::back() const
{
    check(0, "back on empty StrBlob");
    return data->back();
}

void StrBlob::pop_back()
{
    check(0, "pop_back on empty StrBlob");
}

shared_ptr<vector<string>> StrBlobPtr::check(size_t i, const string &msg) const
{
    auto ret = wptr.lock();
    if (!ret)
        throw runtime_error("unbound StrBlobPtr");
    if (i >= ret->size())
        throw out_of_range(msg);
    return ret;
}

string &StrBlobPtr::deref() const
{
    auto p = check(curr, "dereference past end");
    return (*p)[curr];
}

StrBlobPtr &StrBlobPtr::incr()
{
    check(curr, "increment past end of StrBlobPtr");
    ++curr;
    return *this;
}

StrBlobPtr StrBlob::begin()
{
    return StrBlobPtr(*this);
}
StrBlobPtr StrBlob::end()
{
    auto ret = StrBlobPtr(*this, data->size());
    return ret;
}

int main()
{
    ifstream inf("cplusplus//multiple//exercise12_20//txt//in_file.txt");
    if (!inf)
    {
        cerr << "文件打开失败!\n";
        return -1;
    }
    string str;
    StrBlob inb;
    StrBlobPtr inbp(inb, 0);
    while (getline(inf, str))
        inb.push_back(str);
    for (size_t i = 0; i != inb.size(); inbp.incr(), ++i)
        cout << inbp.deref() << "\n";
    return 0;
}
练习12.22
/******************************************************************************
 * 为了能让StrBlobPtr使用const StrBlob,你觉得应该如何修改?定义一个名为
 * ConstStrBlobPtr的类,使其能够指向const StrBlob。
 *****************************************************************************/

#include <iostream>
#include <memory>
#include <vector>

using std::cout;
using std::initializer_list;
using std::make_shared;
using std::out_of_range;
using std::runtime_error;
using std::shared_ptr;
using std::string;
using std::vector;
using std::weak_ptr;

using size_type = vector<string>::size_type;

class ConstStrBlobPtr;

class StrBlob
{
private:
    shared_ptr<vector<string>> data;
    void check(size_type i, const std::string &msg) const;

public:
    friend class ConstStrBlobPtr;
    StrBlob();
    StrBlob(initializer_list<string> il);
    ConstStrBlobPtr begin();
    ConstStrBlobPtr end();
    size_type size() const { return data->size(); }
    bool empty() const { return data->empty(); }
    void push_back(const string &t) { data->push_back(t); }
    void pop_back();
    string &front();
    string &back();
    const string &front() const;
    const string &back() const;
};

class ConstStrBlobPtr
{
private:
    shared_ptr<vector<string>> check(size_t, const string &) const;
    weak_ptr<vector<string>> wptr;
    size_t curr;

public:
    ConstStrBlobPtr() : curr(0) {}
    ConstStrBlobPtr(const StrBlob &a, size_t sz = 0) : wptr(a.data), curr(sz) {}
    string &deref() const;
    ConstStrBlobPtr &incr();
};

StrBlob::StrBlob() : data(make_shared<vector<string>>()) {}

StrBlob::StrBlob(initializer_list<string> il) : data(make_shared<vector<string>>(il)) {}

void StrBlob::check(size_type i, const string &msg) const
{
    if (i >= data->size())
        throw out_of_range(msg);
}

string &StrBlob::front()
{
    check(0, "front on empty StrBlob");
    return data->front();
}

const string &StrBlob::front() const
{
    check(0, "front on empty StrBlob");
    return data->front();
}

string &StrBlob::back()
{
    check(0, "back on empty StrBlob");
    return data->back();
}

const string &StrBlob::back() const
{
    check(0, "back on empty StrBlob");
    return data->back();
}

void StrBlob::pop_back()
{
    check(0, "pop_back on empty StrBlob");
}

shared_ptr<vector<string>> ConstStrBlobPtr::check(size_t i, const string &msg) const
{
    auto ret = wptr.lock();
    if (!ret)
        throw runtime_error("unbound StrBlobPtr");
    if (i >= ret->size())
        throw out_of_range(msg);
    return ret;
}

string &ConstStrBlobPtr::deref() const
{
    auto p = check(curr, "dereference past end");
    return (*p)[curr];
}

ConstStrBlobPtr &ConstStrBlobPtr::incr()
{
    check(curr, "increment past end of StrBlobPtr");
    ++curr;
    return *this;
}

ConstStrBlobPtr StrBlob::begin()
{
    return ConstStrBlobPtr(*this);
}
ConstStrBlobPtr StrBlob::end()
{
    auto ret = ConstStrBlobPtr(*this, data->size());
    return ret;
}

int main()
{
    const StrBlob b1 = {"a", "an", "the"};
    ConstStrBlobPtr sbp(b1, 0);
    cout << sbp.deref() << "\t" << sbp.incr().deref() << "\n";
    return 0;
}
练习12.23
/******************************************************************************
 * 编写一个程序,连接两个字符串字面常量,将结果保存在一个动态分配的char数组中。重写这个程序,
 * 连接两个标准库string对象。
 *****************************************************************************/

/*** 字符串字面常量 ***/
#include <iostream>

using std::cout;

int main()
{
    const char *strp1 = "qwertyuiop", *strp2 = "1234567890";
    char *p = new char[20];
    size_t i = 0;
    for (i = 0; i != 10; ++i)
        p[i] = strp1[i];
    for (size_t j = 0; j != 10; ++j, ++i)
        p[i] = strp2[j];
    cout << p;
    delete[] p;
    return 0;
}

/*** 标准库string对象 ***/
#include <iostream>

using std::cout;
using std::string;

int main()
{
    string strp1 = "qwertyuiop", strp2 = "1234567890";
    char *p = new char[20];
    strp1 += strp2;
    for (size_t i = 0; i != 20; ++i)
        p[i] = strp1[i];
    cout << p;
    delete[] p;
    return 0;
}
练习12.24
/******************************************************************************
 * 编写一个程序,从标准输入读取一个字符串,存入一个动态分配的字符数组中。描述你的程序如何处理
 * 变长输入。测试你的程序,输入一个超出你分配的数组长度的字符串。
 *****************************************************************************/

#include <iostream>

using std::cin;
using std::cout;
using std::string;

int main()
{
    string str;
    char *p = new char[10];
    cin >> str;
    if (str.size() > 10)
    {
        delete[] p;
        p = new char[str.size()];
    }
    for (size_t i = 0; i != str.size(); ++i)
        p[i] = str[i];
    for (size_t i = 0; i != str.size(); ++i)
        cout << p[i];
    cout << "\n";
    delete[] p;
    return 0;
}
练习12.26
/******************************************************************************
 * 用allocator重写第427页中的程序。
 *****************************************************************************/
#include <iostream>

using std::allocator;
using std::cin;
using std::cout;
using std::string;

int main()
{
    size_t n = 10;
    allocator<string> a;
    auto p = a.allocate(n);
    string s;
    string *q = p;
    while (cin >> s && q != p + n)
        a.construct(q++, s);
    const size_t size = q - p;
    q -= size;
    for (size_t i = 0; i != size; ++i)
        cout << q[i] << "\n";
    while (q != p + size)
        a.destroy(q++);
    a.deallocate(p, n);
    return 0;
}
练习12.27
/******************************************************************************
 * TextQuery 和 QueryResult类只使用了我们已经介绍过的语言和标准库特性。不要提前看后续章节
 * 内容,只用已经学到的知识对这两个类编写你自己的版本。
 *****************************************************************************/

/*** TextQuery.hpp ***/
#ifndef TEXTQUERY_HPP_
#define TEXTQUERY_HPP_

#include <vector>
#include <set>
#include <sstream>

using std::ifstream;
using std::istringstream;
using std::set;
using std::vector;

class TextQuery
{
public:
    TextQuery() = default;
    TextQuery(ifstream &infile);
    map<size_t, string> query(const string word);
    vector<string> text;
    map<string, set<size_t>> word_line;
};

TextQuery::TextQuery(ifstream &infile)
{
    string line_text;
    while (getline(infile, line_text))
        text.push_back(line_text);
    string text_word;
    for (size_t i = 0; i != text.size(); ++i)
    {
        istringstream word_in(text[i]);
        while (word_in >> text_word)
        {
            bool wordExist = false;
            for (auto &wl : word_line)
                if (wl.first == text_word)
                {
                    wl.second.insert(i);
                    wordExist = true;
                    break;
                }
            if (!wordExist)
            {
                set<size_t> si;
                si.insert(i);
                word_line[text_word] = si;
            }
        }
    }
}

map<size_t, string> TextQuery::query(const string word)
{
    map<size_t, string> line_str;
    for (const auto &w : word_line)
    {
        if (w.first == word)
        {
            auto wbg = w.second.begin();
            for (size_t i = 0; i != w.second.size(); ++i, ++wbg)
                line_str[*wbg + 1] = text[*wbg];
        }
    }
    return line_str;
}
#endif

/*** QueryResult.hpp ***/
#ifndef QUERYRESULT_HPP_
#define QUERYRESULT_HPP_

#include <iostream>
#include <map>

using std::map;
using std::ostream;
using std::string;

class QueryResult
{
public:
    QueryResult() = default;
    void print(ostream &out, map<size_t, string> pss);
};

void QueryResult::print(ostream &out, map<size_t, string> pss)
{
    out << "该元素出现了" << pss.size() << "次\n";
    for (auto &ss : pss)
        out << "(行 " << ss.first << ")" << ss.second + "\n";
}
#endif

/*** main.c ***/
#include <fstream>
#include "QueryResult.hpp"
#include "TextQuery.hpp"

using std::cerr;
using std::cin;
using std::cout;

void runQueries(ifstream &infile)
{
    TextQuery tq(infile);
    QueryResult qr;
    while (true)
    {
        cout << "输入查找的单词,或按“q”退出:";
        string s;
        if (!(cin >> s) || s == "q")
            break;
        qr.print(cout, tq.query(s));
    }
}

int main()
{
    ifstream infile("exercise12_27/txt/infile.txt");
    if (!infile)
    {
        cerr << "文件打开失败!\n";
        return -1;
    }
    runQueries(infile);
    return 0;
}
练习12.28
/******************************************************************************
 * 编写程序实现文本查询,不要定义类来管理数据。你的程序应该接受一个文件,并与用户交互来查询单
 * 词。使用vector、map和set容器来保存来自文件的数据并生成查询结果。
 *****************************************************************************/
#include <fstream>
#include <vector>
#include <sstream>
#include <map>
#include <set>
#include <iostream>

using std::cerr;
using std::cin;
using std::cout;
using std::getline;
using std::ifstream;
using std::istringstream;
using std::map;
using std::ostream;
using std::set;
using std::string;
using std::vector;

vector<string> vline;
map<string, set<size_t>> word_line;

void process_text(ifstream &infile)
{
    string line, word;
    while (getline(infile, line))
        vline.push_back(line);
    for (size_t i = 0; i != vline.size(); ++i)
    {
        istringstream inw(vline[i]);
        while (inw >> word)
        {
            bool wordExist = false;
            for (auto &wl : word_line)
                if (wl.first == word)
                {
                    wl.second.insert(i);
                    wordExist = true;
                    break;
                }
            if (!wordExist)
            {
                set<size_t> si;
                si.insert(i);
                word_line[word] = si;
            }
        }
    }
}

map<size_t, string> query(const string word)
{
    map<size_t, string> line_str;
    for (auto &wl : word_line)
        if (wl.first == word)
        {
            auto wbg = wl.second.begin();
            for (size_t i = 0; i != wl.second.size(); ++i, ++wbg)
                line_str[*wbg + 1] = vline[*wbg];
        }
    return line_str;
}

void print(ostream &out, map<size_t, string> pss)
{
    out << "该元素出现了" << pss.size() << "次\n";
    for (auto &ss : pss)
        out << "(行 " << ss.first << ")" << ss.second + "\n";
}

int main()
{
    ifstream infile("exercise12_28\\txt\\infile.txt");
    if (!infile)
    {
        cerr << "文件打开失败!\n";
        return -1;
    }
    process_text(infile);
    while (true)
    {
        cout << "输入查找的单词,或按“q”退出:";
        string s;
        if (!(cin >> s) || s == "q")
            break;
        print(cout, query(s));
    }
    return 0;
}
练习12.29
/******************************************************************************
 * 编写程序实现文本查询,不要定义类来管理数据。你的程序应该接受一个文件,并与用户交互来查询单
 * 词。使用vector、map和set容器来保存来自文件的数据并生成查询结果。
 *****************************************************************************/
#include <fstream>
#include <vector>
#include <sstream>
#include <map>
#include <set>
#include <iostream>

using std::cerr;
using std::cin;
using std::cout;
using std::getline;
using std::ifstream;
using std::istringstream;
using std::map;
using std::ostream;
using std::set;
using std::string;
using std::vector;

vector<string> vline;
map<string, set<size_t>> word_line;

void process_text(ifstream &infile)
{
    string line, word;
    while (getline(infile, line))
        vline.push_back(line);
    for (size_t i = 0; i != vline.size(); ++i)
    {
        istringstream inw(vline[i]);
        while (inw >> word)
        {
            bool wordExist = false;
            for (auto &wl : word_line)
                if (wl.first == word)
                {
                    wl.second.insert(i);
                    wordExist = true;
                    break;
                }
            if (!wordExist)
            {
                set<size_t> si;
                si.insert(i);
                word_line[word] = si;
            }
        }
    }
}

map<size_t, string> query(const string word)
{
    map<size_t, string> line_str;
    for (auto &wl : word_line)
        if (wl.first == word)
        {
            auto wbg = wl.second.begin();
            for (size_t i = 0; i != wl.second.size(); ++i, ++wbg)
                line_str[*wbg + 1] = vline[*wbg];
        }
    return line_str;
}

void print(ostream &out, map<size_t, string> pss)
{
    out << "该元素出现了" << pss.size() << "次\n";
    for (auto &ss : pss)
        out << "(行 " << ss.first << ")" << ss.second + "\n";
}

int main()
{
    ifstream infile("exercise12_29\\txt\\infile.txt");
    if (!infile)
    {
        cerr << "文件打开失败!\n";
        return -1;
    }
    process_text(infile);
    do
    {
        cout << "输入查找的单词,或按“q”退出:";
        string s;
        if (!(cin >> s) || s == "q")
            break;
        print(cout, query(s));
    } while (true);
    return 0;
}
练习12.30
/******************************************************************************
 * 定义你自己版本的TextQuery和QueryResult类,并执行12.3。1节(第431页)中的runQueries
 * 函数。
 *****************************************************************************/

/*** TextQuery.hpp ***/
#ifndef TEXTQUERY_HPP_
#define TEXTQUERY_HPP_
#include "QueryResult.hpp"
#include <map>
#include <sstream>

using std::getline;
using std::ifstream;
using std::istringstream;
using std::map;

class TextQuery
{
public:
    TextQuery(ifstream &);
    QueryResult query(string &) const;

private:
    shared_ptr<vector<string>> file;
    map<string, shared_ptr<set<line_no>>> wm;
};

TextQuery::TextQuery(ifstream &is) : file(new vector<string>)
{
    string text;
    while (getline(is, text))
    {
        file->push_back(text);
        int n = file->size() - 1;
        istringstream line(text);
        string word;
        while (line >> word)
        {
            auto &lines = wm[word];
            if (!lines)
                lines.reset(new set<line_no>);
            lines->insert(n);
        }
    }
}
QueryResult TextQuery::query(string &sought) const
{
    static shared_ptr<set<line_no>> nodata(new set<line_no>);
    auto loc = wm.find(sought);
    if (loc == wm.end())
        return QueryResult(sought, nodata, file);
    else
        return QueryResult(sought, loc->second, file);
}
#endif

/*** QueryResult ***/
#ifndef QUERYRESULT_HPP_
#define QUERYRESULT_HPP_
#include <memory>
#include <set>
#include <vector>

using std::endl;
using std::ostream;
using std::set;
using std::shared_ptr;
using std::string;
using std::vector;
using line_no = vector<string>::size_type;

class QueryResult
{
    friend ostream &print(ostream &, const QueryResult &);

public:
    QueryResult(string s, shared_ptr<set<line_no>> p, shared_ptr<vector<string>> f) : sought(s), lines(p), file(f) {}

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

string make_plural(size_t ctr, const string &ending, const string &word = "s")
{
    return (ctr > 1) ? word + ending : word;
}

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

#endif

/*** main ***/
#include <fstream>
#include <iostream>
#include "QueryResult.hpp"
#include "TextQuery.hpp"

using std::cerr;
using std::cin;
using std::cout;

void runQueries(ifstream &infile)
{
    TextQuery tq(infile);
    while (true)
    {
        cout << "enter word to look for, or q to quit: ";
        string s;
        if (!(cin >> s) || s == "q")
            break;
        print(cout, tq.query(s)) << endl;
    }
}

int main()
{
    ifstream infile("exercise12_30\\txt\\infile.txt");
    if (!infile)
    {
        cerr << "Open file error!\n";
        return -1;
    }
    runQueries(infile);
    return 0;
}
练习12.32
/******************************************************************************
 * 重写TextQuery和QueryResult类,用strBlob代替vector<string>保存输入文件。
 *****************************************************************************/

/*** strBlob.hpp ***/
#ifndef STRBLOB_HPP_
#define STRBLOB_HPP_

#include <iostream>
#include <memory>
#include <vector>
#include <fstream>

using std::cerr;
using std::cout;
using std::getline;
using std::ifstream;
using std::initializer_list;
using std::make_shared;
using std::out_of_range;
using std::runtime_error;
using std::shared_ptr;
using std::string;
using std::vector;
using std::weak_ptr;

using size_type = vector<string>::size_type;

class StrBlobPtr;

class StrBlob
{
private:
    shared_ptr<vector<string>> data;
    void check(size_type i, const std::string &msg) const;

public:
    friend class StrBlobPtr;
    StrBlob();
    StrBlob(initializer_list<string> il);
    StrBlobPtr begin();
    StrBlobPtr end();
    size_type size() const { return data->size(); }
    bool empty() const { return data->empty(); }
    void push_back(const string &t) { data->push_back(t); }
    void pop_back();
    string &front();
    string &back();
    const string &front() const;
    const string &back() const;
};

class StrBlobPtr
{
private:
    shared_ptr<vector<string>> check(size_t, const string &) const;
    weak_ptr<vector<string>> wptr;
    size_t curr;

public:
    StrBlobPtr() : curr(0) {}
    StrBlobPtr(StrBlob &a, size_t sz = 0) : wptr(a.data), curr(sz) {}
    string &deref() const;
    StrBlobPtr &incr();
};

StrBlob::StrBlob() : data(make_shared<vector<string>>()) {}

StrBlob::StrBlob(initializer_list<string> il) : data(make_shared<vector<string>>(il)) {}

void StrBlob::check(size_type i, const string &msg) const
{
    if (i >= data->size())
        throw out_of_range(msg);
}

string &StrBlob::front()
{
    check(0, "front on empty StrBlob");
    return data->front();
}

const string &StrBlob::front() const
{
    check(0, "front on empty StrBlob");
    return data->front();
}

string &StrBlob::back()
{
    check(0, "back on empty StrBlob");
    return data->back();
}

const string &StrBlob::back() const
{
    check(0, "back on empty StrBlob");
    return data->back();
}

void StrBlob::pop_back()
{
    check(0, "pop_back on empty StrBlob");
}

shared_ptr<vector<string>> StrBlobPtr::check(size_t i, const string &msg) const
{
    auto ret = wptr.lock();
    if (!ret)
        throw runtime_error("unbound StrBlobPtr");
    if (i >= ret->size())
        throw out_of_range(msg);
    return ret;
}

string &StrBlobPtr::deref() const
{
    auto p = check(curr, "dereference past end");
    return (*p)[curr];
}

StrBlobPtr &StrBlobPtr::incr()
{
    check(curr, "increment past end of StrBlobPtr");
    ++curr;
    return *this;
}

StrBlobPtr StrBlob::begin()
{
    return StrBlobPtr(*this);
}
StrBlobPtr StrBlob::end()
{
    auto ret = StrBlobPtr(*this, data->size());
    return ret;
}
#endif

/*** TextQuery.hpp ***/
#ifndef TEXTQUERY_HPP_
#define TEXTQUERY_HPP_
#include "QueryResult.hpp"
#include <map>
#include <sstream>
#include "strBlob.hpp"

using std::getline;
using std::ifstream;
using std::istringstream;
using std::map;

class TextQuery
{
public:
    TextQuery(ifstream &);
    QueryResult query(string &) const;

private:
    StrBlob file;
    map<string, shared_ptr<set<line_no>>> wm;
};

TextQuery::TextQuery(ifstream &is)
{
    string text;
    while (getline(is, text))
    {
        file.push_back(text);
        int n = file.size() - 1;
        istringstream line(text);
        string word;
        while (line >> word)
        {
            auto &lines = wm[word];
            if (!lines)
                lines.reset(new set<line_no>);
            lines->insert(n);
        }
    }
}
QueryResult TextQuery::query(string &sought) const
{
    static shared_ptr<set<line_no>> nodata(new set<line_no>);
    auto loc = wm.find(sought);
    if (loc == wm.end())
        return QueryResult(sought, nodata, file);
    else
        return QueryResult(sought, loc->second, file);
}
#endif

/*** QueryResult.hpp ***/
#ifndef QUERYRESULT_HPP_
#define QUERYRESULT_HPP_
#include <memory>
#include <set>
#include <vector>
#include "strBlob.hpp"

using std::endl;
using std::ostream;
using std::set;
using std::shared_ptr;
using std::string;
using std::vector;
using line_no = vector<string>::size_type;

class QueryResult
{
    friend ostream &print(ostream &, const QueryResult &);

public:
    QueryResult(string s, shared_ptr<set<line_no>> p, StrBlob f) : sought(s), lines(p), file(f) {}

private:
    string sought;
    shared_ptr<set<line_no>> lines;
    StrBlob file;
};

string make_plural(size_t ctr, const string &ending, const string &word = "s")
{
    return (ctr > 1) ? word + ending : word;
}

ostream &print(ostream &os, const QueryResult &qr)
{
    os << qr.sought << " occurc " << qr.lines->size() << " " << make_plural(qr.lines->size(), "time", "s") << endl;
    auto qrfile = qr.file;
    for (auto num : *qr.lines)
    {
        StrBlobPtr inbp(qrfile, 0);
        auto temp = num;
        while (temp-- != 0)
            inbp.incr();
        os << "\t(line " << num + 1 << ") " << inbp.deref() << endl;
    }
    return os;
}

#endif

/*** main.cpp ***/
#include <fstream>
#include <iostream>
#include "QueryResult.hpp"
#include "TextQuery.hpp"

using std::cerr;
using std::cin;
using std::cout;

void runQueries(ifstream &infile)
{
    TextQuery tq(infile);
    while (true)
    {
        cout << "enter word to look for, or q to quit: ";
        string s;
        if (!(cin >> s) || s == "q")
            break;
        print(cout, tq.query(s)) << endl;
    }
}

int main()
{
    ifstream infile("exercise12_32\\txt\\infile.txt");
    if (!infile)
    {
        cerr << "Open file error!\n";
        return -1;
    }
    runQueries(infile);
    return 0;
}
练习12.33
/******************************************************************************
 * 在第15章中我们将扩展查询系统,在QueryResult类中将会需要一些额外的成员。添加名为begin和
 * end的成员,返回一个迭代器,指向一个给定查询返回的行号的set中的位置。再添加一个名为get_file
 * 的成员,返回一个shared_ptr,指向QueryResult对象中的文件。
 *****************************************************************************/

/*** TextQuery.hpp ***/
#ifndef TEXTQUERY_HPP_
#define TEXTQUERY_HPP_
#include "QueryResult.hpp"
#include <map>
#include <sstream>

using std::getline;
using std::ifstream;
using std::istringstream;
using std::map;

class TextQuery
{
public:
    TextQuery(ifstream &);
    QueryResult query(string &) const;

private:
    shared_ptr<vector<string>> file;
    map<string, shared_ptr<set<line_no>>> wm;
};

TextQuery::TextQuery(ifstream &is) : file(new vector<string>)
{
    string text;
    while (getline(is, text))
    {
        file->push_back(text);
        int n = file->size() - 1;
        istringstream line(text);
        string word;
        while (line >> word)
        {
            auto &lines = wm[word];
            if (!lines)
                lines.reset(new set<line_no>);
            lines->insert(n);
        }
    }
}
QueryResult TextQuery::query(string &sought) const
{
    static shared_ptr<set<line_no>> nodata(new set<line_no>);
    auto loc = wm.find(sought);
    if (loc == wm.end())
        return QueryResult(sought, nodata, file);
    else
        return QueryResult(sought, loc->second, file);
}
#endif

/*** QueryResult.hpp ***/
#ifndef QUERYRESULT_HPP_
#define QUERYRESULT_HPP_
#include <memory>
#include <set>
#include <vector>

using std::endl;
using std::ostream;
using std::set;
using std::shared_ptr;
using std::string;
using std::vector;
using line_no = vector<string>::size_type;

class QueryResult
{
    friend ostream &print(ostream &, const QueryResult &);

public:
    QueryResult(string s, shared_ptr<set<line_no>> p, shared_ptr<vector<string>> f) : sought(s), lines(p), file(f) {}
    set<line_no>::iterator begin() const;
    set<line_no>::iterator end() const;
    shared_ptr<vector<string>> get_file() const;

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

set<line_no>::iterator QueryResult::begin() const
{
    return this->lines->begin();
}

set<line_no>::iterator QueryResult::end() const
{
    return this->lines->end();
}

shared_ptr<vector<string>> QueryResult::get_file() const
{
    return this->file;
}

string make_plural(size_t ctr, const string &ending, const string &word = "s")
{
    return (ctr > 1) ? word + ending : word;
}

ostream &print(ostream &os, const QueryResult &qr)
{
    os << qr.sought << " occurc " << qr.lines->size() << " " << make_plural(qr.lines->size(), "time", "s") << endl;
    for (auto num = qr.begin(); num != qr.end(); ++num)
        os << "\t(line " << *num + 1 << ") " << *(qr.file->begin() + *num) << endl;
    return os;
}

#endif

/*** main.cpp ***/
#include <fstream>
#include <iostream>
#include "QueryResult.hpp"
#include "TextQuery.hpp"

using std::cerr;
using std::cin;
using std::cout;

void runQueries(ifstream &infile)
{
    TextQuery tq(infile);
    while (true)
    {
        cout << "enter word to look for, or q to quit: ";
        string s;
        if (!(cin >> s) || s == "q")
            break;
        print(cout, tq.query(s)) << endl;
    }
}

int main()
{
    ifstream infile("exercise12_33\\txt\\infile.txt");
    if (!infile)
    {
        cerr << "Open file error!\n";
        return -1;
    }
    runQueries(infile);
    return 0;
}
  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2021-09-03 11:43:10  更:2021-09-03 11:44:59 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 20:44:42-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码