答案目录

第3章 字符串、向量和数组

本章代码开头需要以下部分

1
2
3
4
#include <iostream>
#include <string>
#include <vector>
using namespace std;

练习3.2

1
2
3
4
5
6
7
8
9
10
11
12
13
int main()
{
string line;
//一次读入一行
while (getline(cin, line))
cout << line << endl;
//上下两部分代码不能一起用
string word;
//一次读入一个词
while (cin >> word)
cout << word << endl;
return 0;
}

练习3.3

输入运算符会自动忽略字符串前的空白(空格、制表符、换行等),从第一个真正的字符到下一个空白;
getline函数会保存字符串中的空白,读入数据直到遇见换行符,如果第一个就是换行符那就输出一个空string;

练习3.4

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
int main()
{
string line1, line2;
cin >> line1 >> line2;
if (line1 == line2)
cout << "Equal " << line1 << endl;
else
{
if (line1 > line2)
cout <<"Different "<< line1 << endl;
else
cout <<"Different "<< line2 << endl;
}
if(line1.size() == line2.size())
cout << "Size equal " << line1 << endl;
else
{
if (line1.size() > line2.size())
cout << "Size different " << line1 << endl;
else
cout << "Size different " << line2 << endl;
}
return 0;
}

练习3.5

1
2
3
4
5
6
7
8
9
10
int main()
{
string line, temp;
while (getline(cin, temp)) {

line += temp;//line += (temp +" ");
}
cout << line << endl;
return 0;
}

练习3.6

1
2
3
4
5
6
7
8
int main()
{
string str;
getline(cin, str);
for (auto &c : str)
c = 'X';
cout << str << endl;
}

练习3.7

无影响,因为输入的字符串内字符类型为char

练习3.8

都要先知道字符串的长度,相比较而言,范围for语句更加简洁一点

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
int main()
{
string str;
getline(cin, str);
int len = str.size();
//for (int i = 0; i < len; i++)
// str[i] = 'X';
int i = 0;
while (i<len)
{
str[i] = 'X';
i++;
}
cout << str << endl;
}

练习3.9

不合法,使用超出范围的下标将引发不可预知的结果,由此推断,使用下标访问空string也会引发不可预知的结果

练习3.10

1
2
3
4
5
6
7
8
9
10
11
12
int main()
{
string str, result;
getline(cin, str);
for (auto c : str) {
if (ispunct(c))
continue;
else
result += c;
}
cout << result << endl;
}

练习3.11

不合法,设置一个auto类型的引用时,初始值中的顶层const依旧保留,c的类型为const string&。如果在for循环中要改变c的值,则语句不合法;

练习3.12

1
2
3
vector<vector<int>> ivec;    //合法,创建类型为vector<int>的对象。
vector<string> svec = ivec; //不合法,svec是string类型,而ivec是vector<int>类型。
vector<string>svec(10, "null"); //合法,创建10个string类型的元素,每个都被初始化为null

练习3.13

1
2
3
4
5
6
7
(a)vector<int> v1;                     //不包含元素
(b)vector<int> v2(10); //包含10个元素,每个都初始化为0
(c)vector<int> v3(10, 42); // 包含10个元素,每个都初始化为42
(d)vector<int> v4{10}; // 包含1个元素,值为10
(e)vector<int> v5{10, 42}; // 包含2个元素,值分别是10和42
(f)vector<string> v6{10}; // 10个默认初始化的元素,初始化为空
(g)vector<string> v7{10, "hi"}; // 10个值为hi的元素

练习3.14,3.15

1
2
3
4
5
6
7
8
9
10
11
12
13
int main()
{
vector<int> sum;
int number;
while (cin >> number) {
sum.push_back(number);
}
vector<string> str;
string word;
while (cin >> word) {
str.push_back(word);
}
}

练习3.17

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
int main()
{
vector<string> sen;
string word;
while (cin >> word) {
sen.push_back(word);
}
for (auto &temp:sen)
for (auto& str : temp) {
str = toupper(str);
}
for (auto i : sen)
cout << i << endl;
return 0;
}

练习3.18

不合法,ivec为空,不包含任何元素,不能通过下标去访问元素

应改为 ivec.push_back(42);或者给ivec加一个大小;

练习3.19

1
2
3
4
5
6
int main()
{
vector<int> number(10,42);
vector<int> number1(number);
vector<int> number2{ 42,42,42,42,42,42,42,42,42,42 };
}

练习3.20

1
2
3
4
5
6
7
8
9
10
11
int main()
{
vector<int> num;
int i;
while (cin >> i)
num.push_back(i);
for (i = 0; i < num.size()-1; i++)
cout << num[i] + num[i + 1]<<" ";
cout << endl;
return 0;
}
1
2
3
4
5
6
7
8
9
10
11
12
int main()
{
vector<int> num;
int i;
while (cin >> i)
num.push_back(i);
int size = num.size();
for (i = 0; i <size; i++)
cout << num[i] + num[size -1 - i]<<" ";
cout << endl;
return 0;
}

练习3.23

1
2
3
4
5
6
7
8
9
10
11
12
int main()
{
vector<int> res = { 1,2,3,4,5,6,7,8,9,10 };
for (auto it = res.begin(); it != res.end(); it++) {
*it = (*it) * 2;
}
for (auto i : res) {
cout << i <<" ";
}
cout << endl;
return 0;
}

练习3.24

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
int main()
{
vector<int> text(10);
for (int i = 0; i < 10; i++)
{
cin >> text[i];
}
for (auto vector_begin = text.begin(), vector_end = text.end(); vector_begin != vector_end-1; vector_begin++) //这里减1是因为end指向text尾元素的下一位
cout << *vector_begin+ * (vector_begin + 1) << endl;

for (auto vector_begin = text.begin(), vector_end = text.end(); vector_begin != vector_end; vector_begin++)
{
vector_end--;
cout << *vector_begin + *vector_end << endl;
}
}

练习3.25

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
int main()
{
vector<unsigned> scores(11, 0);
unsigned grade;
while (cin >> grade)
{
if (grade <= 100)
{
auto it = scores.begin();
++* (it + grade / 10);
}
else
{
continue;
}
}
for (auto i : scores)
{
cout << i << " ";
}
cout << endl;
return 0;
}

练习3.26

因为end指的是最后一个元素的后一个位置!!!

练习3.27

1
2
3
4
5
unsigned buf_size = 1024;
int ia[buf_size]; //非法,buf_size不是常量
int ia[4*7-14]; // 合法
int ia[txt_size()]; // 非法,函数返回值不是常量
char str[11] = "fundamental"; // 非法,没有空间可放空字符

练习3.28

1
2
3
4
5
6
7
8
9
int main()
{
string sa[10];
int ia[10];
for (auto i:ia)
cout << i << " ";
//cout << i << " ";
cout << endl;
}

ia[10]中含有10个未知数,sa[10]中均为空对象

练习3.29

数组长度不可扩展,一旦定义,不能再更改长度,vector则比较灵活

练习3.30

1
2
3
4
5
6
7
constexpr size_t array_size = 10;
int ia[array_size];
for (size_t ix = 1; ix <= array_size; ix ++)
{
// 下标越界,下标范围为0--9,而不是1--10
ia[ix] = ix;
}

练习3.31

1
2
3
4
5
6
7
8
9
10
int main()
{
int num[10]={};
for (int i = 0; i < 10; i++)
num[i] = i;
for (auto j : num)
cout << j << " ";
cout << endl;
return 0;
}

练习3.32

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
int main()
{
int num[10]={};
for (int i = 0; i < 10; i++)
num[i] = i;
//for (auto j : num)
// cout << j << " ";
//return 0;
int a[10];
for (int i = 0; i < 10; i++)
a[i] = num[i];
for (auto j : a)
cout << j << " ";
cout << endl;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
int main()
{
vector<int> vec(10);
for (int i = 0; i < 10; i++)
{
vec[i] = i;
}

for (auto iter : vec)
{
cout << iter << " ";
}
cout << endl;

vector<int> vec1(vec);
for (auto iter1 : vec1) {
cout << iter1 << " ";
}
cout << endl;
}

练习3.33
不初始化scores,则其中内容未知,大概率输出结果为错误;

练习3.34

p1和p2是指针,相减为其地址相减,因为指向的是同一元素,地址相同,因此p1地址不变;

只要p1和p2合法,这个语句就是合法的;

练习3.35

1
2
3
4
5
6
7
8
9
10
11
12
13
int main()
{
int a[10] = { };
int* p = a;
for (int i = 0; i < 10; i++)
{
*p = 0;
p++;
}
for (auto i : a)
cout << i << " ";
cout << endl;
}

练习3.36

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
int main()
{
int a[10] = { 0,1,2,3,4,5,6,7,8,9 };
int b[10] = { 0,1,2,3,4,5,6,7,8,9 };
int flag = 0;
if (sizeof(a) == sizeof(b))
{
int len = sizeof(a) / sizeof(a[0]);
for (int i = 0; i <len; i++)
if (a[i] == b[i])
flag++;
if (flag == len)
cout << "Equal" << endl;
else
{
cout << "Not equal" << endl;
}
}
else
{
cout << "Couldn't be comapred" << endl;
}
}

vector的比较直接用等号就可以;

1
2
3
4
5
6
7
8
9
10
11
int main()
{
vector<int> vec1 = { 1,2,3,4,5,6,7,8,9 };
vector<int> vec2 = { 1,2,3,4,5,6,7,8,9 };
if (vec1 == vec2) {
cout << "equal" << endl;
}
else {
cout << "not equal" << endl;
}
}

练习3.37

1
2
3
4
5
6
7
8
9
10
int main()
{
const char ca[] = { 'h', 'e', 'l', 'l', 'o' };
const char* cp = ca;
while (*cp) {
cout << *cp << endl;
++cp;
}
}
//ca初始化时,并未加‘\0’,因此其长度未知,while循环会一直继续知道遇见'\0'。输出“hello+未知字符”

练习3.38

两个指针相加,相当于两个地址值相加,比如0x849248 + 0x328134.并没有实际意义

练习3.39

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
int main()
{
string str1 = "hello world";
string str2 = "hello world";
if (str1 == str2)
{
cout << str1 << " is equal with " << str2 << endl;
}
else
{
cout << str1 << " is not equal with " << str2 << endl;
}
char c1[] = { 'c','+','+','\0' };
char c2[] = { 'c','+','+','\0' };
if (strcmp(c1, c2))
{
cout << "c1>c2" << endl;
}
else if (strcmp(c1, c2) == 0)
{
cout << "c1=c2" << endl;
}
else
{
cout << "c1<c2" << endl;
}
}

练习3.40

不知道为啥一直报错,逻辑上写的和网络上的方法是一样的

1
2
3
4
5
6
7
8
9
10
int main()
{
char s1[] = { 'U','E','S','T','C','\0'};
char s2[] = { 'I',' ','L','O','V','E',' ','\0' };
char s3[100];
strcpy(s3, s2);
strcat(s3, " ");
strcat(s3, s1);
cout << s3 << endl;
}

练习3.41

1
2
3
4
5
int main()
{
int num[10] = { 1, 3, 5, 7, 9, 2, 4, 6, 8, 10 };
vector<int> vec(num, num + 10);
}

练习3.42

1
2
3
4
5
6
7
8
9
int main()
{
vector<int> ivec = { 1, 3, 5, 7, 9, 2, 4, 6, 8, 10 };
int c[10];

for (int i = 0; i < 10; i++) {
c[i] = ivec[i];
}
}

练习3.43

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
int main()
{
int ia[3][4] = {
{0, 1, 2, 3},
{4, 5, 6, 7},
{8, 9, 10, 11}
};

// version1
// 要用int引用,是因为防止数组被自动转化成指针。int row[4],就会变成int指针。
for (const int(&row)[4] : ia) {
for (int col : row)
cout << col << " ";
}
cout << endl;

// version 2
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 4; j++)
cout << ia[i][j] << " ";
}
cout << endl;

// version 3
// p指向含有4个整数的数组,q指向p的首元素
for (int(*p)[4] = ia; p != ia + 3; p++) {
for (int* q = *p; q != *p + 4; q++)
cout << *q << " ";
}
cout << endl;

}

练习3.44

记得在开头加上:

using std::begin;
using std::end;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
int main()
{
int ia[3][4] = {
{0, 1, 2, 3},
{4, 5, 6, 7},
{8, 9, 10, 11}
};
//使用别名
using ci = const int[4];
// version 1
for (ci& row : ia) {
for (int col : row) {
cout << col << " ";
}
}
cout << endl;

// version 2
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 4; j++)
cout << ia[i][j] << " ";
}
cout << endl;

// version 3
// 使用别名
using ip = int[4];
for (ip* p = begin(ia); p != end(ia); p++) {
for (auto q = begin(*p); q != end(*p); q++) {
cout << *q << " ";
}
}
cout << endl;
}

练习3.45

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
int main()
{
int ia[3][4] = {
{0, 1, 2, 3},
{4, 5, 6, 7},
{8, 9, 10, 11}
};
// version 1
for (auto& row : ia) {
for (auto col : row) {
cout << col << " ";
}
}
cout << endl;

// version 2
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 4; j++)
cout << ia[i][j] << " ";
}
cout << endl;

// version 3
// p指向含有4个整数的数组,q指向p的首元素
for (auto p = begin(ia); p != end(ia); p++) {
for (auto q = begin(*p); q != end(*p); q++) {
cout << *q << " ";
}
}
cout << endl;
}