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

任务一:

源代码

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

运行结果:

屏幕截图 2025-10-11 170423

问题:

(1)reverse:原地反转,直接修改原容器. reverse(v.begin(), v.end() ),v 本身被反转。

     reverse_copy:拷贝反转,原容器不变,结果存到另一个容器。 reverse_copy(v.begin(), v.end() ,result.begin() ),v 不变,result 是反转后的副本。

 

任务二:

源代码:

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

运行结果:屏幕截图 2025-10-11 171058

问题:

(1)generate:用指定的生成器函数(或函数对象)的结果,填充一个范围内的所有元素

 (2)minmax_element 的优势

效率更高:只需一次遍历就能同时找到最小和最大值。

保证一致性:返回的迭代器指向的是同一时刻容器中的最小和最大值(对于可能变化的容器很重要)。

(3)等同. 优势:

  1. 简单逻辑 - 一次性使用,代码更紧凑

  2. 需要外部变量 - 直接捕获,不用改函数参数

  3. 保持状态 - 通过引用捕获维护状态

  4. 内联定义 - 逻辑直接可见,不用跳转查看函数定义

任务三:

 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 }

运行结果:

屏幕截图 2025-10-11 171250

问题:

(1)func函数功能:字母循环后移一位

(2)tolower:大写字母转小写,其他字符不变

   toupper:小写字母转大写,其他字符不变

(3)s1.begin() - 输入范围起点

   s1.end() - 输入范围终点

    s2.begin() - 输出位置起点

   func-转换函数

(4)结果会直接覆盖s1的内容,s2无效

 

任务四:

源代码:

 1 #include <iostream>
 2 #include <string>
 3 #include <algorithm>
 4 #include <cctype>
 5 
 6 bool is_palindrome(const std::string &s);
 7 bool is_palindrome_ignore_case(const std::string &s);
 8 
 9 int main() {
10     using namespace std;
11     string s;
12 
13     // 多组输入,直到按下Ctrl+Z结束测试
14     while(cin >> s) {
15         cout << boolalpha 
16              << "区分大小写: " << is_palindrome(s) << "\n"
17              << "不区分大小写: " << is_palindrome_ignore_case(s) << "\n\n";
18     }     
19 }
20 
21 // 严格区分大小写的回文判断
22 bool is_palindrome(const std::string &s) {
23     int left = 0;
24     int right = s.length() - 1;
25     
26     while (left < right) {
27         if (s[left] != s[right]) {
28             return false;
29         }
30         left++;
31         right--;
32     }
33     return true;
34 }
35 
36 // 不区分大小写的回文判断
37 bool is_palindrome_ignore_case(const std::string &s) {
38     int left = 0;
39     int right = s.length() - 1;
40     
41     while (left < right) {
42         // 转换为小写后比较
43         if (std::tolower(s[left]) != std::tolower(s[right])) {
44             return false;
45         }
46         left++;
47         right--;
48     }
49     return true;
50 }

运行结果:

屏幕截图 2025-10-11 173411

问题:

用std::getline()代替cin>>s

任务五:

源代码:

 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 
20 // 十进制转n进制函数(x >= 0, 2 <= n <= 36)
21 std::string dec2n(int x, int n) {
22     if (x == 0) return "0";
23     
24     std::string result;
25     const char digits[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
26     
27     // 不断除以n取余数
28     while (x > 0) {
29         int remainder = x % n;
30         result += digits[remainder];
31         x /= n;
32     }
33     
34     std::reverse(result.begin(), result.end());
35     
36     return result;
37 }

运行结果:

屏幕截图 2025-10-11 234322

 

任务六:

源代码:

 1 #include <iostream>
 2  #include <string>
 3  #include <vector>
 4  #include <algorithm>
 5 using namespace std;
 6 template <typename T>
 7 void output(const T &c){
 8     for(auto &i:c)
 9         cout<<i<<" ";
10     cout<<endl;
11 }
12 int main(){
13     vector <char> m{'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'} ;
14     cout<<"  ";output(m);
15     vector <char> v{'B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','A'};
16     cout<<1<<" ";output(v);
17     for(int i=2;i<=26;i++){
18     rotate(v.begin(),v.begin()+1,v.end());
19     cout<<i<<" ";output(v);
20 }
21 return 0; 
22 }

运行结果:

屏幕截图 2025-10-11 232706

任务七:

 1 #include <iostream>
 2 #include <ctime>
 3 using namespace std;
 4 
 5 // 检查题目
 6 bool check(int op) {
 7     int a, b;
 8     char opChar;
 9     int ans;
10     int user;
11     
12     switch (op) {
13         case 0: // 加法
14             a = rand() % 10 + 1;
15             b = rand() % 10 + 1;
16             opChar = '+';
17             ans = a + b;
18             break;
19             
20         case 1: // 减法
21             b = rand() % 10 + 1;
22             a = rand() % (10 - b + 1) + b;
23             opChar = '-';
24             ans = a - b;
25             break;
26             
27         case 2: // 乘法
28             a = rand() % 10 + 1;
29             b = rand() % 10 + 1;
30             opChar = '*';
31             ans = a * b;
32             break;
33             
34         case 3: // 除法
35             do {
36                 b = rand() % 10 + 1;
37                 a = rand() % 10 + 1;
38             } while (a % b != 0 || a / b > 10);
39             opChar = '/';
40             ans = a / b;
41             break;
42     }
43     
44     cout << a << " " << opChar << " " << b << " = ";
45     cin >> user;
46     
47     return user == ans;
48 }
49 
50 // 计算正确率
51 double rate(int correct, int total) {
52     return (correct * 100.0) / total;
53 }
54 
55 int main() {
56     srand(time(0));  // 使用时间作为随机种子,确保每次运行题目不同
57     
58     int correct = 0;
59     const int total = 10;
60     
61     for (int i = 0; i < total; i++) {
62         int op = rand() % 4;
63         
64         if (check(op)) {
65             correct++;
66         }
67     }
68     
69     double accuracy = rate(correct, total);
70     cout << "\n正确率:" << accuracy << "%" << endl;
71     
72     return 0;
73 }

运行结果:

屏幕截图 2025-10-12 230549

 

posted @ 2025-10-12 23:24  南方之木  阅读(12)  评论(1)    收藏  举报