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

实验任务1

task1.cpp

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

螢幕擷取畫面 2025-10-17 160222

reverse(反转):

  • 操作方式:直接在原容器上进行反转操作

  • 数据影响:会改变原始数据的顺序

  • 返回值:没有返回值(void)

  • 空间需求:不需要额外空间,在原地完成操作

  • 使用场景:当你确实需要反转原容器内容时使用

reverse_copy(反转拷贝):

  • 操作方式:将原容器的反转结果拷贝到另一个目标容器中

  • 数据影响:不会改变原始数据的顺序,原容器保持不变

  • 返回值:返回指向目标容器最后一个元素后面位置的迭代器

  • 空间需求:需要预先分配好大小的目标容器

  • 使用场景:当你需要保留原数据,同时获得反转副本时使用

三个参数的含义:

  1. first:指向要旋转区间开始位置的迭代器

  2. middle:指向要成为新序列第一个元素的迭代器(旋转的轴心点)

  3. last:指向要旋转区间结束位置的迭代器(最后一个元素的下一个位置)

工作方式:
rotate 算法将 [first, last) 区间内的元素看作一个环形,然后将这个环形旋转,使得原来在 middle 位置的元素移动到 first 位置,其他元素相应地循环移位。

 

 

 

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

螢幕擷取畫面 2025-10-17 161239

generate算法的主要作用是用指定的生成器函数填充容器的元素。

具体功能:

  • 遍历指定区间内的每个元素位置

  • 对每个位置调用生成器函数

  • 将生成器函数的返回值赋给该位置的元素

  • 完成对整个区间的填充

在需要同时查找最小值和最大值的情况下,minmax_element 在性能、代码简洁性和数据一致性方面都具有明显优势。

 

 

 

实验任务3

task3.cpp

 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     std::cout << "\n测试2: 字符变换\n";
14     test2();
15     return 0;
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     std::string s2;
35     for (auto c : s1)
36         s2 += static_cast<char>(std::tolower(c));
37     std::cout << "s2 = " << s2 << '\n';
38     std::string s3;
39     for (auto c : s1)
40         s3 += static_cast<char>(std::toupper(c));
41     std::cout << "s3 = " << s3 << '\n';
42 }
43 
44 void test2() {
45     std::string s1{ "I love cosmos!" };
46     std::cout << "s1 = " << s1 << '\n';
47 
48     std::string s2(s1.size(), ' ');
49     std::transform(s1.begin(), s1.end(),
50         s2.begin(),
51         func);
52     std::cout << "s2 = " << s2 << '\n';
53 }

螢幕擷取畫面 2025-10-17 161620

func 函数实现了一个简单的字符变换规则:

  1. 字母循环移位:

    • 小写字母:'a'→'b''b'→'c', ..., 'z'→'a'

    • 大写字母:'A'→'B''B'→'C', ..., 'Z'→'A'

  2. 特殊处理边界情况:

    • 'z' 转换为 'a'

    • 'Z' 转换为 'A'

  3. 非字母字符保持不变

tolower:

  • 功能:将字符转换为小写形式

  • 参数:接受一个字符(实际是int类型)

  • 返回值:对应的小写字符(int类型,需要转换)

toupper:

  • 功能:将字符转换为大写形式

  • 参数:接受一个字符(实际是int类型)

  • 返回值:对应的大写字符(int类型,需要转换)

  1. 第一个参数:s1.begin() - 输入序列的起始位置

  2. 第二个参数:s1.end() - 输入序列的结束位置(不包含)

  3. 第三个参数:s2.begin() - 输出序列的起始位置

  4. 第四个参数:func - 应用于每个元素的变换函数

关键区别:

  • 安全性:使用 s2.begin() 更安全,保留原始数据

  • 内存效率:使用 s1.begin() 更节省内存

 

 

 

实验任务4

task3.cpp

 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     // 多组输入,直到按下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 // 函数is_palindrome定义 - 区分大小写的回文检测
21 bool is_palindrome(const std::string& s) {
22     return std::equal(s.begin(), s.begin() + s.size() / 2, s.rbegin());
23 }
24 
25 // 函数is_palindrome_ignore_case定义 - 不区分大小写的回文检测
26 bool is_palindrome_ignore_case(const std::string& s) {
27     std::string lower_s;
28     // 转换为小写
29     std::transform(s.begin(), s.end(), std::back_inserter(lower_s),
30         [](unsigned char c) { return std::tolower(c); });
31     // 检测回文
32     return std::equal(lower_s.begin(), lower_s.begin() + lower_s.size() / 2,
33         lower_s.rbegin());
34 }

螢幕擷取畫面 2025-10-17 162230

主要调整:

  1. 使用 getline(cin, s) 替代 cin >> s

  2. 添加 cin.ignore() 清除输入缓冲区

  3. 添加空字符串检查 避免处理空输入

  4. 在输出中显示测试字符串 方便查看包含空格的输入

 

 

 

 实验任务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 
19 // 函数dec2n定义 - 将十进制数x转换为n进制字符串
20 std::string dec2n(int x, int n) {
21     // 处理特殊情况:0
22     if (x == 0) return "0";
23 
24     // 检查进制范围是否合法
25     if (n < 2 || n > 36) {
26         return "Invalid base";
27     }
28 
29     std::string result;
30     bool is_negative = false;
31 
32     // 处理负数
33     if (x < 0) {
34         is_negative = true;
35         x = -x;  // 转换为正数处理
36     }
37 
38     // 数字字符集,支持最高36进制
39     const char digits[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
40 
41     // 通过除n取余法进行进制转换
42     while (x > 0) {
43         int remainder = x % n;
44         result += digits[remainder];  // 将余数转换为对应字符
45         x /= n;
46     }
47 
48     // 反转字符串,因为我们是逆序添加的
49     std::reverse(result.begin(), result.end());
50 
51     // 如果是负数,添加负号
52     if (is_negative) {
53         result = "-" + result;
54     }
55 
56     return result;
57 }

螢幕擷取畫面 2025-10-17 162716

 

 

 

 

实验任务6

  1 #include <iostream>
  2 #include <string>
  3 #include <iomanip>
  4 
  5 void generate_caesar_cipher_table() {
  6     std::string alphabet = "abcdefghijklmnopqrstuvwxyz";
  7 
  8     std::cout << "凯撒密码完整对照表\n";
  9     std::cout << "==================\n\n";
 10 
 11     // 打印表头
 12     std::cout << std::setw(2) << "" << " ";
 13     for (char c : alphabet) {
 14         std::cout << c;
 15     }
 16     std::cout << "\n";
 17 
 18     // 生成每个移位量的密码表
 19     for (int shift = 1; shift <= 26; shift++) {
 20         std::cout << std::setw(2) << shift;
 21 
 22         std::string cipher_text;
 23         for (char c : alphabet) {
 24             // 凯撒密码移位计算
 25             char encrypted;
 26             if (c >= 'a' && c <= 'z') {
 27                 encrypted = 'a' + (c - 'a' + shift) % 26;
 28             }
 29             else {
 30                 encrypted = c; // 保持非字母字符不变
 31             }
 32             cipher_text += encrypted;
 33         }
 34 
 35         std::cout << cipher_text << "\n";
 36     }
 37 }
 38 
 39 void generate_caesar_cipher_table_uppercase() {
 40     std::string alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
 41 
 42     std::cout << "\n凯撒密码完整对照表 (大写字母)\n";
 43     std::cout << "==========================\n\n";
 44 
 45     // 打印表头
 46     std::cout << std::setw(2) << "" << " ";
 47     for (char c : alphabet) {
 48         std::cout << c;
 49     }
 50     std::cout << "\n";
 51 
 52     // 生成每个移位量的密码表
 53     for (int shift = 1; shift <= 26; shift++) {
 54         std::cout << std::setw(2) << shift;
 55 
 56         std::string cipher_text;
 57         for (char c : alphabet) {
 58             // 凯撒密码移位计算
 59             char encrypted;
 60             if (c >= 'A' && c <= 'Z') {
 61                 encrypted = 'A' + (c - 'A' + shift) % 26;
 62             }
 63             else {
 64                 encrypted = c; // 保持非字母字符不变
 65             }
 66             cipher_text += encrypted;
 67         }
 68 
 69         std::cout << cipher_text << "\n";
 70     }
 71 }
 72 
 73 // 交互式加密功能
 74 void interactive_caesar_cipher() {
 75     std::cout << "\n=== 交互式凯撒密码加密 ===\n";
 76 
 77     std::string text;
 78     int shift;
 79 
 80     std::cout << "请输入要加密的文本: ";
 81     std::cin.ignore(); // 清除输入缓冲区
 82     std::getline(std::cin, text);
 83 
 84     std::cout << "请输入移位量 (1-25): ";
 85     std::cin >> shift;
 86 
 87     if (shift < 1 || shift > 25) {
 88         std::cout << "移位量必须在 1-25 之间!\n";
 89         return;
 90     }
 91 
 92     std::string encrypted_text;
 93     for (char c : text) {
 94         if (c >= 'a' && c <= 'z') {
 95             // 小写字母
 96             encrypted_text += 'a' + (c - 'a' + shift) % 26;
 97         }
 98         else if (c >= 'A' && c <= 'Z') {
 99             // 大写字母
100             encrypted_text += 'A' + (c - 'A' + shift) % 26;
101         }
102         else {
103             // 非字母字符保持不变
104             encrypted_text += c;
105         }
106     }
107 
108     std::cout << "加密结果: " << encrypted_text << "\n";
109 
110     // 解密演示
111     std::string decrypted_text;
112     for (char c : encrypted_text) {
113         if (c >= 'a' && c <= 'z') {
114             decrypted_text += 'a' + (c - 'a' - shift + 26) % 26;
115         }
116         else if (c >= 'A' && c <= 'Z') {
117             decrypted_text += 'A' + (c - 'A' - shift + 26) % 26;
118         }
119         else {
120             decrypted_text += c;
121         }
122     }
123 
124     std::cout << "解密结果: " << decrypted_text << "\n";
125 }
126 
127 int main() {
128     int choice;
129 
130     do {
131         std::cout << "\n凯撒密码系统\n";
132         std::cout << "=============\n";
133         std::cout << "1. 显示小写字母凯撒密码表\n";
134         std::cout << "2. 显示大写字母凯撒密码表\n";
135         std::cout << "3. 交互式加密解密\n";
136         std::cout << "4. 退出\n";
137         std::cout << "请选择功能 (1-4): ";
138         std::cin >> choice;
139 
140         switch (choice) {
141         case 1:
142             generate_caesar_cipher_table();
143             break;
144         case 2:
145             generate_caesar_cipher_table_uppercase();
146             break;
147         case 3:
148             interactive_caesar_cipher();
149             break;
150         case 4:
151             std::cout << "程序结束,再见!\n";
152             break;
153         default:
154             std::cout << "无效选择,请重新输入!\n";
155         }
156     } while (choice != 4);
157 
158     return 0;
159 }

螢幕擷取畫面 2025-10-17 164356

 

 

 

 

实验任务7

  1 #include <iostream>
  2 #include <cstdlib>
  3 #include <ctime>
  4 #include <iomanip>
  5 #include <string>
  6 
  7 using namespace std;
  8 
  9 // 生成随机数 [min, max]
 10 int generate_random_number(int min, int max) {
 11     return rand() % (max - min + 1) + min;
 12 }
 13 
 14 // 生成加法题目
 15 void generate_addition(int& num1, int& num2, string& question) {
 16     num1 = generate_random_number(1, 10);
 17     num2 = generate_random_number(1, 10);
 18     question = to_string(num1) + " + " + to_string(num2) + " = ";
 19 }
 20 
 21 // 生成减法题目
 22 void generate_subtraction(int& num1, int& num2, string& question) {
 23     num1 = generate_random_number(1, 10);
 24     num2 = generate_random_number(1, num1);  // 确保num1 >= num2
 25     question = to_string(num1) + " - " + to_string(num2) + " = ";
 26 }
 27 
 28 // 生成乘法题目
 29 void generate_multiplication(int& num1, int& num2, string& question) {
 30     num1 = generate_random_number(1, 10);
 31     num2 = generate_random_number(1, 10);
 32     question = to_string(num1) + " × " + to_string(num2) + " = ";
 33 }
 34 
 35 // 生成除法题目
 36 void generate_division(int& num1, int& num2, string& question) {
 37     num2 = generate_random_number(1, 10);
 38     int result = generate_random_number(1, 10);
 39     num1 = num2 * result;  // 确保能整除
 40     question = to_string(num1) + " ÷ " + to_string(num2) + " = ";
 41 }
 42 
 43 int main() {
 44     // 设置随机种子
 45     srand(time(0));
 46 
 47     int correct_count = 0;
 48     const int total_questions = 10;
 49 
 50     cout << "小学生算术运算测试" << endl;
 51     cout << "==================" << endl;
 52 
 53     for (int i = 1; i <= total_questions; i++) {
 54         int num1, num2, correct_answer, user_answer;
 55         string question;
 56 
 57         // 随机选择运算类型 (0:加法, 1:减法, 2:乘法, 3:除法)
 58         int operation_type = rand() % 4;
 59 
 60         switch (operation_type) {
 61         case 0:  // 加法
 62             generate_addition(num1, num2, question);
 63             correct_answer = num1 + num2;
 64             break;
 65         case 1:  // 减法
 66             generate_subtraction(num1, num2, question);
 67             correct_answer = num1 - num2;
 68             break;
 69         case 2:  // 乘法
 70             generate_multiplication(num1, num2, question);
 71             correct_answer = num1 * num2;
 72             break;
 73         case 3:  // 除法
 74             generate_division(num1, num2, question);
 75             correct_answer = num1 / num2;
 76             break;
 77         }
 78 
 79         // 显示题目并获取用户答案
 80         cout << "" << i << "题: " << question;
 81         cin >> user_answer;
 82 
 83         // 检查答案
 84         if (user_answer == correct_answer) {
 85             cout << "正确!" << endl;
 86             correct_count++;
 87         }
 88         else {
 89             cout << "错误!正确答案是: " << correct_answer << endl;
 90         }
 91         cout << endl;
 92     }
 93 
 94     // 计算并显示正确率
 95     double accuracy = (static_cast<double>(correct_count) / total_questions) * 100;
 96     cout << "测试结束!" << endl;
 97     cout << "你答对了 " << correct_count << " 道题,共 " << total_questions << " 道题" << endl;
 98     cout << fixed << setprecision(2);
 99     cout << "正确率: " << accuracy << "%" << endl;
100 
101     return 0;
102 }

螢幕擷取畫面 2025-10-17 164954

 

posted @ 2025-10-17 16:51  ToffeeMa  阅读(8)  评论(1)    收藏  举报