实验1

实验任务1:

源代码:

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

运行结果:

屏幕截图 2025-10-12 215725

问题1:reverse 和 reverse_copy 有什么区别?

 答:     reverse是将字符串原地反转,会修改原容器内容;

             reverse_copy是将字符串反转后复制到另外一个容器中,不会对原容器产生改变。

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

 答:     rotate是将元素进行循环旋转,将第一个参数和第二个参数之间的数据(包含第一个参数所代表的数据)依次移到第三个参数所代表的数据后面。

             第一个参数:旋转范围的起始位置

             第二个参数:旋转后的第一个元素的位置

             第三个参数:旋转范围的末尾元素的后一个位置

 

实验任务2:

源代码:

 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 void output(const T &c);
11 
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     std::cout << "\n测试2: \n";
21     test2();
22 }
23 
24 template <typename T>
25 
26 void output(const T &c) {
27     for(auto &i: c)
28     std::cout << i << ' ';
29     std::cout << '\n';
30 }
31 
32 int generate_random_number() {
33     return std::rand() % 101;
34 }
35 
36 void test1() {
37     using namespace std;
38     vector<int> v0(10); 
39     generate(v0.begin(), v0.end(), generate_random_number); 
40     cout << "v0: "; output(v0);
41     vector<int> v1{v0};
42     sort(v1.begin(), v1.end()); 
43     cout << "v1: "; output(v1);
44     vector<int> v2{v0};
45     sort(v2.begin()+1, v2.end()-1); 
46     cout << "v2: "; output(v2);
47 }
48 
49 void test2() {
50     using namespace std;
51     vector<int> v0(10);
52     generate(v0.begin(), v0.end(), generate_random_number);
53     cout << "v0: "; output(v0);
54 
55     auto min_iter = min_element(v0.begin(), v0.end());
56     auto max_iter = max_element(v0.begin(), v0.end());
57     cout << "最小值: " << *min_iter << endl;
58     cout << "最大值: " << *max_iter << endl;
59 
60     auto ans = minmax_element(v0.begin(), v0.end());
61     cout << "最小值: " << *(ans.first) << endl;
62     cout << "最大值: " << *(ans.second) << endl;
63     
64     double avg1 = accumulate(v0.begin(), v0.end(), 0.0) / v0.size();
65     cout << "均值: " << fixed << setprecision(2) << avg1 << endl;
66     
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 }

运行结果:
屏幕截图 2025-10-12 224916

问题1:generate 算法的作用是什么?

 答:    将generate_random_number生成的随机数依次赋值给容器中每一个元素。

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

 答:    minmax_element 只需要遍历一次就能找到最大最小值,而min_element 、 max_element 共需要遍历两次; minmax_element能减少遍历的开销,且代码行数减少,更简洁

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

             

1 // test1()模块和test2()模块:
2 generate(v0.begin(), v0.end(), generate_random_number);
3 ---->改成
4 generate(v0.begin(), v0.end(), [](){return std::rand()%101;});

 答:   效果等同;

           lambda适用于代码简洁的函数中,可以简化代码,无需重复,[](){}中[]用于捕获外部变量,()包含参数列表,{}包含函数体,有具体逻辑。

 

实验任务3:

源代码:

 1 #include <iostream>
 2 #include <string>
 3 #include <algorithm>
 4 #include <cctype>
 5 unsigned char func(unsigned char c);
 6 void test1();
 7 void test2();
 8 
 9 int main() {
10    std::cout << "测试1: 字符串大小写转换\n";
11    test1();
12    std::cout << "\n测试2: 字符变换\n";
13    test2();
14 }
15 
16 unsigned char func(unsigned char c) {
17    if(c == 'z')
18    return 'a';
19    if(c == 'Z')
20    return 'A';
21    if(std::isalpha(c))
22    return static_cast<unsigned char>(c+1);
23    return c;
24 }
25 
26 void test1() {
27    std::string s1{"Hello World 2049!"};
28    std::cout << "s1 = " << s1 << '\n';
29    std::string s2;
30    for(auto c: s1)
31    s2 += std::tolower(c);
32    std::cout << "s2 = " << s2 << '\n';
33    std::string s3;
34    for(auto c: s1)
35    s3 += std::toupper(c);
36    std::cout << "s3 = " << s3 << '\n';
37 }
38 
39 void test2() {
40    std::string s1{"I love cosmos!"};
41    std::cout << "s1 = " << s1 << '\n';
42    std::string s2(s1.size(), ' ');
43    std::transform(s1.begin(), s1.end(),s2.begin(),func);
44    std::cout << "s2 = " << s2 << '\n';
45 }

运行结果:

屏幕截图 2025-10-13 205510

问题1:自定义函数 func 功能是什么?

 答:     func 用于对单个字符的转换,即向下一个字母移动,如果到边界,则循环至第一个字母。

问题2:tolower 和 toupper 功能分别是什么?

 答:     tolower是将大写字母转换为对应的小写字母,原来小写字母保持不变;

             toupper是将小写字母转换为对应的大写字母,原来大写字母保持不变。

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

 答:     s1.begin()为输入元素的起点,s1.end()为输入元素的终点,s2.begin()为转换后元素的起点位置,func为操作函数;

             s2.begin()是将转换后元素保存到新容器中,对于原容器元素不会改变,而 s1.begin()是在原容器中进行修改,会覆盖原容器元素。

 

实验任务4:

源代码:

 1 #include <iostream>
 2 #include <string>
 3 #include <algorithm>
 4 bool is_palindrome(const std::string &s);
 5 bool is_palindrome_ignore_case(const std::string &s);
 6 int main() {
 7 using namespace std;
 8 string s;
 9 // 多组输入,直到按下Ctrl+Z结束测试
10 while(cin >> s) {
11     cout << boolalpha<< "区分大小写: " << is_palindrome(s) << "\n"
12     << "不区分大小写: " << is_palindrome_ignore_case(s) << "\n\n";
13 }
14 }
15 bool is_palindrome(const std::string &s){
16     for(int i=0;i<s.size()/2;i++){
17         if(s[i]!=s[s.size()-i-1])
18         return false;
19     } 
20     return true; 
21 }
22 bool is_palindrome_ignore_case(const std::string &s){
23     std::string s1;
24     for(auto c: s)
25     s1 += std::toupper(c); 
26     return is_palindrome(s1);
27 }

运行结果:

屏幕截图 2025-10-13 215944

观察与思考:使用 cin >> s 输入时,输入的字符串中不能包含空格。如果希望测试字符串包含空格(如 hello oop ),代码应如何调整?
 答:              cin>>s改成getline(cin,s)。
 
 
实验任务5:
源代码:
 1 #include <iostream>
 2 #include <string>
 3 #include <algorithm>
 4 std::string dec2n(int x, int n = 2);
 5 int main() {
 6 int x;
 7 while(std::cin >> x) {    
 8     std::cout << "十进制: " << x << '\n'
 9     << "二进制: " << dec2n(x) << '\n'
10     << "八进制: " << dec2n(x, 8) << '\n'
11     << "十二进制: " << dec2n(x, 12) << '\n'
12     << "十六进制: " << dec2n(x, 16) << '\n'
13     << "三十二进制: " << dec2n(x, 32) << "\n\n";
14 }
15 }
16 std::string dec2n(int x,int n) {
17     if (x == 0) {
18         return "0";
19     }
20     std::string s;
21     while(x>0){
22         if(x%n<10){
23             s+='0'+x%n;
24         }
25         else
26         s+='A'+x%n-10;
27         x/=n;
28     }
29     std::reverse(s.begin(),s.end());
30     return s; 
31 }

运行结果:

屏幕截图 2025-10-13 222455

 

 

实验任务6:
源代码:

 1 #include <iostream>
 2 #include <string>
 3 #include <iomanip>
 4 #include <algorithm>
 5 using namespace std;
 6 
 7 int main() {
 8     std::string s; 
 9     std::string s1;
10     for (char c = 'a'; c <= 'z'; c++) {
11         s+=c;
12     }
13     std::cout<<right<<std::setw(2)<<" ";
14     for(auto c: s){
15         std::cout << std::right << std::setw(2) <<c;
16         s1 += std::toupper(c);
17     }
18     cout<<endl; 
19     for(int i=1;i<=26;i++){
20          std::cout << std::right << std::setw(2) << i;
21          std::rotate(s1.begin(),s1.begin() + 1,s1.end());
22          for(auto c: s1){
23             std::cout << std::right << std::setw(2) <<c;
24     }
25     cout<<endl; 
26     }
27     return 0;
28 }

运行结果:

屏幕截图 2025-10-13 224827

 

实验任务7:

源代码:

 1 #include <iostream>
 2 #include <cstdlib>
 3 #include <ctime>
 4 #include <iomanip>
 5 using namespace std;
 6 
 7 char getsign(int sign){
 8     switch(sign){
 9         case 0:return'+';
10         case 1:return'-';
11         case 2:return'*';
12         case 3:return'/';
13         default: return 0;
14     }
15 }
16 
17 int calculate(int sign,int num1,int num2){
18     switch(sign){
19         case 0:return num1+num2;
20         case 1:return num1-num2;
21         case 2:return num1*num2;
22         case 3:return num1/num2;
23         default: return 0;
24     }
25 } 
26 
27 int main() {
28     srand(time(0)); 
29     int num1,num2;
30     int count=0; 
31     int ans; 
32     for(int i=0;i<10;i++){
33         int sign=rand()%4;
34         bool get = false;
35         while(!get){
36             num1=rand()%10+1;
37             num2=rand()%10+1;
38             if(sign==1&&num1<num2){
39                 get=false;
40             }
41             else if(sign==3&&num1%num2!=0)
42             get=false;
43             else
44             get=true; 
45         } 
46         cout<<num1<<getsign(sign)<<num2<<'=' ;
47         cin>>ans;
48         cout<<endl;
49         if(ans==calculate(sign,num1,num2)){
50             count++;
51         }
52     }
53     cout<<"正确率:" <<fixed<<setprecision(2)<<count/10.00*100<<"%" <<endl;
54 }

运行结果:

屏幕截图 2025-10-13 233502

 

 屏幕截图 2025-10-13 234902

 

 总结:通过这次实验,我对c++自带标准库组件了解了更多,同时也逐渐学会应用它解决问题,同时自身代码能力也有了一定的提升。

 

posted @ 2025-10-13 23:37  noeleven  阅读(5)  评论(0)    收藏  举报