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

实验任务1:

task1源代码:

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

运行测试截图:

task1

1.reverse 和 reverse_copy 有什么区别?
reverse是将自身反转,会改变自己的值;而reverse_copy会把反转后的值复制到另外一个字符串中而自身不变。
2.rotate 算法是如何改变元素顺序的?它的三个参数分别代表什么?
rotate是将元素循环左移和右移来改变元素顺序的,第一个参数是初始范围的起点,第二个参数是初始起点位移后的位置,+表示左移,-表示右移,第三个参数是初始范围的终点。
 
实验任务2:
task2源代码:
 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 {
19     std::srand(std::time(0));        //    添加随机种子
20     std::cout << "测试1:\n";
21     test1();
22     std::cout << "\n测试2:\n";
23     test2(); 
24 }
25 
26 //输出容器c中的元素
27 template<typename T>
28 void output(const T &c)
29 {
30     for(auto &i: c)
31         std::cout << i << ' ';
32     std::cout << '\n';
33 }
34 
35 //返回[0,100]区间内的一个随机整数
36 //int generate_random_number()
37 //{
38 //    return std::rand() % 101;
39 //} 
40 
41 //测试1:对容器类对象指定迭代器区间赋值、排序
42 void test1()
43 {
44     using namespace std;
45     
46     vector<int> v0(10);    //创建一个动态数组对象v0,对象大小为10
47     generate(v0.begin(),v0.end(),[](){return std::rand()%101;});     //生成随机整数填充v0
48     cout << "v0:";output(v0);
49     
50     vector<int> v1{v0};
51     sort(v1.begin(),v1.end());    //对整个vector排序
52     cout << "v1:";output(v1);
53     
54     vector<int> v2{v0};
55     sort(v2.begin()+1,v2.end()-1);    //只对中间部分排序,不包括首尾元素
56     cout << "v2:";output(v2); 
57 }
58  
59 //测试2:对容器类对象指定迭代器区间赋值、计算最大值/最小值/均值
60 void test2()
61 {
62     using namespace std;
63     
64     vector<int> v0(10);    //创建一个动态数组对象v0,对象大小为10
65     generate(v0.begin(),v0.end(),[](){return std::rand()%101;});     //生成随机整数填充v0
66     cout << "v0:";output(v0);
67     
68     //求最大值和最小值
69     auto min_iter = min_element(v0.begin(),v0.end());
70     auto max_iter = max_element(v0.begin(),v0.end());
71     cout << "最小值:" << *min_iter << endl;
72     cout << "最大值:" << *max_iter << endl;
73     
74     //同时求最大值和最小值
75     auto ans = minmax_element(v0.begin(),v0.end());
76     cout << "最小值:" << *(ans.first) << endl;
77     cout << "最大值:" << *(ans.second) << endl;
78     
79     //求平均值
80     double avg1 = accumulate(v0.begin(),v0.end(),0.0)/v0.size();
81     cout << "均值:" << fixed << setprecision(2) << avg1 << endl;
82     
83     sort(v0.begin(),v0.end());
84     double avg2 = accumulate(v0.begin()+1,v0.end()-1,0.0)/(v0.size()-2);
85     cout << "去掉最大值、最小值之后,均值:" << avg2 << endl;
86 }  
View Code

运行测试截图:

task2

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

generate的作用是给一个容器指定范围内进行赋值

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

只需要一行代码就可以求出最小值和最大值

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

效果一样,lamda表达式通常用于只用一次的情况,比较简洁。
 
实验任务3:
task3源代码:
 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 {
12     std::cout << "测试1:字符串大小写转换\n";
13     test1();
14     
15     std::cout << "\n测试2:字符变换\n";
16     test2();
17 }
18 
19 unsigned char func(unsigned char c)
20 {
21     if(c == 'z')
22         return 'a';
23         
24     if(c == 'Z')
25         return 'A';
26         
27     if(std::isalpha(c))
28         return static_cast<unsigned char>(c+1);
29         
30     return c;
31 }
32 
33 void test1()
34 {
35     std:: string s1{"Hello World 2049"};
36     std:: cout << "s1 = " << s1 << '\n';
37     
38     std:: string s2;
39     for(auto c: s1)
40         s2 += std:: tolower(c);
41     std:: cout << "s2 = " << s2 << '\n';
42     
43     std:: string s3;
44     for(auto c: s1)
45         s3 += std:: toupper(c);
46     std:: cout << "s3 = " << s3 << '\n';
47 }
48 
49 void test2()
50 {
51     std:: string s1{"I love cosmos!"};
52     std:: cout << "s1 = " << s1 << '\n';
53     
54     std:: string s2(s1.size(),' ');
55     std:: transform(s1.begin(),s1.end(),s2.begin(),func);
56     std:: cout << "s2 = " << s2 << '\n';
57 }
View Code

运行测试截图:

task3

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

将字符串中的英文字母变成下一个英文字母

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

tolower是将字符串中字母全变成小写,toupper是将字符串中字母全变成大写

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

第一个是原字符串的起始位置,第二个是原字符串的终止位置,第三个是复制到的字符串的起始位置,第四个是使用的变化方法,如果修改会使输出变为s2 = 后面没有原先修改之后的字符串了,因为是覆盖了原先的值而不是复制到s2上导致s2没有被赋值。

 

实验任务4:

 task4源代码:

 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     string s;
12 
13 // 多组输入,直到按下Ctrl+Z结束测试
14     while(cin >> s) 
15     {
16         cout << boolalpha
17         << "区分大小写: " << is_palindrome(s) << "\n"
18         << "不区分大小写: " << is_palindrome_ignore_case(s) << "\n\n";
19     }
20 }
21 
22 //区分大小写 
23 bool is_palindrome(const std::string &s)
24 {
25     for(int i=0;i<s.size()/2;i++)
26     {
27         int back=s.size()-i-1;
28         if(s[i]!=s[back])
29         {
30             return false;
31         }
32     }
33     return true;
34 }
35 
36 //不区分大小写 
37 bool is_palindrome_ignore_case(const std::string &s)
38 {
39     std:: string s1;
40     for(auto c: s)
41         s1 += std:: toupper(c);
42     for(int i=0;i<s1.size()/2;i++)
43     {
44         int back=s1.size()-i-1;
45         if(s1[i]!=s1[back])
46         {
47             return false;
48         }
49     }
50     return true;
51 }
View Code

运行测试截图:

task4

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

将原来的while(cin>>s)改为while(getline(cin,s)

 

实验任务5:

task5源代码:

 1 #include<iostream>
 2 #include<string>
 3 #include<algorithm>
 4 
 5 std::string dec2n(int x,int n=2);
 6 
 7 int main()
 8 {
 9     int x;
10     while(std::cin >> x)
11     {
12         std::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 std::string dec2n(int x,int n)
22 {
23     if(x == 0)
24     {
25         return "0";
26     }
27     
28     std::string s;
29     int t;
30     
31     while(x > 0)
32     {
33         t = x % n;
34         if(t >= 10)
35         {
36             s += static_cast<char>('A' + t - 10);
37         }
38         else
39         {
40             s += static_cast<char>(t + '0');
41         }
42         x = x / n;
43     }
44     std::reverse (s.begin(),s.end());
45     
46     return s;
47 }
View Code

运行测试截图:

task5

 

实验任务6:

task6源代码:

 1 #include<string>
 2 #include<iostream>
 3 #include<iomanip>
 4 
 5 int main()
 6 {
 7     std::cout << "   ";
 8     for(int i = 0; i < 26; i++)
 9     {
10         char c = static_cast<char>('a' + i);
11         std::cout << c << " ";
12     }
13     std::cout << "\n";
14     
15     for(int i = 1; i <= 26; i++)
16     {
17         char c1 = 'A' + i % 26;
18         std::cout << std::setw(2) << i << " ";
19         for(int j = 0; j < 26; j++)
20         {
21             char c2 = 'A' + (i + j) % 26;
22             std::cout << c2 << " ";
23         }
24         std::cout << "\n";
25     }
26     return 0;
27 }
View Code

运行测试截图:

task6

 

实验任务7:

 task7源代码:

 1 #include<iostream>
 2 #include<cstdlib>
 3 #include<ctime>
 4 #include<iomanip>
 5 
 6 int main()
 7 {
 8     //设置随机种子 
 9     std::srand(time(0));
10     
11     int correct = 0;
12     
13     for(int i = 0; i < 10; i++)
14     {
15         int number1 , number2 , result , answer , sign;
16         char c;
17         
18         number1 = rand() % 10 + 1;
19         number2 = rand() % 10 + 1;
20         sign = rand() % 4;
21         
22         switch(sign)
23         {
24             case 0:
25             //加法
26                 c = '+';
27                 result = number1 + number2;
28                 break;
29             
30             case 1:
31             //减法
32                 c = '-';
33                 if(number2 > number1)
34                     std::swap(number1 , number2);
35                 result = number1 - number2;
36                 break;
37             
38             case 2:
39             //乘法
40                 c = '*';
41                 result = number1 * number2;
42                 break;
43             
44             case 3:
45             //除法
46                 c = '/';
47                 while(number1 % number2 !=0)
48                 {
49                     number1 = rand() % 10 + 1;
50                     number2 = rand() % 10 + 1;
51                 } 
52                 result = number1 / number2;
53                 break;
54         }
55         
56         std::cout << number1 << " " << c << " " << number2 << " " << "= ";
57         std::cin >> answer;
58         
59         if(answer==result)
60         {
61             correct++;
62         }
63         std::cout << "\n";
64     }
65     
66     double accuracy = static_cast<double>(correct) / 10 * 100;
67     std::cout << "正确率: " << std::fixed << std::setprecision(2) << accuracy << "%" << "\n";
68     return 0;
69 }
View Code

运行测试截图:

task7_1

task7_2

 

实验总结:

以下为部分我写代码过程中踩的坑,因为部分函数比如cin,endl忘记写std::频繁报错,使用iomanip来完成数字对齐以及按规定格式输出,字符串通过加就能实现赋值,这是我的一个新的体验

 

posted @ 2025-10-16 13:14  王宝炜  阅读(14)  评论(1)    收藏  举报