C++ Primer第5版 第九章課后練習答案


練習9.1

(a)list更合適,因為按照字典序插入到容器中代表需要在容器中間插入元素

(b)deque更合適,因為deque支持雙端插入和刪除

(c)無具體的插入刪除操作,讀取整數數量也是未知,可以選擇vector

 

練習9.2

int main(int argc, char* argv[])
{
    std::list<std::deque<int>> lq;
}

 

練習9.3

指向同一個容器的元素,或者尾后迭代器

end不在begin之前

 

練習9.4

bool find(vector<int>::const_iterator& begin, vector<int>::const_iterator& end, int i) {
    while (begin != end) {
        if (*begin == i)return true;
    }
    return false;
}

 

練習9.5

vector<int>::const_iterator& find(vector<int>::const_iterator& begin, vector<int>::const_iterator& end, int i) {
    while (begin != end) {
        if (*begin == i)return begin;
    }
    std::cerr << "don't find the num in the arrange";
    return end;
}

 

練習9.6

 在C++定義的容器類型中,只有vector和queue容器提供迭代器算數運算和除!=和==之外的關系運算

 

練習9.7

vector<int>::size_type

 

練習9.8

讀取

list<string>::iterator||list<string>::const_iterator

寫入

list<string>::iterator

 

練習9.9

cbegin返回的是const迭代器對象,begin不是

 

練習9.10

it1:vector<int>::iterator

it2:const vector<int>::iteratorit3:vector<int>::const_iterator

it4:const vector<int>::const_iterator

 

練習9.11 

vector<int> v1;//
vector<int> v2(v1);//v1的拷貝
vector<int> v3{ 0,1,2,3 };//初始化為初始化列表的拷貝
vector<int> v4(v3.begin(), v3.end());//初始化為迭代器之間元素的拷貝
vector<int> v5(10);//包含10個元素,每一個都被值初始化為0
vector<int> v6(10, 5);//包含10個元素,每個都初始化為5

 

練習9.12

接受一個容器創建其拷貝的構造函數:要求具有相同的容器類型,保存的是相同的元素類型

接受兩個迭代器創建拷貝的構造函數:只要求迭代器范圍內的元素類型相同

 

練習9.13

int main(int argc, char* argv[])
{
    list<int> li{ 0,1,2,3 };
    vector<double> vd(li.begin(), li.end());
    for (auto i : vd)
        cout << i << " ";
    cout << endl;
    vector<int> vi{ 0,1,2,3 };
    vector<double> vd2(vi.begin(), vi.end());
    for (auto i : vd2)
        cout << i << " ";
}

 

練習9.14

int main(int argc, char* argv[])
{
    list<const char*> lc;
    vector<string> vs;
    vs.assign(lc.begin(), lc.end());
}

 

練習9.15

template<typename T>
bool check(const vector<T>& v1, const vector<T>& v2) {
    return v1 == v2;
}

int main(int argc, char* argv[])
{
    vector<string> vs1{ "012" };
    vector<string> vs2{ "012","123" };
    cout << (check(vs1, vs2) ? "相等" : "不相等");
}

 

練習9.16

template<typename T>
bool check(const list<T>& v1, const vector<T>& v2) {
    if (v1.size() == v2.size()) {
        auto j = v2.begin();
        for (auto i = v1.begin(); i !=v1.end() ; i++,j++) {
            if (*i != *j)return false;
        }
        return true;
    }
    return false;
}

int main(int argc, char* argv[])
{
    list<string> vs1{ "012" };
    vector<string> vs2{ "012","123" };
    cout << (check(vs1, vs2) ? "相等" : "不相等");
}

 

練習9.17

要求不是無序關聯容器,c1和c2必須是相同類型的容器,且必須保存相同類型的元素

 

練習9.18

int main(int argc, char* argv[])
{
    std::deque<string> ds;
    string s;
    while (cin >> s) {
        ds.emplace_back(s);
        s.clear();
    }
    for (auto it = ds.begin(); it != ds.end(); it++) {
        cout << *it << endl;
    }
}

 

練習9.19

