1. 程式人生 > >C++ Primer(第五版)課後習題記錄 —— 第三章

C++ Primer(第五版)課後習題記錄 —— 第三章

第三章 字串、向量和陣列

練習3.2

利用 getline() 函式可以實現讀入一整行,而直接用 cin 輸入則只能讀取一個詞。

#include <iostream>
#include <string>
using namespace std;
//讀入一整行
int main()
{
    string str;
    while (getline(cin ,str))
        cout << str << endl;
    return 0;
}
#include <iostream>
#include <string>
using namespace std; //讀入一個詞 int main() { string str; while (cin >> str) cout << str << endl; return 0; }

練習3.3

string 類輸入運算子會首先忽略掉開頭的空格符(也包括換行符,製表符等),並從第一個真正的字元開始讀起,直到遇到下一個空白處為止。
getline 函式則會儲存字串中的空白字元,會在換行符處終止。

練習3.4

比較大小:

#include <iostream>
#include <string>
using namespace std; int main() { string s1,s2,sout; getline(cin ,s1); getline(cin ,s2); if (s1 == s2) cout << " Bingo! " <<endl; else { sout = s1 > s2? s1 : s2; cout << sout << endl; } return 0; }

比較長度:

#include <iostream>
#include <string> using namespace std; int main() { string s1,s2,sout; getline(cin ,s1); getline(cin ,s2); if (s1.size() == s2.size()) cout << " Bingo! " <<endl; else { sout = s1.size() > s2.size()? s1 : s2; cout << sout << endl; } return 0; }

練習3.5

簡單的加法

#include <iostream>
#include <string>
using namespace std;
int main()
{
    string sout,sin;
    while (cin >> sin)
        sout += sin;
    cout << sout << endl;
    return 0;
}
#include <iostream>
#include <string>
using namespace std;
int main()
{
    string sout,sin;
    cin >> sout;
    while (cin >> sin){
        sout = sout + sin + ' ';
    }
    cout << sout << endl;
    return 0;
}

練習 3.6

//使用新的for 迴圈;
#include <iostream>
#include <string>
using namespace std;
int main()
{
    string sout,sin;
    getline(cin ,sin);
    for(auto &c : sin)
        c = 'X';
    cout << sin << endl;
    return 0;
}

練習3.7

不會出現問題,每個字元單獨拿出時都是作為字元型來操作的。

練習3.9

不合法,s 未經初始化,預設為空字串。

練習3.10

//利用 ispunct 函式來判別符號。
#include <iostream>
#include <string>
using namespace std;
int main()
{
    string s;
    getline(cin ,s);
    for (auto c : s)
        if (!ispunct(c))
            cout << c;
    cout << endl;
    return 0;
}

練習3.11

for 語句合法。c 的型別是對常量的引用。

練習3.12

(a) 正確, Ivec 為存放 vector 的 vector;
(b) 錯誤,型別不一樣;
(c) 正確,svec 中包含10個 “null” 字串。

練習3.13

(a) vector<int> v1; v1是一個空的vector,其潛在資料型別為 int;
(b) vector<int> v2(10); v2包含了10個被初始化為0的元素;
(c) vector<int> v3(10, 42); v3包含了10個被初始化為42的元素;
(d) vector<int> v4{10}; v4包含了一個值為10的元素;
(e) vector<int> v5{10, 42}; v5包含了被初始化為10和42的兩個元素;
(f) vector<string> v6{10}; v6包含了10個空字串;\
(g) vector<string> v7{10, "hi"}; v7包含了10個被初始化為 “hi” 的字串。

練習3.14/3.15

#include <iostream>
#include <string>
#include <vector>
using namespace std;
int main()
{
    vector<int> n;
    int pend;
    while(cin >> pend)
        n.push_back(pend);
    return 0;
}

字串就不寫了。

練習3.16

#include <iostream>
#include <string>
#include <vector>
using namespace std;
int main()
{
    vector<int> v1;
    vector<int> v2(10);
    vector<int> v3(10, 42);
    vector<int> v4{10};
    vector<int> v5{10, 42};
    vector<string> v6{10};
    vector<string> v7{10, "hi"};
    for (auto c : v1)
        cout << c << ' ';
    cout << endl;
    for (auto c : v2)
        cout << c << ' ';
    cout << endl;
    for (auto c : v3)
        cout << c << ' ';
    cout << endl;
    for (auto c : v4)
        cout << c << ' ';
    cout << endl;
    for (auto c : v5)
        cout << c << ' ';
    cout << endl;
    for (auto c : v6)
        cout << c << ' ';
    cout << endl;
    for (auto c : v7)
        cout << c << ' ';
    cout << endl;
    return 0;
}

正確。

練習3.17

#include <iostream>
#include <string>
#include <vector>
using namespace std;
int main()
{
    string sin;
    vector<string> strs;
    while (cin >> sin)
        strs.push_back(sin);
    for (auto &temp : strs){
        for (auto &t : temp){
            t = toupper(t);
            cout << t << endl;
        }
    }
}

練習3.18

不合法;
將第一句改為 `vector ivec(1); 使 ivec 中初始包含一個元素。

練習3.19

(a) vector<int> a(10,42);
(b) vector<int> b{42,42,42,42,42,42,42,42,42,42};
(c) vector<int> a = b;

練習3.20

//輸出相鄰和。
#include <iostream>
#include <string>
#include <vector>
using namespace std;
int main()
{
    int in, pre;
    vector<int> con;
    while (cin >> in)
        con.push_back(in);
    for (auto c : con){
        if (c == con[0])
            pre = c;
        else {
            cout << c+pre << endl;
            pre = c;
        }
    }
}
//首尾和。
#include <iostream>
#include <string>
#include <vector>
using namespace std;
int main()
{
    int in, pre;
    vector<int> con;
    while (cin >> in)
        con.push_back(in);
    for (decltype(con.size()) ix = 0; ix <=con.size()/2; ix++){
        if (ix != con.size()-1-ix)
            cout << con[ix]+con[con.size()-1-ix] << endl;
        else
            cout << con[ix] << endl;
    }
    return 0;
}

練習3.21

把原始碼中範圍 for 迴圈改為

for (auto c = v1.begin(); c != v1.end(); ++c)

    cout << *c << ' ' ;

練習3.22

要改成大寫形式,則在定義迭代器使不能使用 cbegin() 。

#include <iostream>
#include <string>
#include <vector>
using namespace std;
int main()
{
    vector<string> text;
    string in;
    while(getline(cin ,in))
        text.push_back(in);
    for (auto it = text.begin(); it != text.end() && !it->empty(); ++it){
        for (auto &c : *it)
            c = toupper(c);
        cout << * it << endl;
    }
    return 0;
}

練習3.23

#include <iostream>
#include <string>
#include <vector>
using namespace std;
int main()
{
    vector<int> num{1, 2, 3, 4, 5, 6, 7, 8, 9, 33};
    for (auto c = num.begin(); c != num.end(); ++c){
        *c *= 2;
        cout << * c << endl;
    }

    return 0;
}

練習3.24

#include <iostream>
#include <string>
#include <vector>
using namespace std;
int main()
{
    vector<int> num;
    int in;
    while (cin >> in)
        num.push_back(in);
    cout << "相鄰元素之和:" << endl;
    for(auto c = num.begin(); c != num.end()-1; ++c)
        cout << * c + * (c + 1) << ' ';
    cout << endl;
    cout << "頭尾相加:" << endl;
    for (auto c = num.begin(), b = num.end() - 1; c <= b; ++c, --b){
        if (c == b)
            cout << * c;
        else
            cout << * c + * b << ' ';
    }
    cout << endl;
    return 0;
}

練習3.25

#include <iostream>
#include <string>
#include <vector>
using namespace std;
int main()
{
    vector<unsigned> score(11,0);
    unsigned grade;
    auto it = score.begin();
    while (cin >> grade){
        if (grade <=100)
            ++ * (it+grade/10);
    }
    cout << "各分數段人數:" << endl;
    for ( auto c : score)
        cout << c << endl;
    return 0;
}

練習3.26

beg 和 end 分別是兩個迭代器啊,不存在兩個迭代器相加這樣的運算啊。

練習3.27

d 的定義是非法的,因為作為字元陣列,沒有給空字元留下空間。
c 的定義有隱患,若 txt_size 是 constexpr 時正確。

練習3.28

sa 陣列為空。
ia 陣列含有10個被初始化為0的整數。
sa2 陣列為空。
ia2 陣列含有10個未被定義的整數。

練習3.29

陣列在定義時需要確定其確切個數,並且在之後不能自由地新增元素。

練習3.30

索引中下標範圍應該為 0 ~ array_size-1 。

練習3.31

#include <iostream>
#include <string>
#include <vector>
using namespace std;
int main(){
    constexpr size_t array_size = 10;
    int ia[array_size];
    for (size_t ix; ix < array_size; ++ix)
        ia[ix] = ix;
    return 0;
}

練習3.32

#include <iostream>
#include <string>
#include <vector>
using namespace std;
int main(){
    constexpr size_t array_size = 10;
    vector<int> ia(array_size);
    for (size_t ix=0; ix < array_size; ix++)
        ia[ix] = ix;
    vector<int> iaa = ia;
    for (auto c : iaa)
        cout << c << endl;
    return 0;
}

練習3.33

不初始化 scores 的話, scores 數組裡的值就是未定義的,不能達到從0開始計數的效果。

練習3.34

功能是讓 p1 指標指向 p2 目前所指向的位置。
在 p1 指標是尾後指標時非法。

練習3.35

#include <iostream>
#include <string>
#include <vector>
using namespace std;
int main(){
    constexpr size_t array_size = 10;
    int ia[array_size] = {1,2,3,4,5,6,7,8,9,0};
    int * p = ia;
    while (p != end(ia))
        * (p++) = 0;
    for (auto c : ia)
        cout << c << endl;
    return 0;
}

練習3.36

vector 物件之間可以直接用 == 比較。陣列之間則不能直接比較,需要線比較大小,再逐個元素比較。

練習 3.37

程式實現逐個輸出 ca 中元素的功能;
結果為:

h
e
l
l
o
                            (最後還有一行)

練習3.38

兩個指標直接相加得到的是兩指標地址之和,指向另一個無關的地址,所以沒什麼意義。

練習 3.39

#include <iostream>
#include <string>
#include <vector>
#include <cstring>
using namespace std;
int main(){

    char ia[] = "sup";
    char iaa[] = "suP";
    if (strcmp(ia,iaa) > 0)
        cout << "ia da" << endl;
        else if (strcmp(ia,iaa) < 0)
            cout << "iaa da" << endl;
            else
                cout << "dou da" << endl;
    string ai("sup");
    string aii("suP");
    if (ai > aii)
        cout << "ai da";
        else if (ai < aii)
            cout << "aii da";
        else
            cout << "dou da";
    return 0;
}

練習3.40

#include <iostream>
#include <string>
#include <vector>
#include <cstring>
using namespace std;
int main(){

    char ia[] = "sup";
    char iaa[] = "suP";
    char iaaa[7];
    strcpy(iaaa, ia);
    strcat(iaaa, iaa);
    cout << iaaa << endl;
    return 0;
}

練習 3.41

#include <iostream>
#include <string>
#include <vector>
#include <cstring>
using namespace std;
int main(){

    int a[4] = {0,2,4,2};
    vector<int> aa(begin(a), end(a));
    for (auto c : aa)
        cout << c << endl;
    return 0;
}

練習3.42

整型陣列不能用 vector 物件直接初始化,所以應採用逐個拷貝的方法。

練習3.43

//按順序三種版本。
#include <iostream>
#include <string>
#include <vector>
#include <cstring>
using namespace std;
int main(){
    int ia[3][4] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
    for (int (&row)[4] : ia)
        for (int  col : row)
            cout << col << ' ';
    cout << endl;
    for (int row = 0; row < 3; ++row)
        for (int col = 0; col < 4; ++col)
            cout << ia[row][col] << ' ';
    cout << endl;
    for (int (*row)[4] = ia; row != ia + 3; row++)
        for (int *col = *row; col != *row + 4; col++)
            cout << * col << ' ';
    cout << endl;
    return 0;
}

練習3.44

//類型別名就簡單很多。
#include <iostream>
#include <string>
#include <vector>
#include <cstring>
using namespace std;
using int_array = int[4];
int main(){
    int ia[3][4] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
    for (int_array &row : ia)
        for (int  col : row)
            cout << col << ' ';
    cout << endl;
    return 0;
}

練習3.45

 //auto 就更簡單了。
#include <iostream>
#include <string>
#include <vector>
using namespace std;
int main(){
    int ia[3][4] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
    for (auto &row : ia)
        for (int  col : row)
            cout << col << ' ';
    cout << endl;
    return 0;
}