第三章 字符串,向量和数组
3.1
Part A
// use `using` for 1.4.1 #include <iostream> using std::cin; using std::cout; using std::endl; int main() { int sum = 0, val = 1; // keep executing the while as long as val is less than or equal to 10 while (val <= 10) { sum += val; ++val; } cout << "Sum of 1 to 10 inclusive is " << sum << endl; return 0;
Part B
#include <iostream> #include <string> using std::string; using std::cin; using std::cout; using std::endl; using std::cerr; struct Sales_data { string bookNo; unsigned units_sold = 0; double revenue = 0.0; }; int main() { Sales_data data1, data2; // code to read into data1 and data2 double price = 0; // price per book, used to calculate total revenue // read the first transactions: ISBN, number of books sold, price per book cin >> data1.bookNo >> data1.units_sold >> price; // calculate total revenue from price and units_sold data1.revenue = data1.units_sold * price; // read the second transaction cin >> data2.bookNo >> data2.units_sold >> price; data2.revenue = data2.units_sold * price; // code to check whether data1 and data2 have the same ISBN // and if so print the sum of data1 and data2 if (data1.bookNo == data2.bookNo) { unsigned totalCnt = data1.units_sold + data2.units_sold; double totalRevenue = data1.revenue + data2.revenue; // print: ISBN, total sold, total revenue, average price per book cout << data1.bookNo << " " << totalCnt << " " << totalRevenue << " "; if (totalCnt != 0) cout << totalRevenue / totalCnt << endl; else cout << "(no sales)" << endl; return 0; // indicate success } else { // transactions weren't for the same ISBN cerr << "Data must refer to the same ISBN" << endl; return -1; // indicate failure } }
3.2
part A
// read the standard input a line at a time. #include <iostream> #include <string> using std::string; using std::cin; using std::cout; using std::endl; using std::getline; int main() { string input; while (getline(cin, input)) cout << input << endl; return 0; }
part B
// read the standard input a word at a time #include <iostream> #include <string> using std::string; using std::cin; using std::cout; using std::endl; int main() { string word; while (cin >> word) cout << word << endl; return 0; }
3.3
在执行读取操作时,string对象会自动忽略开头的空白(即空格符,换行符,制表符等),并从一个真正的字符开始读起,直到遇见下一处空白为止。
getline函数从给定的输入流读入内容,直到遇到换行符,然后把所读的内容存入到那个string对象中去(不存换行符)。
3.4
part A
// read two strings and report whether the strings are equal // If not, report which of the two is larger. #include <iostream> #include <string> using std::string; using std::cin; using std::cout; using std::endl; int main() { string str1, str2; while (cin >> str1 >> str2) { if (str1 == str2) cout << "The two strings are equal." << endl; else cout << "The larger string is " << ((str1 > str2) ? str1 : str2); } return 0; }
part B
// read two strings and report whether the strings have the same length // If not, report which is longer #include <iostream> #include <string> using std::string; using std::cin; using std::cout; using std::endl; int main() { string str1, str2; while (cin >> str1 >> str2) { if (str1.size() == str2.size()) cout << "The two strings have the same length." << endl; else cout << "The longer string is " << ((str1.size() > str2.size()) ? str1 : str2); } return 0; }
3.5
part A
// read strings from the standard input, concatenating what is read into one // large string. // Print the concatenated string. #include <iostream> #include <string> using std::string; using std::cin; using std::cout; using std::endl; int main() { string largeStr; string str; while (cin >> str) { largeStr += str; } cout << "The concatenated string is " << largeStr << endl; return 0; }
part B
// separate adjacent input strings by a space. #include <iostream> #include <string> using std::string; using std::cin; using std::cout; using std::endl; int main() { string largeStr; string str; while (cin >> str) { if (largeStr.empty()) largeStr += str; else largeStr += " " + str; } cout << "The concatenated string is " << largeStr << endl; return 0; }
3.6
// Use a range for to change all the characters in a string to X. #include <iostream> #include <string> using std::string; using std::cout; using std::endl; int main() { string str("a simple string"); for (auto& c : str) c = 'X'; cout << str << endl; return 0; }
3.7
没有不同,通过使用auto关键字让编译器来决定变量c的类型,这里c的类型是char。
3.8
// Use a range for to change all the characters in a string to X. #include <iostream> #include <string> using std::string; using std::cout; using std::endl; int main() { string str("a simple string"); // use while decltype(str.size()) i = 0; while (i < str.size()) { str[i] = 'X'; ++i; } cout << str << endl; // use traditional for for (i = 0; i < str.size(); ++i) str[i] = 'Y'; cout << str << endl; // I like the first one. return 0; }
3.9
不合法。因为s为空,s[0]的结果将是未定义的。在访问指定字符之前,首先检查s是否为空。
3.10
// reads a string of characters including punctuation and writes what was read // but with the punctuation removed. #include <iostream> #include <string> using std::string; using std::cout; using std::cin; using std::endl; int main() { string s; cout << "Enter a string of characters including punctuation." << endl; while (getline(cin, s)) { for (auto i : s) if (!ispunct(i)) cout << i; cout << endl; } return 0; }
3.11
c的类型是字符型常量引用,只要不改变c的值,都是合法的,否则是非法的。
3.12
(a)合法(c++11),其对象是vector对象。
(b)不合法,两个vector对象的类型必须相同。
(c)合法,有10个“null"。
3.13
(a)初始状态为空,没有元素。
(b)10个元素,都是0。
(c)10个元素,都是42。
(d)1个元素,是10。
(e)2个元素,10和42。
(f)10个默认初始化的元素。
(g)10个值为”hi"的元素。
3.14
#include <iostream> #include <vector> int main() { std::vector<int> vec; int i; while (std::cin >> i) vec.push_back(i); return 0; }
3.15
include <iostream> #include <vector> #include <string> int main() { std::vector<std::string> vec; std::string str; while (std::cin >> str) vec.push_back(str); return 0; }
3.16
#include <iostream> #include <vector> #include <string> using std::vector; using std::string; using std::cout; using std::endl; int main() { vector<int> v1; cout << "{\n \"v1\":{\"size\":\"" << v1.size() << "\",\"value\":["; for (auto i : v1) cout << i << ","; if (!v1.empty()) cout << "\b"; cout << "]}" << endl; vector<int> v2(10); cout << " \"v2\":{\"size\":\"" << v2.size() << "\",\"value\":["; for (auto i : v2) cout << i << ","; if (!v2.empty()) cout << "\b"; cout << "]}" << endl; vector<int> v3(10, 42); cout << " \"v3\":{\"size\":\"" << v3.size() << "\",\"value\":["; for (auto i : v3) cout << i << ","; if (!v3.empty()) cout << "\b"; cout << "]}" << endl; vector<int> v4{10}; cout << " \"v4\":{\"size\":\"" << v4.size() << "\",\"value\":["; for (auto i : v4) cout << i << ","; if (!v4.empty()) cout << "\b"; cout << "]}" << endl; vector<int> v5{10, 42}; cout << " \"v5\":{\"size\":\"" << v5.size() << "\",\"value\":["; for (auto i : v5) cout << i << ","; if (!v5.empty()) cout << "\b"; cout << "]}" << endl; vector<string> v6{10}; cout << " \"v6\":{\"size\":\"" << v6.size() << "\",\"value\":["; for (auto i : v6) if (i.empty()) cout << "(null)" << ","; else cout << i << ","; if (!v6.empty()) cout << "\b"; cout << "]}" << endl; vector<string> v7{10, "hi"}; cout << " \"v7\":{\"size\":\"" << v7.size() << "\",\"value\":["; for (auto i : v7) if (i.empty()) cout << "(null)" << ","; else cout << i << ","; if (!v7.empty()) cout << "\b"; cout << "]}\n}" << endl; return 0; }
3.17
#include <iostream> #include <vector> #include <string> using std::cin; using std::cout; using std::endl; using std::vector; using std::string; int main() { vector<string> vec; string word; while (cin >> word) vec.push_back(word); for (auto& str : vec) for (auto& c : str) c = toupper(c); for (decltype(vec.size()) i = 0; i != vec.size(); ++i) { if (i != 0 && i % 8 == 0) cout << endl; cout << vec[i] << " "; } cout << endl; return 0; }
3.18
#include <vector> using std::vector; int main() { vector<int> ivec{0}; ivec[0] = 42; return 0; }
3.19
#include <iostream> #include <vector> using std::vector; int main() { vector<int> ivec1(10, 42); vector<int> ivec2{42, 42, 42, 42, 42, 42, 42, 42, 42, 42}; vector<int> ivec3; for (int i = 0; i != 10; ++i) ivec3.push_back(42); std::cout << "The first approach is better!" << std::endl; }
3.20
#include <iostream> #include <vector> using std::vector; using std::cout; using std::endl; using std::cin; int main() { vector<int> ivec; int i; while (cin >> i) ivec.push_back(i); if (ivec.empty()) { cout << "input at least one integer." << endl; return -1; } else if (ivec.size() == 1) { cout << ivec[0] << " don't have any adjacent elements."; } else { for (decltype(ivec.size()) i = 0; i != ivec.size() - 1; ++i) cout << ivec[i] + ivec[i + 1] << " "; } cout << endl; decltype(ivec.size()) size = ivec.size(); if (size % 2 != 0) size = size / 2 + 1; else size /= 2; for (decltype(ivec.size()) i = 0; i != size; ++i) cout << ivec[i] + ivec[ivec.size() - i - 1] << " "; cout << endl; return 0; }
3.21
#include <vector> #include <iterator> #include <string> #include <iostream> using std::vector; using std::string; using std::cout; using std::endl; void check(const vector<int>& vec) { if (vec.empty()) cout << "size: 0; no values." << endl; else { cout << "size: " << vec.size() << "; values:"; for (auto it = vec.begin(); it != vec.end(); ++it) cout << *it << ","; cout << "\b." << endl; } } void check(const vector<string>& vec) { if (vec.empty()) cout << "size: 0; no values." << endl; else { cout << "size: " << vec.size() << "; values:"; for (auto it = vec.begin(); it != vec.end(); ++it) if (it->empty()) cout << "(null)" << ","; else cout << *it << ","; cout << "\b." << endl; } } 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"}; check(v1); check(v2); check(v3); check(v4); check(v5); check(v6); check(v7); return 0; }
3.22
#include <iostream> #include <vector> #include <string> #include <iterator> using std::vector; using std::string; using std::cout; using std::cin; using std::endl; int main() { vector<string> text; for (string line; getline(cin, line);) text.push_back(line); 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 <vector> #include <iostream> #include <iterator> using std::vector; using std::iterator; using std::cout; using std::endl; int main() { vector<int> ivec(10, 1); for (auto it = ivec.begin(); it != ivec.end(); ++it) *it *= 2; for (auto value : ivec) cout << value << " "; cout << endl; return 0; }
3.24
#include <iostream> #include <vector> #include <iterator> using std::vector; using std::cout; using std::endl; using std::cin; int main() { int i; vector<int> ivec; while (cin >> i) ivec.push_back(i); if (ivec.empty()) { cout << "input at least one integer." << endl; return -1; } else if (ivec.size() == 1) { cout << *ivec.begin() << " has no adjacent elements."; } for (auto it = ivec.begin(); it + 1 != ivec.end(); ++it) cout << *it + *(it + 1) << " "; cout << endl; for (auto beg = ivec.begin(), end = ivec.end() - 1; beg <= end; ++beg, --end) cout << *beg + *end << " "; cout << endl; return 0; }
3.25
#include <vector> #include <iterator> #include <iostream> using std::vector; using std::cout; using std::cin; using std::endl; int main() { vector<unsigned> scores(11, 0); unsigned grade; while (cin >> grade) if (grade <= 100) ++(*(scores.begin() + grade / 10)); for (auto score : scores) cout << score << " "; cout << endl; return 0; }
3.26
vector迭代器运算中不支持两个迭代器相加,只支持两个迭代器相减,或一个迭代器与整数值的加减。
3.27
(a) 非法,维度必须是一个常量表达式。
(b)合法。
(c)非法,返回值不是常量表达式。
(d)非法,没有空间可存放空字符。
3.28
string不是内置类型,其支持无须显式初始化而定义对象,没有指定初值则生成一个空串,ia,ia2是内置类型,ia在函数体之外被初始化为0,ia2在函数体内部将不被初始化,其值是未定义的。
3.29
数组大小确定不变,不能随意向数组中增加元素。
3.30
数组索引从0开始,所以ix应该小于array_size,不可以等于。
3.31
#include <cstddef> #include <iostream> using std::cout; using std::endl; int main() { int ia[10]; for (size_t i = 0; i < 10; ++i) ia[i] = i; for (auto i : ia) cout << i << " "; cout << endl; return 0; }
3.32
#include <cstddef> #include <iostream> #include <vector> #include <iterator> using std::cout; using std::endl; using std::vector; using std::iterator; int main() { // use array int ia[10]; for (size_t i = 0; i < 10; ++i) ia[i] = i; int ia2[10]; for (size_t i = 0; i < 10; ++i) ia2[i] = ia[i]; // use vector vector<int> iv(10); for (auto iter = iv.begin(); iter != iv.end(); ++iter) *iter = iter - iv.begin(); vector<int> iv2(iv); for (auto i : iv2) cout << i << " "; cout << endl; return 0; }
3.33
不初始化数组将含有未定义的值。
3.34
相当于p1=p2; 只要p1和p2都合法,则该程序一直合法。
3.35
#include <iostream> #include <iterator> using std::begin; using std::end; using std::cout; using std::endl; int main() { int arr[10]; int* b = begin(arr); int* e = end(arr); for (int* i = b; i != e; ++i) *i = 0; for (auto i : arr) cout << i << " "; cout << endl; return 0; }
3.36
#include <iostream> #include <vector> #include <iterator> using std::begin; using std::end; using std::cout; using std::endl; using std::vector; // pb point to begin of the array, pe point to end of the array. bool compare(int* const pb1, int* const pe1, int* const pb2, int* const pe2) { if ((pe1 - pb1) != (pe2 - pb2)) // have different size. return false; else { for (int *i = pb1, *j = pb2; (i != pe1) && (j != pe2); ++i, ++j) if (*i != *j) return false; } return true; } int main() { int arr1[3] = {0, 1, 2}; int arr2[3] = {0, 2, 4}; if (compare(begin(arr1), end(arr1), begin(arr2), end(arr2))) cout << "The two arrays are equal." << endl; else cout << "The two arrays are not equal." << endl; cout << "==========" << endl; vector<int> vec1 = {0, 1, 2}; vector<int> vec2 = {0, 1, 2}; if (vec1 == vec2) cout << "The two vectors are equal." << endl; else cout << "The two vectors are not equal." << endl; return 0; }
3.37
输出数组ca的所有元素。whiile循环检测空字符,需在数组最后一个字符后添加一个空字符。
3.38
因为两个指针相减可以得到在内存区域的相位差(距离),加减一个整数可以表明指针的前后移动。两个指针相加在逻辑上没有意义。
3.39
#include <iostream> #include <string> #include <cstring> using std::cout; using std::endl; using std::string; int main() { // use string. string s1("Mooophy"); string s2("Pezy"); if (s1 == s2) cout << "same string." << endl; else if (s1 > s2) cout << "Mooophy > Pezy" << endl; else cout << "Mooophy < Pezy" << endl; cout << "=========" << endl; // use C-Style character strings. const char* cs1 = "Wangyue"; const char* cs2 = "Pezy"; auto result = strcmp(cs1, cs2); if (result == 0) cout << "same string." << endl; else if (result < 0) cout << "Wangyue < Pezy" << endl; else cout << "Wangyue > Pezy" << endl; return 0; }
3.40
#include <cstring> #include <iostream> using std::cout; using std::endl; int main() { const char cstr1[] = "Hello"; const char cstr2[] = "world!"; size_t new_size = strlen(cstr1) + strlen(" ") + strlen(cstr2) + 1; char* cstr3 = new char[new_size]; strcpy(cstr3, cstr1); strcat(cstr3, " "); strcat(cstr3, cstr2); std::cout << cstr3 << std::endl; delete [] cstr3; }
3.41
#include <iostream> #include <vector> using std::vector; using std::cout; using std::endl; using std::begin; using std::end; int main() { int int_arr[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; vector<int> ivec(begin(int_arr), end(int_arr)); for (auto i : ivec) cout << i << " "; cout << endl; return 0; }
3.42
#include <iostream> #include <vector> using std::vector; using std::cout; using std::endl; using std::begin; using std::end; int main() { vector<int> ivec{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; int int_arr[10]; for (int* i = begin(int_arr); i != end(int_arr); ++i) *i = ivec[i - begin(int_arr)]; for (auto i : int_arr) cout << i << " "; cout << endl; return 0; }
3.43
#include <iostream> using std::cout; using std::endl; int main() { int ia[3][4] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}; // a range for to manage the iteration for (const int(&p)[4] : ia) for (int q : p) cout << q << " "; cout << endl; // ordinary for loop using subscripts for (size_t i = 0; i != 3; ++i) for (size_t j = 0; j != 4; ++j) cout << ia[i][j] << " "; cout << endl; // using pointers. for (int(*p)[4] = ia; p != ia + 3; ++p) for (int* q = *p; q != *p + 4; ++q) cout << *q << " "; cout << endl; return 0; }
3.44
#include <iostream> using std::cout; using std::endl; int main() { int ia[3][4] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}; // a range for to manage the iteration // use type alias using int_array = int[4]; for (int_array& p : ia) for (int q : p) cout << q << " "; cout << endl; // ordinary for loop using subscripts for (size_t i = 0; i != 3; ++i) for (size_t j = 0; j != 4; ++j) cout << ia[i][j] << " "; cout << endl; // using pointers. // use type alias for (int_array* p = ia; p != ia + 3; ++p) for (int* q = *p; q != *p + 4; ++q) cout << *q << " "; cout << endl; return 0; }
3.45
#include <iostream> using std::cout; using std::endl; int main() { int ia[3][4] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}; // a range for to manage the iteration for (auto& p : ia) for (int q : p) cout << q << " "; cout << endl; // ordinary for loop using subscripts for (size_t i = 0; i != 3; ++i) for (size_t j = 0; j != 4; ++j) cout << ia[i][j] << " "; cout << endl; // using pointers. for (auto p = ia; p != ia + 3; ++p) for (int* q = *p; q != *p + 4; ++q) cout << *q << " "; cout << endl; return 0; }