int main(int argc, char* argv[])
{
    list<string> ls;
    string s;
    while (cin >> s) {
        ls.emplace_back(s);
        s.clear();
    }
    for (auto it = ls.begin(); it != ls.end(); it++) {
        cout << *it << endl;
    }
}

 

練習9.20

int main(int argc, char* argv[])
{
    list<int> li;
    int i;
    deque<int> di1, di2;
    while (cin >> i) {
        li.emplace_back(i);
    }
    for (auto it = li.begin(); it != li.end(); it++) {
        if ((*it) % 2)di1.emplace_back(*it);
        else di2.emplace_back(*it);
    }
}

 

練習9.21

int main(int argc, char* argv[])
{
    vector<string> vst;
    string word;

    auto iter = vst.begin();
    while (cin >> word) {
        iter = vst.insert(iter, word);
    }
}

將iter初始化為vst.begin(),第一次調用insert會將我們剛剛讀入的string插入到iter所指向的元素之前的位置。

 

練習9.22

int main(int argc, char* argv[])
{
    vector<int> iv{ 0,1,2,3,4,5 };
    vector<int>::iterator iter = iv.begin(), mid = iv.begin() + iv.size() / 2;
    int some_val = 0;
    while (iter!=mid)
    {
        if (*iter == some_val)
            iv.insert(iter, 2 * some_val);
    }
}

該程序會在滿足程序的情況下在vector開頭插入元素,導致迭代器失效,應更新循環中的迭代器,並保證迭代器不會陷入無限循環

int main(int argc, char* argv[])
{
    vector<int> iv{ 0,1,2,3,4,5 };
    vector<int>::iterator iter = iv.begin(), mid = iv.begin() + iv.size() / 2;
    int some_val = 0;
    while (iter!=mid)
    {
        if (*iter == some_val) {
            iter = iv.insert(iter, 2 * some_val);
            iter += 2;
        }        
        else
            iter++;
        mid = iv.begin() + iv.size() / 2;
    }
}

 

練習9.23

val,val2,val3和val4的值都相同

 

練習9.24

at:有未經處理的異常: Microsoft C++ 異常: std::out_of_range

下標運算符:vector subscript out of range

front:front() called on empty vector

begin:cant't dereference value-initialized vector iterator

 

練習9.25

elem1與elem2相等不會刪除容器元素,如果elem2時尾后迭代器會刪除所有elem1到elem2的所有元素(不包括elem2),如果elem1和elem2皆為尾后迭代器則不會刪除元素

 

練習9.26

int main(int argc, char* argv[])
{
    int ia[] = { 0 ,1,1,2,3,5,8,13,21,55,89 };
    vector<int> iv;
    iv.assign(ia, ia + sizeof(ia) / sizeof(int));
    auto it = iv.begin();
    while (it!=iv.end())
    {
        if (!(*it % 2))
            it = iv.erase(it);
        else it++;
    }


    list<int> il;
    il.assign(ia, ia + sizeof(ia) / sizeof(int));
    auto it2 = il.begin();
    while (it2 != il.end())
    {
        if (*it2 % 2)
            it2 = il.erase(it2);
        else it2++;
    } 
}

 

練習9.27

int main(int argc, char* argv[])
{
    forward_list<int> flst = { 0,1,2,3,4,5,6,7,8,9 };
    auto prev = flst.before_begin(), curr = flst.begin();
    while (curr != flst.end()) {
        if (*curr % 2) {
            curr = flst.erase_after(prev);
        }
        else {
            prev = curr;
            curr++;
        }        
    }
}

 

練習9.28

void fl_find_insert(forward_list<string>& flst, string& s1, string& s2) {
    auto prev = flst.before_begin(), curr = flst.begin();
    while (curr != flst.end()) {
        if (*curr == s1) {
            flst.insert_after(prev, s2);
            return;
        }
        else {
            prev = curr;
            ++curr;
        }
    }
    flst.insert_after(prev, s2);
}

 

練習9.29

vec.resize(100):調整vec大小為100,由於vec原來包含25個元素,將75個值為0的元素添加到vec末尾

vec.resize(10):調整vec大小為10,由於vec原來包含25個元素,將vec末尾15個元素刪除

 

練習9.30

元素必須能進行值初始化,若為類類型元素則必須提供默認值或者默認構造函數

 

練習9.31

list迭代器沒有遞增遞減的操作,需要修改為advance(iter, 2);

forward_list沒有insert和erase操作需要修改

 

練習9.32

 不合法,++遞增符改變了iter的值,將產生未定義的行為。因為賦值運算符左右兩端的運算對象都用到了iter,並且右側的運算對象還改變了iter的值

 

練習9.33

迭代器失效

 

練習9.34

遍歷容器,查找所有為奇數的元素並復制該元素插入到容器中,但因為只遞增了一次導致程序只會卡在第一次找到奇數的時候

 

練習9.35

容器的size是指它已經保存的元素的數目

容器的capacity是在不分配新的內存空間的前提下他最多能保存多少元素

 

練習9.36

不可能,因為size必然小於等於capacity

 

練習9.37

list沒有capacity是因為不要求空間是連續的

array沒有capacity是因為array不允許修改空間大小

 

練習9.38

int main(int argc, char* argv[])
{
    vector<int> vec1;
    int a;
    while (cin >> a)
    {
        vec1.push_back(a);
        cout << "vector的大小" << vec1.size() << endl;;
        cout << "vector的容量" << vec1.capacity() << endl;
    }

}

 

 

練習9.39

為vector分配1024個string元素的內存,傳入值,然后插入容器一半數量的空string元素

 

練習9.40

256:1024

512:1024

1000:1536

1024:2304

 

練習9.41

int main(int argc, char* argv[])
{
    vector<char>cvec(10, 'c');
    char *charray=new char[cvec.size()];
    memcpy(charray, &cvec[0], cvec.size() * sizeof(char));
    string s(charray);
}

 

練習9.42

int main(int argc, char* argv[])
{
    string s;
    s.reserve(100);
    char c;
    while (cin >> c) {
        s.push_back(c);
    }
}

 

練習9.43

void str_find_replace(string& s, string& oldVal, string& newVal) {
    auto it1 = s.begin(), it2 = newVal.begin(), it3 = newVal.end();
    for (; it1 != s.end() - oldVal.size(); it1++) {
        if (s.substr(it1 - s.begin(), oldVal.size()) == oldVal) {
            s.erase(it1 - s.begin(), oldVal.size());
            it1 = s.insert(it1, newVal.begin(), newVal.end());
            it1 += newVal.size();
        }
    }
}

 

練習9.44

void str_find_replace(string& s, string& oldVal, string& newVal) {
    auto it1 = s.begin(), it2 = newVal.begin(), it3 = newVal.end();
    for (; it1 != s.end() - oldVal.size(); it1++) {
        if (s.substr(it1 - s.begin(), oldVal.size()) == oldVal) {
            s.replace(it1, it1 + oldVal.size(), newVal);
            it1 += newVal.size();
        }
    }
}

 

練習9.45

void str_find_add(string& s, string& prev, string& last) {
    s.insert(0, prev);
    s.append(last);
}

 

練習9.46

void str_find_add(string& s, string& prev, string& last) {
    s.insert(0, prev);
    s.insert(s.size(), last);
}

 

練習9.47

只用find_first_of的

int main(int argc, char* argv[])
{
    string s = "ab2c3d7R4E6";
    string numbers("0123456789");
    auto pos = 0;
    while ((pos = s.find_first_of(numbers, pos)) != string::npos) {
        cout << s[pos++];
    }
    auto pos1 = 0, pos2 = 0;
    while ((pos2 = s.find_first_of(numbers, pos1)) != string::npos) {
        for (; pos1 != pos2; ++pos1)
            cout << s[pos1];
        ++pos1;
    }
    if (pos1 != s.find_last_not_of(numbers))cout << s[pos1];
    return 0;
}

 

只用find_first_not_of的

int main(int argc, char* argv[])
{
    string s = "ab2c3d7R4E6";
    string numbers("0123456789");
    auto pos1 = 0, pos2 = 0;
    while ((pos2 = s.find_first_not_of(numbers, pos1)) != string::npos) {
        for (; pos1 != pos2; ++pos1)
            cout << s[pos1];
        ++pos1;
    }
    if (pos1 != s.find_last_not_of(numbers))cout << s[pos1];
    auto pos = 0;
    while ((pos = s.find_first_not_of(numbers, pos)) != string::npos){
        cout << s[pos++];
    } 
    return 0;
}

 

