当前位置: 首页 > news >正文

实验1 现代C++编程初体验

任务1:

源代码

 1 #include <iostream>
 2 #include <string>
 3 #include <vector>
 4 #include <algorithm>
 5 template<typename T>
 6 void output(const T &c);
 7 
 8 void test1();
 9 void test2();
10 void test3();
11 
12 int main() {
13     std::cout << "测试1: \n";
14     test1();
15 
16     std::cout << "\n测试2: \n";
17     test2();
18 
19     std::cout << "\n测试3: \n";
20     test3();
21 }
22 
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 void test1() {
30     using namespace std;
31 
32     string s0{"0123456789"};
33     cout << "s0 = " << s0 << endl;
34 
35     string s1(s0);
36     reverse(s1.begin(), s1.end());  
37     cout << "s1 = " << s1 << endl;
38 
39     string s2(s0.size(), ' ');
40     reverse_copy(s0.begin(), s0.end(), s2.begin()); 
41     cout << "s2 = " << s2 << endl;
42 }
43 
44 
45 void test2() {
46     using namespace std;
47 
48     vector<int> v0{2, 0, 4, 9};
49     cout << "v0: "; output(v0);
50 
51     vector<int> v1{v0};
52     reverse(v1.begin(), v1.end());
53     cout << "v1: "; output(v1);
54 
55     vector<int> v2{v0};
56     reverse_copy(v0.begin(), v0.end(), v2.begin());
57     cout << "v2: "; output(v2);
58 }
59 
60 
61 void test3() {
62     using namespace std;
63 
64     vector<int> v0{0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
65     cout << "v0: "; output(v0);
66 
67     vector<int> v1{v0};
68     rotate(v1.begin(), v1.begin()+1, v1.end());  
69     cout << "v1: "; output(v1);
70 
71     vector<int> v2{v0}; 
72     rotate(v2.begin(), v2.begin()+2, v2.end());  
73     cout << "v2: "; output(v2);
74 
75     vector<int> v3{v0};
76     rotate(v3.begin(), v3.end()-1, v3.end()); 
77      cout << "v3: "; output(v3);
78 
79     vector<int> v4{v0};
80     rotate(v4.begin(), v4.end()-2, v4.end()); 
81     cout << "v4: "; output(v4);
82 }
任务1

运行结果截图:

任务1

回答问题:

问题1: reverse 和 reverse_copy 有什么区别? 问题2: rotate 算法是如何改变元素顺序的?它的三个参数分别代表什么?

1.reverse和reverse_copy的区别在于reverse是直接反转原来元素的顺序,而reverse_copy相当于建立一个副本,在副本上反转原来的元素顺序,不修改原始数据。
2.rotate算法工作原理:rotate执行循环左移的操作,使得元素n_first成为新的第一个元素,n_first之前的元素移动到末尾。即:先将序列分成两部分[first,n_first)和[n_first,last)两部分,然后再交换两部分的位置。
三个参数的含义:first:范围起始位置;n_first:要旋转到起始位置的元素;last:范围结束位置

任务2:

源代码:

 1 #include <iostream>
 2 #include <vector>
 3 #include <algorithm>
 4 #include <numeric>
 5 #include <iomanip>
 6 #include <cstdlib>
 7 #include <ctime>
 8 template<typename T>
 9 void output(const T &c);
10 
11 int generate_random_number();
12 void test1();
13 void test2();
14 
15 int main() {
16     std::srand(std::time(0));   
17     std::cout << "测试1: \n";
18     test1();
19 
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 
38     vector<int> v0(10); 
39     generate(v0.begin(), v0.end(), generate_random_number); 
40     cout << "v0: "; output(v0);
41 
42     vector<int> v1{v0};
43     sort(v1.begin(), v1.end());
44     cout << "v1: "; output(v1);
45 
46     vector<int> v2{v0};
47     sort(v2.begin()+1, v2.end()-1); 
48     cout << "v2: "; output(v2);
49 }
50 
51 
52 void test2() {
53     using namespace std;
54 
55     vector<int> v0(10);  
56     generate(v0.begin(), v0.end(), generate_random_number); 
57     cout << "v0: "; output(v0);
58     auto min_iter = min_element(v0.begin(), v0.end());
59     auto max_iter = max_element(v0.begin(), v0.end());
60     cout << "最小值: " << *min_iter << endl;
61     cout << "最大值: " << *max_iter << endl;
62     auto ans = minmax_element(v0.begin(), v0.end());
63     cout << "最小值: " << *(ans.first) << endl;
64     cout << "最大值: " << *(ans.second) << endl;
65     double avg1 = accumulate(v0.begin(), v0.end(), 0.0) / v0.size();
66     cout << "均值: " << fixed << setprecision(2) << avg1 << endl;
67     sort(v0.begin(), v0.end());
68     double avg2 = accumulate(v0.begin()+1, v0.end()-1, 0.0) / (v0.size()-2);
69     cout << "去掉最大值、最小值之后,均值: " << avg2 << endl;
70 }
任务2

运行结果截图:

任务2

回答问题:

问题1: generate 算法的作用是什么? 问题2: minmax_element 和分别调用 min_element 、 max_element 相比,有什么优势? 问题3:把代码中函数 generate_random_number 的声明(line13)和定义(line35-37)注释起来,把两处调用改成如下写法,观察效果是否等同?lambda表达式适用场景是什么?

1.general算法的作用是将给定的函数对象所生成的值赋值给范围[first,last)中的每个元素,该任务代码中使用generate_random_number函数生成的随机数填充v0中的每个元素。
2.优势在于minmax element只需要遍历一次,时间复杂度更低,而且一行代码即可完成。
3.效果相同,都会用0-100的随机数填充容器;lambda的适用场景有替代简单的函数对象、简化测试代码、函数逻辑较为简单时可用。

任务3:

源代码:

 1 #include <iostream>
 2 #include <string>
 3 #include <algorithm>
 4 #include <cctype>
 5 
 6 unsigned char func(unsigned char c);
 7 void test1();
 8 void test2();
 9 
10 int main() {
11     std::cout << "测试1: 字符串大小写转换\n";
12     test1();
13 
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     
50     std::string s2(s1.size(), ' ');
51     std::transform(s1.begin(), s1.end(),
52                    s2.begin(),
53                    func);
54     std::cout << "s2 = " << s2 << '\n';
55 }
任务3

运行结果截图:

任务3

回答问题:

问题1:自定义函数 func 功能是什么? 问题2: tolower 和 toupper 功能分别是什么? 问题3: transform 的4个参数意义分别是什么?如果把第3个参数 s2.begin() 改成 s1.begin() ,有何区别?

1.func函数的功能是字母表循环后向下一个字母移动,可以将每个字母替换成字母表中的下一个字母。
2.tolower的功能是将字符转换为小写形式;toupper的功能是将字符转换为大写形式。
3.四个参数的意义:first1:输入范围的开始值
last1:输入范围的结束值
d_first:输出范围的开始值
unary_op:操作函数
区别在于:如果使用s2.begin():不是在原基础上操作,原始数据仍被保留,而s1.begin()在原基础上操作,会修改原始数据

任务4:

源代码:

 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     while(cin >> s) {
12         cout << boolalpha 
13              << "区分大小写: " << is_palindrome(s) << "\n"
14              << "不区分大小写: " << is_palindrome_ignore_case(s) << "\n\n";
15     }     
16 }
17 
18 bool is_palindrome(const std::string &s) {
19     int left = 0;
20     int right = s.length() - 1;
21     
22     while (left < right) {
23         if (s[left] != s[right]) {
24             return false;
25         }
26         left++;
27         right--;
28     }
29     return true;
30 }
31 
32 bool is_palindrome_ignore_case(const std::string &s) {
33     int left = 0;
34     int right = s.length() - 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

运行结果截图:

任务4

回答问题:

问题:使用 cin >> s 输入时,输入的字符串中不能包含空格。如果希望测试字符串包含空格(如 hello oop ),代码应如何调整?

如果要测试包含空格的字符串,可以使用 std::getline(cin, s) 代替 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 
19 std::string dec2n(int x, int n) {
20     if (x == 0) {
21         return "0";
22     }
23     if (n < 2 || n > 36) {
24         return "Error";
25     }
26     std::string result = "";
27     int num = x;  
28     while (num > 0) {
29         int remainder = num % n;  
30         num = num / n;          
31         if (remainder < 10) {
32             result += '0' + remainder;
33         } else {
34             result += 'A' + (remainder - 10);
35         }
36     }
37     std::reverse(result.begin(), result.end());
38     
39     return result;
40 }
任务5

运行结果截图:

任务5

任务6:

源代码:

 1 #include <iostream>
 2 #include <string>
 3 #include <algorithm>
 4 #include <cctype>
 5 using namespace std; 
 6 void test1();  // 打印原始字母表
 7 void test2();  // 打印移位字母表
 8 string shiftAlphabet(const std::string& alphabet, int shift);
 9 
10 int main() {
11     cout << "字母密文对照表:\n\n";
12     
13     test1();
14     test2();
15     
16     return 0;
17 }
18 
19 void test1() {
20     string alphabet = "abcdefghijklmnopqrstuvwxyz";
21     cout << alphabet << endl;
22 }
23 
24 void test2() {
25     string alphabet = "abcdefghijklmnopqrstuvwxyz";
26     
27     for (int i = 1; i <= 26; ++i) {
28         string shifted = alphabet;
29         rotate(shifted.begin(), shifted.begin() + i, shifted.end());
30         transform(shifted.begin(), shifted.end(), shifted.begin(), ::toupper);
31         
32         cout << i << shifted << endl;
33     }
34 }
任务6

运行结果截图:

任务6

任务7:

源代码:

 1 #include <iostream>
 2 #include <cstdlib>
 3 #include <ctime>
 4 #include <iomanip>
 5 #include <string>
 6 using namespace std; 
 7 int main() {
 8     srand(time(0));
 9     int correctCount = 0; 
10     for (int i = 0; i < 10; ++i) {
11         int num1 = rand() % 10 + 1;
12         int num2 = rand() % 10 + 1;
13         int a = rand() % 4;
14         char operator_a;
15         int correctAnswer;
16         switch (a) {
17             case 0: 
18                 operator_a = '+';
19                 correctAnswer = num1 + num2;
20                 break;
21                 
22             case 1:
23                 if (num1 < num2) {
24                     swap(num1, num2);
25                 }
26                 operator_a = '-';
27                 correctAnswer = num1 - num2;
28                 break;
29                 
30             case 2: 
31                 operator_a = '*';
32                 correctAnswer = num1 * num2;
33                 break;
34                 
35             case 3: 
36                 if (num1 < num2) {
37                     swap(num1, num2);
38                 }
39                 if (num2 > 1) {
40                     int maxMultiple = 10 / num2;
41                     if (maxMultiple > 0) {
42                         num1 = num2 * (rand() % maxMultiple + 1);
43                     } else {
44                         num1 = num2; 
45                     }
46                 }
47                 operator_a = '/';
48                 correctAnswer = num1 / num2;
49                 break;
50         }
51 
52         cout << num1 << " " << operator_a << " " << num2 << " = ";
53         int userAnswer;
54         cin >> userAnswer;
55 
56         if (userAnswer == correctAnswer) {
57             correctCount++;
58         }
59     }
60 
61     double accuracy = (static_cast<double>(correctCount) / 10) * 100;
62     cout << "\n正确率:" << fixed << setprecision(2) << accuracy << "%" << endl;
63     
64     return 0;
65 }
任务7

运行结果截图:

任务7

 

实验总结:
1收获: 1)学会了使用迭代器进行容器遍历和算法操作
2)新学习到了tolower的功能是将字符转换为小写形式;toupper的功能是将字符转换为大写形式。
3) 新学习到了general的算法:作用是将给定的函数对象所生成的值赋值给范围[first,last)中的每个元素,该任务代码中使用generate_random_number函数生成的随机数填充v0中的每个元素。
2.我的感受:1)成就感:从最初对C++的陌生到能够效仿前几个任务完成回文判断、进制转换等任务的代码书写,让我体会到了亲手敲代码比复制粘贴更能加深理解,而且在调试过程中发现的错误也能及时帮助巩固一些知识点。
2) 挑战性:理解算法原理和模板机制时需要花费大量时间反复思考和实验

 

http://www.hskmm.com/?act=detail&tid=29031

相关文章:

  • 10.11总结
  • 2025年10月门窗十大品牌最新推荐榜单,十大品牌测评排名与选择指南
  • CF60E Mushroom Gnomes
  • CF691E Xor-sequences
  • LCPC12E - Johnnys Empire 题解
  • 中微笔记-cp.1 技术
  • P1896 [SCOI2005] 互不侵犯小总结
  • 美国能源部《生成式人工智能参考指南》解读
  • 分析InfluxDB中读取时CPU飙升
  • win10系统访问smb服务时提示密码错误
  • 《小说课》读书笔记
  • 2025-10-11?
  • 高二停课周记(信息学竞赛) Week1
  • AtCoder Beginner Contest 427 ABCDEF 题目解析
  • zju博士资格考试考前复习(微分方程方向)ode 部分
  • 测试一下博客功能
  • AI如何改变芯片设计
  • NOIP 2024
  • 2025/10/11
  • 好玩热门的switch游戏推荐【PC+安卓】塞尔达传说:王国之泪|v1.4.2整合版|官方中文| 附switch模拟器
  • 十年运维工程师总结
  • 运动控制教学——5分钟学会Dijkstra与A*搜索算法!(附仿真视频及代码) - 教程
  • ffplay数据结构解析
  • CNN 发展历程
  • FileX和ThreadX精简版
  • ue4素材场景 - MKT
  • 阅读《构建之法》的思考与问题
  • 实验报告5(链栈基本操作,数制转换,匹配算法,伴舞问题)
  • 阅读和提问作业1:《构建之法》提问
  • 企业推行OKR中层领导关注的10个关键问题及解决方案