C++ Primer(第五版) 第九章练习答案

C++ Primer(第五版) 第九章练习答案

目录

  • C++ Primer(第五版) 第九章练习答案
      • 9.1
      • 9.2
      • 9.3
      • 9.4
      • 9.5
      • 9.6
      • 9.7
      • 9.8
      • 9.9
      • 9.10
      • 9.11
      • 9.12
      • 9.13
      • 9.14
      • 9.15
      • 9.16
      • 9.17
      • 9.18
      • 9.19
      • 9.20
      • 9.21
      • 9.22
      • 9.23
      • 9.24
      • 9.25
      • 9.26
      • 9.27
      • 9.28
      • 9.29
      • 9.30
      • 9.31
      • 9.32
      • 9.33
      • 9.34
      • 9.35
      • 9.36
      • 9.37
      • 9.38
      • 9.39
      • 9.40
      • 9.41
      • 9.42
      • 9.43
      • 9.44
      • 9.45
      • 9.46
      • 9.47
      • 9.48
      • 9.49
      • 9.50
      • 9.51
      • 9.52

9.1


/**
 * list  链表插入速度很快
 * deque 队列 头尾操作速度很快
 * vector 可变大小数组
 */

9.2

#include 
#include 

using namespace std;

int main()
{
    list<deque<int>> list;

    return 0;
}

9.3


/**
 * 指向同一容器, 或尾后元素
 * end 不在 begin 之前
 */

9.4

#include 
#include 

using namespace std;

bool find_int(const vector<int>::iterator &begin, const vector<int>::iterator &end, const int i)
{
    auto beg = begin;
    while (beg != end)
        if (*beg++ == i)
            return true;
    return false;
}

9.5

#include 
#include 

using namespace std;

vector<int>::iterator find_int(const vector<int>::iterator &begin, const vector<int>::iterator &end, const int i)
{
    auto beg = begin;
    while (beg != end)
    {
        if (*beg == i)
            return beg;
        ++beg;
    }

    return end;
}

9.6



/**
 * 链表只有 == !=
 */

9.7


/**
 * int&
 * vector::reference
 */

9.8


/**
 * list::const_iterator
 * list::iterator
 */

9.9


/**
 * 写
 * 读
 */

9.10


/**
 * vector::iterator
 * vector::const_iterator
 * vector::const_iterator
 * vector::const_iterator
 */

9.11

#include 
#include 

using namespace std;

int main()
{
    // 空
    vector<int> vec1;
    // 1 2 3
    vector<int> vec2{1, 2, 3};
    // 1 2 3
    vector<int> vec3(vec2);
    // 1 2 3
    vector<int> vec4(vec3.begin(), vec3.end());
    // 0 0 0 0 0 0 0 0 0 0
    vector<int> vec5(10);
    // 1 1 1 1 1 1 1 1 1 1 
    vector<int> vec6(10, 1);

    return 0;
}

9.12


/**
 * 容器类型和元素类型必须匹配
 * 容器类型和元素类型可以不同, 元素类型可以转换到目标类型
 */

9.13

#include 
#include 
#include 

using namespace std;

int main()
{
    list<int> list{1, 2, 3, 4, 5};
    vector<int> ivec{6, 7, 8, 9};

    vector<double> dvec(list.begin(), list.end());

    for(auto &i : dvec)
        cout << i << ends;
    cout << endl;

    dvec.assign(ivec.begin(), ivec.end());

    for(auto &i : dvec)
        cout << i << ends;
    cout << endl;

    return 0;
}

9.14

#include 
#include 
#include 
#include 

using namespace std;

int main()
{
    list<const char*> list{"x", "i", "a", "o"};

    vector<string> vec(list.begin(), list.end());

    for (auto &i : vec)
        cout << i << ends;
    cout << endl;

    return 0;
}

9.15

#include 
#include 

using namespace std;

int main()
{
    vector<int> v1{1, 2, 3, 4};
    vector<int> v2{1, 2, 3, 4, 5};
    vector<int> v3{1, 2, 3, 4};
    vector<int> v4{1, 1, 6, 4, 1};
    vector<int> v5{1, 3};

    cout << boolalpha
         << (v1 > v4) << ends
         << (v2 > v3) << ends
         << (v3 > v4) << ends
         << (v4 > vector<int>{1, 0, 8, 45, 4}) << ends
         << (v5 > v1) << endl;
    

    return 0;
}

9.16

#include 
#include 
#include 
#include 

using namespace std;

bool compare(list<int> &list, vector<int> &vec);

int main()
{
    list<int> list{1, 2, 3, 4, 5};
    vector<int> vec{1, 2, 3, 4, 5};

    cout << boolalpha 
         << compare(list, vec) << endl;

    return 0;
}

bool compare(list<int> &list, vector<int> &vec)
{
    if (list.size() != vec.size())
        return false;

    auto lbeg = list.begin();
    auto vbeg = vec.begin();
    // 长度相同
    if (list.size() == vec.size())
        while (lbeg != list.end())
            if (*lbeg++ != *vbeg++)
                return false;
    return true;
}

9.17


/**
 * 容器和元素类型要相同
 */

9.18

#include 
#include 
#include 
#include 
#include 
#include 
#include 

using namespace std;

int main()
{
    string str;
    deque<decltype(str)> deq;

    while (cin >> str)
        deq.emplace_back(str);
    
    for (auto beg = deq.begin(); beg != deq.end(); beg++)
        cout << *beg << endl;

    return 0;
}

9.19

#include 
#include 
#include 
#include 
#include 
#include 
#include 

using namespace std;

int main()
{
    string str;
    list<decltype(str)> deq;

    while (cin >> str)
        deq.emplace_back(str);
    
    for (auto beg = deq.begin(); beg != deq.end(); beg++)
        cout << *beg << endl;

    return 0;
}

9.20

#include 
#include 
#include 
#include 
#include 
#include 
#include 

using namespace std;

void copy(const list<int> &list, deque<int> &deqo, deque<int> &deqj);
void print(deque<int> &deq);

int main()
{
    list<int> list{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
    deque<int> deqo, deqj;

    copy(list, deqo, deqj);

    print(deqo);
    print(deqj);

    return 0;
}

void copy(const list<int> &list, deque<int> &deqo, deque<int> &deqj)
{
    // 显式 const
    for (const auto &l : list)
    {
        if (l % 2 == 0)
            deqo.push_back(l);
        else
            deqj.emplace_back(l);
    }
}

void print(deque<int> &deq)
{
    for (auto &i : deq)
        cout << i << ends;
    cout << endl;
}

9.21

#include 
#include 
#include 
#include 
#include 
#include 
#include 

using namespace std;


int main()
{
    vector<string> svec;
    string word;
    auto iter = svec.begin();

    // 头插
    while (cin >> word)
        iter = svec.insert(iter, word);

    for (auto &i : svec)
        cout << i << ends;
    cout << endl;

    return 0;
}

9.22


/**
 * iv.insert(iter++, 2 * some_val);
 */

9.23



/**
 * 四个值 相等
 */

9.24

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

using namespace std;

int main()
{
    vector<int> vec;

    // 程序崩溃
    auto val1 = vec.front();
    puts("1");
    auto &val2 = *vec.begin();
    auto val3 = vec.at(0);
    auto val4 = vec[0];

    printf("=%d= =%d= =%d= =%d=\n",val1, val2, val3, val4);

    return 0;
}

9.25


/**
 * 没有删除元素 返回第一个参数
 * 删除元素后 返回第二个边参数
 * 没有删除元素 返回第一个参数
 */ 

9.26

#include 
#include 
#include 
#define P(a) for(auto &i : a) cout << i << ends; cout << endl;

using namespace std;

int main()
{
    int ia[] = {0, 1, 1, 2, 3, 5, 8, 13, 21, 55, 89};

    vector<int> vec(begin(ia), end(ia));
    list<int> list(begin(ia), end(ia));

    auto it = vec.begin();
    while (it != vec.end())
        if (*it % 2)
            it = vec.erase(it);
        else
            ++it;

    auto il = list.begin();
    while (il != list.end())
        if (*il % 2)
            ++il;
        else
            il = list.erase(il);

    P(ia);
    P(vec);
    P(list);

    return 0;
}

9.27

#include 
#include 
#define P(a) for(auto &i : a) cout << i << ends; cout << endl;

using namespace std;

int main()
{
    forward_list<int> fst{1, 2, 3, 4, 5, 6, 7, 8, 9};

    // 前继
    forward_list<int>::iterator prev = fst.before_begin();
    // 后继
    auto curr = fst.begin();

    while (curr != fst.end())
    {
        if (*curr % 2 != 0)
            curr = fst.erase_after(prev);
        else
        {
            // 下一个
            prev = curr;
            ++curr;
        }
    }

    P(fst);

    return 0;
}

9.28

#include 
#include 
#include 
#define P(a) for(auto &i : a) cout << i << ends; cout << endl;

using namespace std;

forward_list<string>::reference
insert(forward_list<string> &fst, const string &s1, const string &s2);

int main()
{
    forward_list<string> lst{"xiao", "ni", "liong", "hong", "ji"};
    insert(lst, "ni", "lo") = "hhhhhhh";

    P(lst);

    return 0;
}

forward_list<string>::reference
insert(forward_list<string> &fst, const string &s1, const string &s2)
{
    // 记录尾后
    auto bef = fst.before_begin();
    auto beg = fst.begin();

    while (beg != fst.end())
        if (*beg == s1)
        {
            beg = fst.emplace_after(beg, s2);
            return *beg;
        }
        else
        {
            bef = beg;
            ++beg;
        } 

    // 没有找到 在尾后插入
    beg = fst.insert_after(bef, s2);

    return *beg;    
}

9.29


/**
 * 会增加 75 个元素, 进行值初始化, 如果元素为类类型必须提供初始值或默认构造函数
 * 会减少 90 个元素
 */

9.30



/**
 * 类类型必须有默认构造函数
 */

9.31


/**
 * 没有 += 运算符
 */

#include 
#include 
#include 
#define P(a) for(auto &i : a) cout << i << ends; cout << endl;

using namespace std;

#ifdef ONE
int main()
{
    list<int> lst{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
    auto iter = lst.begin();

    while (iter != lst.end())
    {
        if (*iter % 2)
        {
            iter = lst.insert(iter, *iter);
            ++iter;
            ++iter;
        }
        else
        {
            iter = lst.erase(iter);
        }
    }

    P(lst);

    return 0;
}
#else
int main()
{
    forward_list<int> lst{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
    auto feg = lst.before_begin();
    auto iter = lst.begin();

    while (iter != lst.end())
    {
        if (*iter % 2)
        {
            iter = lst.insert_after(iter, *iter);
            ++iter;
            ++feg;
            ++feg;
        }
        else
        {
            iter = lst.erase_after(feg);
        }
    }

    P(lst);

    return 0;
}
#endif

9.32



/**
 * 不合法
 * 函数调用时实参的求值顺序并没有被规定, 也就是说不同编译器下, 产生的运算结果可能不同
 */

9.33

#include 
#include 
#include 
#define P(a) for(auto &i : a) cout << i << ends; cout << endl;

using namespace std;

int main()
{
    // vector v{1, 2, 3};
    list<int> v{1, 2, 3};

    auto begin = v.begin();
    while (begin != v.end())
    {
        ++begin;
        // 插入 begin 前, 返回新元素位置
        // begin = v.insert(begin, 42);

        // 在 begin 前面 插入元素, begin 失效
        v.insert(begin, 42);
        // 下一个元素
        ++begin;
    }

    P(v);
    
    return 0;
}

9.34

#include 
#include 
#define P(a) for(auto &i : a) cout << i << ends; cout << endl;

using namespace std;

int main()
{
    vector<int> vi{1, 2, 3, 4};

    auto iter = vi.begin();
    while (iter != vi.end() && vi.size() != 10)
        if (*iter % 2)
            iter = vi.insert(iter, *iter);

        // 不在块内 死循环
        ++iter;
    P(vi);
}

9.35



/**
 * capacity 返回 可存储容量
 * size 返回 当前存储元素数目
 */

9.36



/**
 * 不可能 capacity >= size
 */

9.37



/**
 * 链表 不需要连续内存
 * 不可变数组 没意义
 */

9.38

#include 
#include 
#include 
#include 
#include 
#include 
#define P(a) for(auto &i : a) cout << i << ends; cout << endl;

using namespace std;

int main()
{
    vector<int> vec;
    /**
     * 分配与size一样的容量
     * 重新分配时 * 2
     */
    vec.emplace_back(1);
    cout << vec.capacity() << ends
         << vec.size()   << endl;

    vec.emplace_back(2);
    cout << vec.capacity() << ends
         << vec.size()   << endl;

    vec.emplace_back(3);
    cout << vec.capacity() << ends
         << vec.size()   << endl;

    return 0;
}

9.39


/**
 * 给空 svec 分配容量
 * 插入数据
 * 改变元素数目
 */

9.40



/**
 * 1024
 * 1024
 * 1024
 * 2048
 */

9.41

#include 
#include 
#include 
#include 
#include 
#include 
#define P(a) for(auto &i : a) cout << i << ends; cout << endl;

using namespace std;

int main()
{
    vector<char> cvec(10, 'a');
    string s1(cvec.begin(), cvec.end());

    cout << s1 << endl;

    return 0;
}

9.42


/**
 * reserve(200);
 */

9.43

#include 
#include 
#include 

using namespace std;

int kmp(const char * str1, const char * str2);
void str(string &s, const string &oldval, const string &newval);

int main()
{
    string s("ling hong shi ni wo er bibi ooo ppppp qaqaq");
    str(s, "shi", "xxxxxxxxx");

    cout << s << endl;

    return 0;
}

void str(string &s, const string &oldval, const string &newval)
{
    int k = kmp(s.c_str(), oldval.c_str());
    if (k == -1)
        return ;
    
    s.replace(k, oldval.size(), newval);
    // s.erase(k, oldval.size());
    // s.insert(k, newval);
}

int kmp(const char * str1, const char * str2)
{
    int len1 = strlen(str1);
    int len2 = strlen(str2);

    int next[len2 + 1], i, j;
    next[0] = -1, i = 0, j = -1;

    while (i < len2)
        if (j == -1 || str2[i] == str2[j])
        {
            i++;
            j++;
            next[i] = j;
        }
        else
            j = next[j];

    i = 0, j = 0;
    while (i < len1 && j < len2)
        if (j == -1 || str1[i] == str2[j])
        {
            i++;
            j++;
        }
        else
            j = next[j];

    if (j == len2)
        return i - len2;
    else
        return -1;
}

9.44

#include 
#include 

using namespace std;

void str(string &s, const string &oldval, const string &newval);

int main()
{
    string s("ling lingc lingcc");
    str(s, "lingcc", "xxxxxxxxx");

    cout << s << endl;

    return 0;
}

void str(string &s, const string &oldval, const string &newval)
{
    auto sbeg = s.begin();
    auto obeg = oldval.begin();

    int a = 0;

    while (sbeg != s.end())
    {
        // 记录
        auto temp = sbeg;
        // 字符相等 且没到结尾
        while (obeg != oldval.end() && sbeg != s.end() && *sbeg == *obeg)
        {
            ++sbeg;
            ++obeg;
        }

        // 字符全部相等
        if (obeg == oldval.end())
        {
            auto k = s.erase(sbeg - oldval.size(), sbeg);
            s.insert(k, newval.begin(), newval.end());
            return ;
        }

        // 重置
        sbeg = temp;
        obeg = oldval.begin();
        // 下一个
        ++sbeg;
    }
}

9.45

#include 
#include 

using namespace std;

string str(const string &s, const string &q, const string &h);

int main()
{
    cout << str("ooo", "zhe", "sha") << endl;

    return 0;
}

string str(const string &s, const string &q, const string &h)
{
    string temp(s);
    temp.insert(0, q);
    temp.append(h);
    
    return temp;
}

9.46

#include 
#include 

using namespace std;

string str(const string &s, const string &q, const string &h);

int main()
{
    cout << str("ooo", "zhe", "sha") << endl;

    return 0;
}

string str(const string &s, const string &q, const string &h)
{
    string temp(s);
    temp.insert(0, q);
    temp.insert(temp.size(), h);
    
    return temp;
}

9.47

#include 
#include 

using namespace std;

int main()
{
    string s("ab2c3d7R4E6");
    string number("0123456789");

    decltype(s.size()) pos = 0;
    while ((pos = s.find_first_of(number, pos)) != string::npos)
        cout << s[pos++] << ends;
    putchar('\n');

    pos = 0;
    while ((pos = s.find_first_not_of(number, pos)) != string::npos)
        cout << s[pos++] << ends;
    putchar('\n');

    return 0;
}

9.48


/**
 * string::npos
 * (unsigned long long) -1
 */

9.49

#include 
#include 
#include 

using namespace std;

int main(int argc, char **argv)
{
    if (argc != 2)
    {
        puts("请输入文件");
        exit(EXIT_FAILURE);
    }
    
    // 打开文件
    ifstream infile(argv[1]);

    if (!infile)
    {
        puts("文件打开失败");
        exit(1);
    }

    string ex("dfpg");
    string word;
    string maxword;

    while (infile >> word)
    {
        if (word.find_first_of(ex) == string::npos && word.size() > maxword.size())
            maxword.assign(word);
    }

    cout << maxword << endl;

    return 0;
}

9.50

#include 
#include 
#include 

using namespace std;

#ifdef I
int main()
{
    vector<string> svec;
    string str;

    while (cin >> str)
        svec.emplace_back(str);

    int sum = 0;    
    for (auto &i : svec)
        sum += stoi(i);
    
    cout << sum << endl;

    return 0;
}
#else
int main()
{
    vector<string> svec;
    string str;

    while (cin >> str)
        svec.emplace_back(str);

    double sum = 0;    
    for (auto &i : svec)
        sum += stod(i);
    
    cout << sum << endl;

    return 0;
}
#endif

9.51

#include 
#include 

class Date {
friend std::ostream &operator<<(std::ostream &os, const Date &item);
public:
    typedef unsigned type;
    Date() = default;
    Date(const std::string &s);
private:
    type year = 0;
    type month = 0;
    type day = 0;
};

Date::Date(const std::string &s)
{                                                 // sept
    std::string mon{" Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec"};

    std::string number("0123456789");

    // 没有英文
    if (s.find_first_of(mon) == std::string::npos)
    {
        decltype(s.size()) pos = 0;
        // 查找第一个并更新 pos, 返回 s 从 pos 开始的字符串, 转换成 int
        month = std::stoi(s.substr(pos = s.find_first_of(number, pos)));
        ++pos;

        day = std::stoi(s.substr(pos = s.find_first_of(number, pos)));
        ++pos;

        year = std::stoi(s.substr(pos = s.find_first_of(number, pos)));
    }
    else // 有英文
    {
        decltype(s.size()) pos = 0;
        // 查找 s 前三个字母
        month = (mon.find(s.c_str(), 0, 3) + 3) / 4;

        day = std::stoi(s.substr(pos = s.find_first_of(number, pos)));
        ++pos;

        year = std::stoi(s.substr(pos = s.find_first_of(number, pos)));
    }
}

std::ostream &operator<<(std::ostream &os, const Date &item)
{
    os << item.year << "/"
       << item.month << "/"
       << item.day;
       
    return os;
}

9.52

#include 
#include 
#include 
#include 
#include 
#include 
#include 

using namespace std;

typedef signed long long lld;
// 运算符
vector<char> oper{'+', '-', '*', '/', '%', '(', ')', '#', '^'};
// 优先级
vector<vector<char>> priority
{
    // < 入栈,  > 出栈
 //    symobl.top()
 //   +    -    *    /    %    (    )    #    ^
    {'>', '>', '<', '<', '<', '<', '>', '>', '>'},  // +

    {'>', '>', '<', '<', '<', '<', '>', '>', '>'},  // -

    {'>', '>', '>', '>', '>', '<', '>', '>', '>'},  // *

    {'>', '>', '>', '>', '>', '<', '>', '>', '>'},  // /
    
    {'>', '>', '>', '>', '>', '<', '>', '>', '>'},  // %

    {'<', '<', '<', '<', '<', '<', '=', ' ', '<'},  // (

    {'>', '>', '>', '>', '>', ' ', '>', '>', '>'},  // )

    {'<', '<', '<', '<', '<', '<', ' ', '=', '<'},  // #

    {'>', '>', '>', '>', '>', '<', '>', '>', '>'}   // ^   s.top()
};

// 判断符号
bool isoper(char c, const vector<char>&);
// 运算
lld operat(lld a, char x, lld b);
// 返回 运算符 下标
lld getindex(char, vector<char>&);
// 获取优先级
char getpr(char, char);
// 计算
lld jisuan(string s);

int main()
{
    string line;

    while (getline(cin, line))
    {
        cout << line << " = " << jisuan(line) << endl;
    }

    return 0;
}

lld jisuan(string s)
{
    // 对象
    stack<lld> object;
    // 符号
    stack<char> symbol;

    // 计算用
    int a, b;
    char x;
    
    // 结束符
    symbol.push('#');
    s.append("#");

    // 下标
    decltype(s.size()) i = 0;
    while (s[i] != '#' || symbol.top() != '#')
    {
        // 消除空白
        while (isspace(s[i]))
            ++i;
        // 是数字
        if (isdigit(s[i]))
        {
            // 压入 对象
            object.push(stoll(s.substr(i)));
            // 直到不是数字
            while (isdigit(s[i]))
                ++i;
        }
        else if(isoper(s[i], oper))
        {
            // 获取 优先级
            switch(getpr(symbol.top(), s[i]))
            {
                case '<':  // 压入
                        symbol.push(s[i]);
                        ++i;
                        break;
                case '=':  // 弹出
                        symbol.pop();
                        ++i;
                        break;
                case '>': 
                        // 弹出两个对象 和 一个 运算符
                        a = object.top();
                        object.pop();
                        b = object.top();
                        object.pop();
                        x = symbol.top();
                        symbol.pop();

                        // 压入计算结果
                        object.push(operat(b, x, a));
                        break;
                default :
                        cerr << "输入有误!!!" << endl;
                        return -1;
            }
        }
        else
        {
            cerr << "输入有误!!!" << endl;
            return -1;
        }

    }

    return object.top();
}

lld getindex(char top, vector<char> &oper)
{
    for (decltype(oper.size()) i = 0; i != oper.size(); ++i)
    {
        if (top == oper[i])
            return i;
    }

    return 0;
}

lld operat(lld a, char x, lld b)
{
    switch (x)
    {
        case '+': return a + b;
        case '-': return a - b;
        case '*': return a * b;
        case '/': return a / b;
        case '%': return a % b;
        case '^': return pow(a, b); // math
    }
    return 0;
}

char getpr(char objecttop, char stop)
{
    return priority[getindex(objecttop, oper)] [ getindex(stop, oper)];
}

bool isoper(char c, const vector<char> &vec)
{
    for (auto &i : vec)
    {
        if (c == i)
            return true;
    }
    return false;
}

你可能感兴趣的:(C++,Primer(第五版),c++)