練習9.48

string::npos

 

練習9.49

int main(int argc, char* argv[])
{
    string ascender("bdfhklt"); //上出頭部分單詞
    string descender("gjpqy");  //下出頭部分單詞
    std::ifstream ifs(argv[1]);
    string s,  maxs;
    auto max = 0;
    string::size_type pos;
    if (ifs)
    {
        while (!ifs.eof())
        {
            ifs >> s;
            if (s.find_first_of(ascender) == string::npos && s.find_first_of(descender) == string::npos&&s.size()>max) {
                max = s.size();
                maxs = s;
            }
            s.clear();
        }
    }
    return 0;
}

 

練習9.50

計算整型值的string之和

int main(int argc, char* argv[])
{
    vector<string> strvec;
    long long ll = 0;
    for (const auto& it : strvec) {
        ll += stoll(it);
    }
    cout << ll << endl;
    return 0;
}

計算浮點值的string之和

int main(int argc, char* argv[])
{
    vector<string> strvec;
    long double ld = 0;
    for (const auto& it : strvec) {
        ld += stold(it);
    }
    cout << ld << endl;
    return 0;
}

 

練習9.51

#ifndef DATE_H_
#define DATE_H_
#include<string>
using std::string;
class Date
{
public:
    Date(string&);
    ~Date();

private:
    unsigned year;
    unsigned month;
    unsigned day;
    void str_to_month(string &str,string::size_type& pos);
};

Date::Date(string &s)
{
    string::size_type pos1, pos2;
    if (pos1 = s.find_first_of(",/") == string::npos) {
        pos1 = s.find_first_of(" ");
        pos2 = s.find_last_of(" ");
        str_to_month(s, pos1);
        day = stoul(s.substr(pos1 + 1, pos2));
        year = stoul(s.substr(pos2 + 1, s.size()));
    }
    else if (pos1 = s.find_first_of(",") == string::npos) {
        pos1 = s.find_first_of("/");
        pos2 = s.find_last_of("/");
        str_to_month(s, pos1);
        day = stoul(s.substr(pos1 + 1, pos2));
        year = stoul(s.substr(pos2 + 1, s.size()));
    }
    else if (pos1 = s.find_first_of("/") == string::npos) {
        pos1 = s.find_first_of(" ");
        pos2 = s.find_last_of(",");
        str_to_month(s, pos1);
        day = stoul(s.substr(pos1 + 1, pos2));
        year = stoul(s.substr(pos2 + 1, s.size()));
    }
}

Date::~Date()
{
}

inline void Date::str_to_month(string& s, string::size_type& pos1)
{
    if (s.substr(0, pos1) == "Jan" || s.substr(0, pos1) == "January") {
        month = 1;
    }
    else if (s.substr(0, pos1) == "Feb" || s.substr(0, pos1) == "February") {
        month = 2;
    }
    else if (s.substr(0, pos1) == "Mar" || s.substr(0, pos1) == "March") {
        month = 3;
    }
    else if (s.substr(0, pos1) == "Apr" || s.substr(0, pos1) == "April") {
        month = 4;
    }
    else if (s.substr(0, pos1) == "May" || s.substr(0, pos1) == "May") {
        month = 5;
    }
    else if (s.substr(0, pos1) == "Jun" || s.substr(0, pos1) == "June") {
        month = 6;
    }
    else if (s.substr(0, pos1) == "Jul" || s.substr(0, pos1) == "July") {
        month = 7;
    }
    else if (s.substr(0, pos1) == "Aug" || s.substr(0, pos1) == "August") {
        month = 8;
    }
    else if (s.substr(0, pos1) == "Sept" || s.substr(0, pos1) == "September") {
        month = 9;
    }
    else if (s.substr(0, pos1) == "Oct" || s.substr(0, pos1) == "October") {
        month = 10;
    }
    else if (s.substr(0, pos1) == "Nov" || s.substr(0, pos1) == "November") {
        month = 11;
    }
    else if (s.substr(0, pos1) == "Dec" || s.substr(0, pos1) == "December") {
        month = 12;
    }
    else {
        month = stoul(s.substr(0, pos1));
    }
}
#endif // !DATE_H_

 

