实验1 现代C++编程初体验
一、实验任务1源代码:

1 #include <iostream> 2 #include <string> 3 #include <vector> 4 #include <algorithm> 5 // 模板函数声明 6 template<typename T> 7 void output(const T& c); 8 void test1(); 9 void test2(); 10 void test3(); 11 int main() { 12 std::cout << "测试1: \n"; 13 test1(); 14 std::cout << "\n测试2: \n"; 15 test2(); 16 std::cout << "\n测试3: \n"; 17 test3(); 18 } 19 // 输出容器对象c中的元素 20 template <typename T> 21 void output(const T& c) { 22 for (auto& i : c) 23 std::cout << i << ' '; 24 std::cout << '\n'; 25 } 26 // 测试1:组合使用算法库、迭代器、string反转字符串 27 void test1() { 28 using namespace std; 29 string s0{ "0123456789" }; 30 cout << "s0 = " << s0 << endl; 31 string s1(s0); 32 // 反转s1自身 33 reverse(s1.begin(), s1.end()); 34 cout << "s1 = " << s1 << endl; 35 string s2(s0.size(), ' '); 36 // 将s0反转后结果拷贝到s2, s0自身不变 37 reverse_copy(s0.begin(), s0.end(), s2.begin()); 38 cout << "s2 = " << s2 << endl; 39 } 40 // 测试2:组合使用算法库、迭代器、vector反转动态数组对象vector内数据 41 void test2() { 42 using namespace std; 43 vector<int> v0{ 2, 0, 4, 9 }; 44 cout << "v0: "; output(v0); 45 vector<int> v1{ v0 }; 46 reverse(v1.begin(), v1.end()); 47 cout << "v1: "; output(v1); 48 vector<int> v2{ v0 }; 49 reverse_copy(v0.begin(), v0.end(), v2.begin()); 50 cout << "v2: "; output(v2); 51 } 52 // 测试3:组合使用算法库、迭代器、vector实现元素旋转移位 53 void test3() { 54 using namespace std; 55 vector<int> v0{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; 56 cout << "v0: "; output(v0); 57 vector<int> v1{ v0 }; 58 // 将[v1.begin(), v1.end())区间内元素循环左移1位 59 rotate(v1.begin(), v1.begin() + 1, v1.end()); 60 cout << "v1: "; output(v1); 61 vector<int> v2{ v0 }; 62 // 将[v1.begin(), v1.end())区间内元素循环左移2位 63 rotate(v2.begin(), v2.begin() + 2, v2.end()); 64 cout << "v2: "; output(v2); 65 vector<int> v3{ v0 }; 66 // 将[v1.begin(), v1.end())区间内元素循环右移1位 67 rotate(v3.begin(), v3.end() - 1, v3.end()); 68 cout << "v3: "; output(v3); 69 vector<int> v4{ v0 }; 70 // 将[v1.begin(), v1.end())区间内元素循环右移2位 71 rotate(v4.begin(), v4.end() - 2, v4.end()); 72 cout << "v4: "; output(v4); 73 }
任务1运行截图:
二、实验任务2源代码:

1 #include <iostream> 2 #include <vector> 3 #include <algorithm> 4 #include <numeric> 5 #include <iomanip> 6 #include <cstdlib> 7 #include <ctime> 8 // 模板函数声明 9 template<typename T> 10 void output(const T& c); 11 int generate_random_number(); 12 void test1(); 13 void test2(); 14 int main() { 15 std::srand(std::time(0)); 16 std::cout << "测试1: \n"; 17 test1(); 18 // 添加随机种子 19 std::cout << "\n测试2: \n"; 20 test2(); 21 } 22 // 输出容器对象c中的元素 23 template <typename T> 24 void output(const T& c) { 25 for (auto& i : c) 26 std::cout << i << ' '; 27 std::cout << '\n'; 28 } 29 // 返回[0, 100]区间内的一个随机整数 30 int generate_random_number() { 31 return std::rand() % 101; 32 } 33 // 测试1:对容器类对象指定迭代器区间赋值、排序 34 void test1() { 35 using namespace std; 36 vector<int> v0(10); // 创建一个动态数组对象v0, 对象大小为10 37 generate(v0.begin(), v0.end(), generate_random_number); // 生成随机数填充v0 38 cout << "v0: "; output(v0); 39 vector<int> v1{ v0 }; 40 sort(v1.begin(), v1.end()); // 对整个vector排序 41 cout << "v1: "; output(v1); 42 vector<int> v2{ v0 }; 43 sort(v2.begin() + 1, v2.end() - 1); // 只对中间部分排序,不包含首尾元素 44 cout << "v2: "; output(v2); 45 } 46 // 测试2:对容器类对象指定迭代器区间赋值、计算最大值/最小值/均值 47 void test2() { 48 using namespace std; 49 vector<int> v0(10); 50 generate(v0.begin(), v0.end(), generate_random_number); 51 cout << "v0: "; output(v0); 52 // 求最大值和最小值 53 auto min_iter = min_element(v0.begin(), v0.end()); 54 auto max_iter = max_element(v0.begin(), v0.end()); 55 cout << "最小值: " << *min_iter << endl; 56 cout << "最大值: " << *max_iter << endl; 57 // 同时求最大值和最小值 58 auto ans = minmax_element(v0.begin(), v0.end()); 59 cout << "最小值: " << *(ans.first) << endl; 60 cout << "最大值: " << *(ans.second) << endl; 61 // 求平均值 62 double avg1 = accumulate(v0.begin(), v0.end(), 0.0) / v0.size(); 63 cout << "均值: " << fixed << setprecision(2) << avg1 << endl; 64 sort(v0.begin(), v0.end()); 65 double avg2 = accumulate(v0.begin() + 1, v0.end() - 1, 0.0) / (v0.size() - 2); 66 cout << "去掉最大值、最小值之后,均值: " << avg2 << endl; 67 }
任务2运行截图:
问题1回答:提供一个生成器为指定区间每一个元素进行赋值
问题2回答:效率更高
问题3回答:前者适用于生成逻辑复杂、多次复用,后者适用于逻辑简单、无需复用
三、实验任务3源代码:

1 #include <iostream> 2 #include <string> 3 #include <algorithm> 4 #include <cctype> 5 unsigned char func(unsigned char c); 6 void test1(); 7 void test2(); 8 int main() { 9 std::cout << "测试1: 字符串大小写转换\n"; 10 test1(); 11 std::cout << "\n测试2: 字符变换\n"; 12 test2(); 13 } 14 unsigned char func(unsigned char c) { 15 if (c == 'z') 16 return 'a'; 17 if (c == 'Z') 18 return 'A'; 19 if (std::isalpha(c)) 20 return static_cast<unsigned char>(c + 1); 21 return c; 22 } 23 void test1() { 24 std::string s1{ "Hello World 2049!" }; 25 std::cout << "s1 = " << s1 << '\n'; 26 std::string s2; 27 for (auto c : s1) 28 s2 += std::tolower(c); 29 std::cout << "s2 = " << s2 << '\n'; 30 std::string s3; 31 for (auto c : s1) 32 s3 += std::toupper(c); 33 std::cout << "s3 = " << s3 << '\n'; 34 } 35 void test2() { 36 std::string s1{ "I love cosmos!" }; 37 std::cout << "s1 = " << s1 << '\n'; 38 std::string s2(s1.size(), ' '); 39 std::transform(s1.begin(), s1.end(), 40 s2.begin(), 41 func); 42 std::cout << "s2 = " << s2 << '\n'; 43 }
任务3运行截图:
问题1回答:将z变为a,将Z变为A,其余字母变为下一个字母
问题2回答:tolower是将单个大写字母转换为对应的小写字母,非大写字母字符原样返回
toupper是将单个小写字母转换为对应的大写字母,对非小写字母字符原样返回
问题3回答:将指定的操作应用于序列的每个元素,并将结果写入另一个序列。修改参数之后会覆写s1
四、实验任务4源代码:

1 #include <iostream> 2 #include <string> 3 #include <algorithm> 4 bool is_palindrome(const std::string& s); 5 bool is_palindrome_ignore_case(const std::string& s); 6 int main() { 7 using namespace std; 8 string s; 9 // 多组输入,直到按下Ctrl+Z结束测试 10 while (cin >> s) { 11 cout << boolalpha 12 << "区分大小写: " << is_palindrome(s) << "\n" 13 << "不区分大小写: " << is_palindrome_ignore_case(s) << "\n\n"; 14 } 15 } 16 // 函数is_palindrome定义 17 bool is_palindrome(const std::string& s) { 18 int left = 0; 19 int right = s.size() - 1; 20 21 while (left < right) { 22 if (s[left] != s[right]) { 23 return false; 24 } 25 left++; 26 right--; 27 } 28 return true; 29 } 30 31 // 函数is_palindrome_ignore_case定义 32 bool is_palindrome_ignore_case(const std::string& s) { 33 int left = 0; 34 int right = s.size() - 1; 35 36 while (left < right) { 37 if (std::tolower(s[left]) != std::tolower(s[right])) { 38 return false; 39 } 40 left++; 41 right--; 42 } 43 return true; 44 }
任务4运行截图:
问题回答:可以使用getline(cin, s)进行输入操作
五、实验任务5源代码:

1 #include <iostream> 2 #include <string> 3 #include <algorithm> 4 5 std::string dec2n(int x, int n = 2); 6 7 int main() { 8 int x; 9 while (std::cin >> x) { 10 std::cout << "十进制: " << x << '\n' 11 << "二进制: " << dec2n(x) << '\n' 12 << "八进制: " << dec2n(x, 8) << '\n' 13 << "十二进制: " << dec2n(x, 12) << '\n' 14 << "十六进制: " << dec2n(x, 16) << '\n' 15 << "三十二进制: " << dec2n(x, 32) << "\n\n"; 16 } 17 } 18 // 函数dec2n定义 19 std::string dec2n(int x, int n) { 20 std::string result; 21 if (x == 0) return "0"; 22 23 while (x > 0) { 24 int r = x % n; 25 26 if (r < 10) { 27 result.push_back('0' + r); 28 } 29 else { 30 result.push_back('A' + (r - 10)); 31 } 32 x = x / n; 33 } 34 35 std::reverse(result.begin(), result.end()); 36 return result; 37 38 }
任务5运行截图:
六、实验任务6源代码:

1 #include <iostream> 2 #include <string> 3 #include <algorithm> 4 5 int main() { 6 std::cout << ' ' << ' '; 7 for (int i = 0; i < 26; i++) { 8 std::cout << ' ' << char('a' + i); 9 } 10 std::cout << std::endl; 11 12 for (int i = 1; i <= 26; i++) { 13 if (i < 10) std::cout << ' ' << i; else std::cout << i; 14 for (int j = 65; j <= 90; j++) { 15 if(j + i <= 90) 16 std::cout << ' ' << char(j + i); 17 else 18 std::cout << ' ' << char(j + i - 26); 19 } 20 std::cout << std::endl; 21 } 22 }
任务6运行结果:
七、实验任务7源代码:

1 #include <iostream> 2 #include <iomanip> 3 #include <ctime> 4 #include <cstdlib> 5 6 using namespace std; 7 8 int main() { 9 //随机初始化种子 10 srand(time(0)); 11 12 int correct = 0; 13 14 for (int i = 0; i < 10; i++) { 15 int num1 = rand() % 10 + 1; 16 int num2 = rand() % 10 + 1; 17 18 int operatortype = rand() % 4; 19 char operatorchar; 20 int answer; 21 22 switch (operatortype) { 23 case 0: 24 answer = num1 + num2; 25 operatorchar = '+'; 26 break; 27 28 case 1: 29 if (num1 < num2) { 30 swap(num1, num2); 31 } 32 answer = num1 - num2; 33 operatorchar = '-'; 34 break; 35 36 case 2: 37 answer = num1 * num2; 38 operatorchar = '*'; 39 break; 40 41 case 3: 42 if (num1 < num2) { 43 swap(num1, num2); 44 } 45 num1 = num1 / num2 * num2; 46 answer = num1 / num2; 47 operatorchar = '/'; 48 break; 49 } 50 51 int useranswer; 52 cout << num1 << ' ' << operatorchar << ' ' << num2 << ' ' << '=' << ' '; 53 cin >> useranswer; 54 55 if (useranswer == answer) { 56 correct++; 57 } 58 } 59 cout << "正确率:" << double(correct * 10) << '%' << endl; 60 }
任务7运行结果: