实验一

实验一

  task1

(1)
 1 // 现代C++标准库、算法库体验
 2 // 本例用到以下内容:
 3 // 1.字符串string, 动态数组容器类vector、迭代器
 4 // 2.算法库:反转元素次序、旋转元素
 5 // 3.函数模板、const引用作为形参
 6 
 7 #include<iostream>
 8 #include<string>
 9 #include<vector>
10 #include<algorithm>
11 
12 //模板函数声明
13 template<typename T >
14 void output(const T &c);
15 
16 void test1();
17 void test2();
18 void test3();
19 
20 int main(){
21     std::cout<<"测试1:\n";
22     test1();
23     
24     std::cout<<"测试2:\n";
25     test2();
26     
27     std::cout<<"测试3:\n";
28     test3();
29 }
30 template<typename T>
31 void output(const T &c){
32     for(auto &i:c)
33         std::cout<<i<<' ';
34     std::cout<<'\n';
35 } 
36  //测试1:组合使用算法库、迭代器、string反转字符串
37 void test1(){
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 //测试2:组合使用算法库、迭代器、vector反转动态数组对象vector内数据
54 void test2(){
55     using namespace std;
56     
57     vector<int>v0{2,0,4,9};
58     cout<<"v0:";output(v0);
59     vector<int>v1{v0};
60     reverse(v1.begin(),v1.end());
61     cout<<"v1:";output(v1);
62     
63     vector<int>v2{v0};
64     reverse_copy(v0.begin(),v0.end(),v2.begin());
65     cout<<"v2:";output(v2);
66     
67 }
68  //测试3:组合使用算法库、迭代器、vector实现元素旋转移位
69 void test3(){
70     using namespace std;
71     
72     vector<int>v0{0,1,2,3,4,5,6,7,8,9};
73     cout<<"v0:";output(v0);
74      
75     vector<int>v1{v0};
76     //将[v1.begin(),v1.end())区间内元素循环左移1位
77     rotate(v1.begin(),v1.begin()+1,v1.end());
78     cout<<"v1:";output(v1);
79     
80     vector<int>v2{v0};
81     // 将[v1.begin(), v1.end())区间内元素循环左移2位
82     rotate(v2.begin(),v2.begin()+2,v2.end());
83     cout<<"v2:";output(v2);
84     
85     vector<int> v3{v0};
86     // 将[v1.begin(), v1.end())区间内元素循环右移1位
87     rotate(v3.begin(),v3.end()-1,v3.end());
88     cout<<"v3:";output(v3);
89     
90     vector<int> v4{v0};
91     // 将[v1.begin(), v1.end())区间内元素循环右移2位
92     rotate(v4.begin(),v4.end()-2,v4.end());
93     cout<<"v4:";output(v4);
94     
95 }
task1代码

  (2)运行结果截图

image

(3)回答问题

    问题1:reverse是原地反转容器(v1)中的元素顺序,而reverse_copy是将反转后的结果复制到另一个容器(v2)中,不会修改原来的容器。

    问题2:rotate算法将容器中的元素进行循环左移,使得中间参数指向的元素成为新的首元素。

        第一个参数是范围的起始位置,第二个参数是新范围起始位置的元素,第三个元素是范围的结束位置。

    

 task2

(1)
 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  // 输出容器对象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  // 返回[0, 100]区间内的一个随机整数
33 int generate_random_number(){
34     return std::rand()%101;
35 }
36 
37  // 测试1:对容器类对象指定迭代器区间赋值、排序
38  void test1(){
39      using namespace std;
40      
41      vector<int>v0(10);// 创建一个动态数组对象v0, 对象大小为10
42      generate(v0.begin(),v0.end(),generate_random_number); // 生成随机数填充v0
43      cout<<"v0:";output(v0);
44      
45      vector<int>v1{v0};
46      sort(v1.begin(),v1.end());//对整个vector排序
47     cout<<"v1:";output(v1);
48     
49     vector<int>v2{v0};
50     sort(v2.begin()+1,v2.end()-1);// 只对中间部分排序,不包含首尾元素
51     cout<<"v2:";output(v2);
52 
53  }
54  
55 // 测试2:对容器类对象指定迭代器区间赋值、计算最大值/最小值/均值
56  void test2(){
57      using namespace std;
58      
59      vector<int>v0(10);
60      generate(v0.begin(),v0.end(),generate_random_number);
61      cout<<"v0:";output(v0);
62      
63      // 求最大值和最小值
64       auto min_iter=min_element(v0.begin(),v0.end());
65       auto max_iter=max_element(v0.begin(),v0.end());
66       cout<<"最小值:"<<*min_iter<<endl;
67      cout<<"最大值:"<<*max_iter<<endl;
68      
69     // 同时求最大值和最小值
70        auto ans=minmax_element(v0.begin(),v0.end());
71        cout<<"最小值:"<<*(ans.first)<<endl;
72         cout<<"最大值:"<<*(ans.second)<<endl;
73         //求平均值
74          double avg1=accumulate(v0.begin(),v0.end(),0.0)/v0.size();
75          cout<<"均值:"<<fixed<<setprecision(2)<<avg1<<endl;
76          
77          sort(v0.begin(),v0.end());
78          double avg2=accumulate(v0.begin()+1,v0.end()-1,0.0)/(v0.size()-2);
79          cout<<"去掉最大值、最小值之后,均值:"<<avg2<<endl; 
80  }
task2代码

(2)运行测试截图

image

 (3)回答问题

问题1:generate算法用指定的生成函数填充容器的元素范围。用以在0~100中生成随机数字。

问题2:①效率高:只需要一次遍历就能同时找到最小值和最大值。

     ②代码简洁,代码行数减少

问题3:效果等同,都是生成0~100的随机数。

task3

(1)
 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     if(c=='Z')
22         return 'A';
23     if(std::isalpha(c))
24         return static_cast<unsigned char>(c+1);
25         
26     return c;
27 }
28 
29 void test1(){
30     std::string s1{"Hello World 2049!"};
31     std::cout<<"s1="<<s1<<'\n';
32     
33     std::string s2;
34     for(auto c:s1)
35         s2+=std::tolower(c);
36     std::cout<<"s2="<<s2<<'\n';
37     
38     std::string s3;
39     for(auto c:s1)
40         s3+=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(),s2.begin(),func);
50     std::cout<<"s2="<<s2<<'\n';
51 }
task3代码

(2)运行测试截图

image

 (3)回答问题

问题1:func的功能是将字母按顺序向左移一位。

问题2:tolower是将字符串中的所有字符中的字母大写转换成小写;toupper是将字符串中的所有字符中的字母小写转换成大写写。

问题3:transform第一个参数是作用范围的起点,第二个参数是作用范围的结束,第三个参数是把作用后的元素输出的起点,第四个参数是转换函数。

     使用s1.begin()的结果是直接覆盖原字符串s1,会破坏原始数据。而使用s2.begin()对原始数据无影响。

task4:

(1)   

 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      using namespace std;
18      if(x==0)return "0";
19      string result="";
20      
21      while(x>0){
22          int remainder=x%n;
23            x=x/n;
24            if(remainder<10){
25                result+='0'+remainder;
26            }
27            else{
28                result='A'+(remainder-10);
29            }
30        }
31      reverse(result.begin(), result.end());  
32      return result;  
33  }
代码

(2)运行测试截图

image

 (3)思考: 可以使用getline(cin,s),这个读取整行内容,包括空格。也可以使用cin.getline()。

task5

(1) 

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

(2)运行测试截图

image

 task6

(1)

 1 #include <iostream>
 2 #include<iomanip>
 3 #include <string>
 4 #include <algorithm>
 5 using namespace std;
 6 unsigned char func(unsigned char c) {
 7 
 8  if(c == 'Z')
 9  return 'A';
10  if(isalpha(c))
11  return static_cast<unsigned char>(c+1);
12  return c;
13  }
14  int main() {
15     int i=1;
16     string v{"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"};
17        cout<<"   "<<v<<endl;
18        string s;
19         for(auto c: v)
20            s+=toupper(c);
21        string s1(s.size(),' ');
22        while(i!=27){
23            transform(s.begin(), s.end(),s1.begin(),func);
24            cout<<setw(3)<<left<<i++;
25         cout<<s1<<endl;
26         s=s1;
27     }
28 }
代码

(2)运行测试截图

image

 task7

(1)

 1 #include <iostream>
 2 #include<iomanip>
 3 #include <string>
 4 #include <algorithm>
 5 #include<random>
 6 #include<ctime>
 7 #include<cstdlib>
 8 using namespace std;
 9  int main() {
10     srand(time(0));
11     
12     int correctCount=0;
13     
14     for(int i=1;i<=10;i++){
15         int num1=rand()%10+1;
16         int num2=rand()%10+1;
17         
18         int op=rand()%4;
19         char opChar;
20         int correctAnswer;
21         int userAnswer;
22         
23         switch(op){
24             case 0:
25                 opChar='+';
26                 correctAnswer=num1+num2;
27                 break;
28                 
29             case 1:
30                 opChar='-';
31                 if(num1<num2)
32                     swap(num1,num2); 
33                 correctAnswer=num1-num2;
34                 break;
35                 
36             case 2:
37                 opChar='*';
38                 correctAnswer=num1*num2;
39                 break;
40                 
41             case 3:
42                 opChar='/';
43                 while(num1%num2!=0){
44                     num2=rand()%10+1;
45                 }
46                 correctAnswer=num1/num2;
47         }
48         cout<<num1<<" "<<opChar<<" "<<num2<<"=";
49         cin>>userAnswer;
50         if(userAnswer==correctAnswer)
51             correctCount++;
52     }   
53     double correctavg=(static_cast<double>(correctCount)/10)*100;
54     cout<<fixed<<setprecision(2);
55     cout<<"正确率:"<<correctavg<<"%"<<endl; 
56 }
代码

(2)运行测试截图

image

 

posted @ 2025-10-15 16:38  deep_l  阅读(5)  评论(0)    收藏  举报