練習9.52

unsigned get_operator_level(const char& c) {
    if (c == ')')return 4;
    else if (c == '*' || c == '/')return 3;
    else if (c == '+' || c == '-')return 2;
    else return 1;
}

int main(int argc, char* argv[])
{
    string s("(11+21)*13-(62+21)/53");
    string ns;
    stack<char> chars;
    stack<long> numbers;
    bool other = true;
    for (const auto&c:s) {
        if (isdigit(c)) {
            ns.insert(ns.end(), c);
        }
        else if(chars.empty()||c=='('){
            chars.push(c);
        }
        else if (c != ')') {
            while (!chars.empty() && get_operator_level(chars.top()) >= get_operator_level(c)) {
                ns.insert(ns.end(), chars.top());
                chars.pop();
            }
            chars.push(c);
            ns.insert(ns.end(), ' ');
        }
        else {
            while (chars.top() != '(') {
                ns.insert(ns.end(), chars.top());
                chars.pop();
            }
            chars.pop();
        }   
    }
    while (!chars.empty()) {
        ns.insert(ns.end(), chars.top());
        chars.pop();
    }
    for (const auto& c : ns) {
        if (isdigit(c) && other) {
            long num = 0;
            if (!numbers.empty()) {
                num = numbers.top();
                numbers.pop();
            }          
            num = num * 10 + c - '0';
            numbers.push(num);
        }
        else if (isdigit(c)) {
            numbers.push(c - '0');
            other = true;
        }
        else if (isspace(c)) {
            other = false;
        }
        else {
            long num1, num2;
            num2 = numbers.top();
            numbers.pop();
            num1 = numbers.top();
            numbers.pop();
            if (c == '+')numbers.push(num1 + num2);
            else if (c == '-')numbers.push(num1 - num2);
            else if (c == '*')numbers.push(num1 * num2);
            else if (c == '/')numbers.push(num1 / num2);
            other = false;
        }
    }
    return 0;
}
unsigned get_operator_level(const char& c) {
    if (c == ')')return 4;
    else if (c == '*' || c == '/')return 3;
    else if (c == '+' || c == '-')return 2;
    else return 1;
}

int main(int argc, char* argv[])
{
    string s("(11+21)*13-(62+21)/53");
    string ns;
    stack<char> chars;
    stack<long> numbers;
    bool other = true;
    for (const auto&c:s) {
        if (isdigit(c)) {
            ns.insert(ns.end(), c);
        }
        else if(chars.empty()||c=='('){
            chars.push(c);
        }
        else if (c != ')') {
            while (!chars.empty() && get_operator_level(chars.top()) >= get_operator_level(c)) {
                ns.insert(ns.end(), chars.top());
                chars.pop();
            }
            chars.push(c);
            ns.insert(ns.end(), ' ');
        }
        else {
            while (chars.top() != '(') {
                ns.insert(ns.end(), chars.top());
                chars.pop();
            }
            chars.pop();
        }   
    }
    while (!chars.empty()) {
        ns.insert(ns.end(), chars.top());
        chars.pop();
    }
    for (const auto& c : ns) {
        if (isdigit(c) && other) {
            long num = 0;
            if (!numbers.empty()) {
                num = numbers.top();
                numbers.pop();
            }          
            num = num * 10 + c - '0';
            numbers.push(num);
        }
        else if (isdigit(c)) {
            numbers.push(c - '0');
            other = true;
        }
        else if (isspace(c)) {
            other = false;
        }
        else {
            long num1, num2;
            num2 = numbers.top();
            numbers.pop();
            num1 = numbers.top();
            numbers.pop();
            if (c == '+')numbers.push(num1 + num2);
            else if (c == '-')numbers.push(num1 - num2);
            else if (c == '*')numbers.push(num1 * num2);
            else if (c == '/')numbers.push(num1 / num2);
            other = false;
        }
    }
    return 0;
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM