实验1 现代C++编程初体验
任务1:
源代码task1.cpp
1 #include <iostream> 2 #include <string> 3 #include <vector> 4 #include <algorithm> 5 6 7 template<typename T> 8 void output(const T &c); 9 void test1(); 10 void test2(); 11 void test3(); 12 13 int main() { 14 std::cout << "测试1: \n"; 15 test1(); 16 17 std::cout << "\n测试2: \n"; 18 test2(); 19 20 std::cout << "\n测试3: \n"; 21 test3(); 22 } 23 24 template <typename T> 25 void output(const T &c) { 26 for(auto &i : c) 27 std::cout << i << ' '; 28 std::cout << '\n'; 29 } 30 31 void test1() { 32 using namespace std; 33 34 string s0{"0123456789"}; 35 cout << "s0 = " << s0 << endl; 36 string s1(s0); 37 reverse(s1.begin(), s1.end()); 38 cout << "s1 = " << s1 << endl; 39 string s2(s0.size(), ' '); 40 reverse_copy(s0.begin(), s0.end(), s2.begin()); 41 cout << "s2 = " << s2 << endl; 42 } 43 44 void test2() { 45 using namespace std; 46 vector<int> v0{2, 0, 4, 9}; 47 cout << "v0: "; output(v0); 48 vector<int> v1{v0}; 49 reverse(v1.begin(), v1.end()); 50 cout << "v1: "; output(v1); 51 vector<int> v2{v0}; 52 reverse_copy(v0.begin(), v0.end(), v2.begin()); 53 cout << "v2: "; output(v2); 54 } 55 56 void test3() { 57 using namespace std; 58 vector<int> v0{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; 59 cout << "v0: "; output(v0); 60 vector<int> v1{v0}; 61 rotate(v1.begin(), v1.begin()+1, v1.end()); 62 cout << "v1: "; output(v1); 63 vector<int> v2{v0}; 64 rotate(v2.begin(), v2.begin()+2, v2.end()); 65 cout << "v2: "; output(v2); 66 vector<int> v3{v0}; 67 rotate(v3.begin(), v3.end()-1, v3.end()); 68 cout << "v3: "; output(v3); 69 vector<int> v4{v0}; 70 rotate(v4.begin(), v4.end()-2, v4.end()); 71 cout << "v4: "; output(v4); 72 }
运行结果截图:
问题1: reverse 和 reverse_copy 有什么区别?
答:reverse 会直接在原容器的指定范围内将元素顺序反转,reverse_copy 不改变原序列
问题2: rotate 算法是如何改变元素顺序的?它的三个参数分别代表什么?
答:函数执行后,会把从第二个参数指向的元素开始到末尾的部分移到前面,而原来从开始到该位置之前的部分则接在后面。参数第一个是序列的起始位置,第二个是新的首元素的位置,第三个是序列的结束位置。
任务2:
task2.cpp
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 12 int generate_random_number(); 13 void test1(); 14 void test2(); 15 16 int main() { 17 std::srand(std::time(0)); 18 std::cout << "测试1: \n"; 19 test1(); 20 std::cout << "\n测试2: \n"; 21 test2(); 22 } 23 24 template <typename T> 25 void output(const T &c) { 26 for(auto &i: c) 27 std::cout << i << ' '; 28 std::cout << '\n'; 29 } 30 31 int generate_random_number() { 32 return std::rand() % 101; 33 } 34 35 void test1() { 36 using namespace std; 37 vector<int> v0(10); 38 generate(v0.begin(), v0.end(), generate_random_number); 39 cout << "v0: "; output(v0); 40 41 vector<int> v1{v0}; 42 sort(v1.begin(), v1.end()); 43 cout << "v1: "; output(v1); 44 45 vector<int> v2{v0}; 46 sort(v2.begin()+1, v2.end()-1); 47 cout << "v2: "; output(v2); 48 } 49 50 void test2() { 51 using namespace std; 52 vector<int> v0(10); 53 generate(v0.begin(), v0.end(), generate_random_number); 54 cout << "v0: "; output(v0); 55 56 auto min_iter = min_element(v0.begin(), v0.end()); 57 auto max_iter = max_element(v0.begin(), v0.end()); 58 cout << "最小值: " << *min_iter << endl; 59 cout << "最大值: " << *max_iter << endl; 60 61 auto ans = minmax_element(v0.begin(), v0.end()); 62 cout << "最小值: " << *(ans.first) << endl; 63 cout << "最大值: " << *(ans.second) << endl; 64 65 double avg1 = accumulate(v0.begin(), v0.end(), 0.0) / v0.size(); 66 cout << "均值: " << fixed << setprecision(2) << avg1 << endl; 67 68 sort(v0.begin(), v0.end()); 69 double avg2 = accumulate(v0.begin()+1, v0.end()-1, 0.0) / (v0.size()-2); 70 cout << "去掉最大值、最小值之后,均值: " << avg2 << endl; 71 }
运行结果截图:

问题1: generate 算法的作用是什么?
答:generate 算法的作用是为容器中的每个元素赋值。
问题2: minmax_element 和分别调用 min_element 、 max_element 相比,有什么优势?
答:效率更高。
问题3:查询 generate 第3个参数 [](){return std::rand()%101;} 用法,与使用自定义函数
generate_random_number 相比,lambda表达式适用场景是什么?
答:适用于那些逻辑简单、只在局部使用一次的场景。
任务3:
task3.cpp
1 #include <iostream> 2 #include <string> 3 #include <algorithm> 4 #include <cctype> 5 6 unsigned char func(unsigned char c); 7 8 void test1(); 9 void test2(); 10 11 int main(){ 12 std::cout << "测试1: 字符串大小写转换\n"; 13 test1(); 14 std::cout << "\n测试2: 字符变换\n"; 15 test2(); 16 } 17 18 unsigned char func(unsigned char c) { 19 if(c == 'z') 20 return 'a'; 21 22 if(c == 'Z') 23 return 'A'; 24 25 if(std::isalpha(c)) 26 return static_cast<unsigned char>(c+1); 27 28 return c; 29 } 30 31 void test1() { 32 std::string s1{"Hello World 2049!"}; 33 std::cout << "s1 = " << s1 << '\n'; 34 35 std::string s2; 36 for(auto c: s1) 37 s2 += std::tolower(c); 38 std::cout << "s2 = " << s2 << '\n'; 39 40 std::string s3; 41 for(auto c: s1) 42 s3 += std::toupper(c); 43 std::cout << "s3 = " << s3 << '\n'; 44 } 45 46 void test2() { 47 std::string s1{"I love cosmos!"}; 48 std::cout << "s1 = " << s1 << '\n'; 49 std::string s2(s1.size(), ' '); 50 std::transform(s1.begin(), s1.end(), 51 s2.begin(), 52 func); 53 std::cout << "s2 = " << s2 << '\n'; 54 }
运行结果截图:

问题1:自定义函数 func 功能是什么?
答:函数 func使一个字母按字母表循环右移一位。
问题2: tolower 和 toupper 功能分别是什么?
答: tolower 将字符转为小写, toupper 将字符转为大写。
问题3: transform 的4个参数意义分别是什么?如果把第3个参数 s2.begin() 改成 s1.begin() ,有何区
generate(v0.begin(), v0.end(), [](){return std::rand()%101;});
1别?
答:4个参数分别是源开始、源结束、目标开始、变换函数。变换结果写回 s1 自身,s1 被修改
任务4:
task4.cpp
1 #include <iostream> 2 #include <string> 3 #include <algorithm> 4 5 bool is_palindrome(const std::string &s); 6 bool is_palindrome_ignore_case(const std::string &s); 7 8 int main() { 9 using namespace std; 10 string s; 11 12 // 多组输入,直到按下Ctrl+Z结束测试 13 while(cin >> s) { 14 cout << boolalpha 15 << "区分大小写: " << is_palindrome(s) << "\n" 16 << "不区分大小写: " << is_palindrome_ignore_case(s) << "\n\n"; 17 } 18 } 19 20 21 // 函数is_palindrome定义 22 bool is_palindrome(const std::string &s) { 23 int left = 0; 24 int right = s.size() - 1; 25 while (left < right) { 26 if (s[left] != s[right]) { 27 return false; 28 } 29 ++left; 30 --right; 31 } 32 return true; 33 } 34 35 36 37 // 函数is_palindrome_ignore_case定义 38 bool is_palindrome_ignore_case(const std::string &s) { 39 int left = 0; 40 int right = s.size() - 1; 41 while (left < right) { 42 if (std::tolower(s[left]) != std::tolower(s[right])) { 43 return false; 44 } 45 ++left; 46 --right; 47 } 48 return true; 49 }
运行结果截图:

问题:使用 cin >> s 输入时,输入的字符串中不能包含空格。如果希望测试字符串包含空格(如 hello
oop ),代码应如何调整?
答:将 cin >> s 改为 getline(cin, s)
任务5:
task5.cpp
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 if (x == 0) { 21 return "0"; 22 } 23 24 if (n < 2 || n > 36) { 25 return "错误:进制 n 必须在 [2, 36] 范围内!"; 26 } 27 28 std::string result = ""; 29 const std::string digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; // 最多到 Z (对应35) 30 31 while (x > 0) { 32 int remainder = x % n; 33 result += digits[remainder]; 34 x /= n; 35 } 36 37 std::reverse(result.begin(), result.end()); 38 return result; 39 }
运行结果截图:

任务6:
task.cpp
1 #include <iostream> 2 #include <string> 3 4 int main() { 5 using namespace std; 6 7 cout << " "; 8 for (char c = 'a'; c <= 'z'; ++c) { 9 cout << c << " "; 10 } 11 cout << "\n"; 12 13 for (int i = 1; i <= 26; ++i) { 14 cout << i << " "; 15 for (int j = 0; j < 26; ++j) { 16 char letter = 'A' + (j + i - 1) % 26; 17 cout << letter << " "; 18 } 19 cout << "\n"; 20 } 21 22 return 0; 23 }
运行结果截图:

任务7:
task7.cpp
1 #include <iostream> 2 #include <cstdlib> 3 #include <ctime> 4 #include <iomanip> 5 6 using namespace std; 7 8 int main() { 9 srand(time(0)); 10 11 int correct = 0; 12 const int total = 10; 13 14 cout << "请输入每道题的答案:\n\n"; 15 16 for (int i = 0; i < total; ++i) { 17 int a, b; 18 char op; 19 int result; 20 21 int type = rand() % 4; 22 23 if (type == 0) { 24 a = rand() % 10 + 1; 25 b = rand() % 10 + 1; 26 op = '+'; 27 result = a + b; 28 } 29 else if (type == 1) { 30 b = rand() % 10 + 1; 31 a = rand() % 10 + 1; 32 if (a < b) swap(a, b); 33 op = '-'; 34 result = a - b; 35 } 36 else if (type == 2) { 37 a = rand() % 10 + 1; 38 b = rand() % 10 + 1; 39 op = '*'; 40 result = a * b; 41 } 42 else { 43 b = rand() % 10 + 1; 44 45 a = b * (rand() % 10 / b + 1); 46 while (a > 10) { 47 a = b * (rand() % 10 / b + 1); 48 } 49 op = '/'; 50 result = a / b; 51 } 52 53 54 cout << a << " " << op << " " << b << " = "; 55 int user_answer; 56 cin >> user_answer; 57 58 if (user_answer == result) { 59 ++correct; 60 } 61 } 62 63 64 double accuracy = (double)correct / total * 100; 65 cout << "\n正确率:" << fixed << setprecision(2) << accuracy << "%\n"; 66 67 return 0; 68 }
运行结果截图:


浙公网安备 33010602011771号