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

任务一:

源代码task1.cpp

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

运行结果图:

屏幕截图 2025-10-17 215444

观察与思考:

1. reverse 和 reverse_copy 有什么区别?

   ①reverse是改变原始序列,将数组指定范围的元素顺序调转

   ②reverse_copy是将原始序列指定范围的元素顺序调转 并 存储到指定序列位置后,不改变原始序列

2. rotate 算法是如何改变元素顺序的?它的三个参数分别代表什么?

  ①rotate 算法通过“左旋转”改变元素顺序:将 [first, middle) 范围内的元素移到 [middle, last) 之后,形成 [middle, last) + [first, middle) 的新顺序。

  ②三个参数: first:序列起始迭代器(包含)  middle:旋转点迭代器(以此为界分割元素) last:序列结束迭代器(不包含)

 

任务二:

源代码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 
11 void output(const T &c);
12 int generate_random_number();
13 void test1();
14 void test2();
15 
16 int main()
17 {
18     std::srand(std::time(0)); // 添加随机种子
19     
20     std::cout << "测试1: \n";
21     test1();
22     
23     std::cout << "\n测试2: \n";
24     test2();
25 }
26 
27 // 输出容器对象c中的元素
28 template <typename T>
29 
30 void output(const T &c) 
31 {
32     for(auto &i: c)
33         std::cout << i << ' ';
34     std::cout << '\n';
35 }
36 
37 // 返回[0, 100]区间内的一个随机整数
38 int generate_random_number() 
39 {
40     return std::rand() % 101;
41 }
42 
43 // 测试1:对容器类对象指定迭代器区间赋值、排序
44 void test1() 
45 {
46     using namespace std;
47     
48     vector<int> v0(10); // 创建一个动态数组对象v0, 对象大小为10
49     generate(v0.begin(), v0.end(), generate_random_number); // 生成随机数填充v0
50     cout << "v0: "; output(v0);
51     
52     vector<int> v1{v0};
53     sort(v1.begin(), v1.end()); // 对整个vector排序
54     cout << "v1: "; output(v1);
55     
56     vector<int> v2{v0};
57     sort(v2.begin()+1, v2.end()-1); // 只对中间部分排序,不包含首尾元素
58     cout << "v2: "; output(v2);
59 }
60 
61 // 测试2:对容器类对象指定迭代器区间赋值、计算最大值/最小值/均值
62 void test2()
63 {
64     using namespace std;
65     
66     vector<int> v0(10);
67     generate(v0.begin(), v0.end(), generate_random_number);
68     cout << "v0: "; output(v0);
69     
70     // 求最大值和最小值
71     auto min_iter = min_element(v0.begin(), v0.end());
72     auto max_iter = max_element(v0.begin(), v0.end());
73     cout << "最小值: " << *min_iter << endl;
74     cout << "最大值: " << *max_iter << endl;
75     
76     // 同时求最大值和最小值
77     auto ans = minmax_element(v0.begin(), v0.end());
78     cout << "最小值: " << *(ans.first) << endl;
79     cout << "最大值: " << *(ans.second) << endl;
80     
81     // 求平均值
82     double avg1 = accumulate(v0.begin(), v0.end(), 0.0) / v0.size();
83     cout << "均值: " << fixed << setprecision(2) << avg1 << endl;
84     sort(v0.begin(), v0.end());
85     
86     double avg2 = accumulate(v0.begin()+1, v0.end()-1, 0.0) / (v0.size()-2);
87     cout << "去掉最大值、最小值之后,均值: " << avg2 << endl;
88 }

运行结果图:

image

 

观察与思考:

1. generate 算法的作用是什么?

  通过调用一个函数生成值(源代码中的generate_random_number()),为指定范围(源代码中v0.begin(), v0.end())内的元素逐一赋值。

2. minmax_element和分别调用min_element、max_element相比,有什么优势?

  前者一次遍历即可同时获取最大和最小值,比分别调用后者效率更高。

3. 把代码中函数generate_random_number的声明(line13)和定义(line35-37)注释起来,把两处调用改成如下写法,观察效果是否等同?查阅c++中lambda表达式用法。

  效果等同,但是lambda 表达式是匿名函数,可以直接定义在代码中,简洁方便。

 

任务三:

源代码task3:

 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 {
13     std::cout << "测试1: 字符串大小写转换\n";
14     test1();
15 
16     std::cout << "\n测试2: 字符变换\n";
17     test2();
18 }
19 
20 unsigned char func(unsigned char c) 
21 {
22     if(c == 'z')return 'a';
23     if(c == 'Z')return 'A';
24     if(std::isalpha(c))
25         return static_cast<unsigned char>(c+1);
26     return c;
27 }
28 
29 void test1() 
30 {
31     std::string s1{"Hello World 2049!"};
32     std::cout << "s1 = " << s1 << '\n';
33 
34     std::string s2;
35 
36     for(auto c: s1)
37         s2 += std::tolower(c);
38     std::cout << "s2 = " << s2 << '\n';
39 
40     std::string s3;
41 
42     for(auto c: s1)
43         s3 += std::toupper(c);
44     std::cout << "s3 = " << s3 << '\n';
45 }
46 
47 void test2() 
48 {
49     using namespace std;
50     
51     string s1{"I love cosmos!"};
52     cout << "s1 = " << s1 << '\n';
53 
54     string s2(s1.size(), ' ');
55     transform(s1.begin(), s1.end(),s2.begin(),func);
56     cout << "s2 = " << s2 << '\n';
57 }

运行结果图:

image

 

观察与思考:

1. 自定义函数func功能是什么?

  将指定元素字母转换成下一个字母,当到达'z''Z'时返回到'a''A'。

2. tolower和toupper功能分别是什么?

  ①tolower 将序列中所有的字母元素全部转换成小写字母

  ②toupper 将序列中所有的字母元素全部转换成大写字母

3. transform的4个参数意义分别是什么?如果把第3个参数s2.begin()改成s1.begin(),有何区别?

  参数含义: ①s1.begin()代表转换操作的起始迭代器

    ②s1.end()代表转换操作的结束迭代器(不包含)

    ③s2.begin()代表输出序列的起始迭代器

    ④func 是对于输入范围内的元素的处理操作函数

  会直接赋值到s1本身,改变原始序列。

 

任务四:

源代码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 {
10     using namespace std;
11     
12     string s;
13     while(cin>>s)
14     {
15         cout<<boolalpha
16             << "区分大小写: " << is_palindrome(s) << "\n"
17             << "不区分大小写: " << is_palindrome_ignore_case(s) 
18             << "\n\n";
19     }
20 }
21 
22 bool is_palindrome(const std::string &s)
23 {
24     using namespace std;
25     
26     string s1(s.size(),' ');
27     reverse_copy(s.begin(),s.end(),s1.begin());
28     
29     if(s==s1)return true;
30     else return false;
31 }
32 
33 bool is_palindrome_ignore_case(const std::string &s)
34 {
35     using namespace std;
36     
37     string s1;
38     for(auto c:s)
39         s1+=toupper(c);
40         
41     string s2(s.size(),' ');
42     reverse_copy(s1.begin(),s1.end(),s2.begin());
43     
44     if(s1==s2)return true;
45     else return false;
46 }

运行结果截图:

image

 

观察与思考:

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

  使用getline(cin,s)代替cin>>s。

 

任务五:

源代码task5.cpp

 1 #include <iostream>
 2 #include <string>
 3 #include <algorithm>
 4 using namespace std;
 5 
 6 string dec2n(int x, int n = 2);
 7 
 8 int main() 
 9 {
10     int x;
11     while(cin >> x) {
12     cout << "十进制: " << x << '\n'
13         << "二进制: " << dec2n(x) << '\n'
14         << "八进制: " << dec2n(x, 8) << '\n'
15         << "十二进制: " << dec2n(x, 12) << '\n'
16         << "十六进制: " << dec2n(x, 16) << '\n'
17         << "三十二进制: " << dec2n(x, 32) << "\n\n"; 
18     }
19 }
20 
21 string dec2n(int x, int n )
22 {
23     string result;
24     int t;
25     
26     if(x==0)return "0";
27     
28     while(x>0)
29     {
30         t=x%n;
31         if(t<=9) result+=char(t+'0');
32         else 
33             result+=char('A'+t-10);
34         x=x/n;
35     }
36     reverse(result.begin(),result.end());
37     
38     return result;
39 }

运行结果截图:

image

任务六:

源代码task6.cpp

 1 #include <iostream>
 2 #include <string>
 3 #include <algorithm>
 4 #include <vector>
 5 using namespace std;
 6 
 7 int main() 
 8 {
 9     vector<char> s0{'a','b','c','d','e','f','g','h','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'};
10     cout<<' '<<' ';
11     
12     for(auto ch:s0)
13         cout<<' '<<ch;
14     cout<<endl;
15     
16     int i=1;
17     for(auto &c:s0)
18         c=(char)toupper(c);
19         
20     while(i<=26)
21     {
22         if(i<=9)    cout<<' ';
23         cout<<i<<' ';
24         rotate(s0.begin(),s0.begin()+1,s0.end());
25         for(auto ch : s0)
26             cout<<ch<<' ';
27            cout<<endl;
28         i++;
29     }
30     return 0;
31 }

 

运行结果截图:

image

 

任务七:

源代码task7.cpp

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

 

 运行结果截图:

imageimage

 实验总结:

1.学会了如reverse generate rotate等算法高效处理数据元素,提升效率,增强代码可读性。

2.巩固了vector 等已经学过的知识,通过撰写代码提升了逻辑思维能力和编写代码能力。

 

posted @ 2025-10-18 01:51  zxy22213  阅读(10)  评论(1)    收藏  举报