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

任务1:

源代码task1.cpp

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

运行结果截图:

屏幕截图 2025-10-14 231744

 

问题1
 reverse  直接反转原序列(修改原序列); reverse_copy  反转原序列后复制到新序列(不修改原序列)。
问题2
 rotate  通过将“起始到分界点”的元素移到末尾、“分界点到结束”的元素移到开头来改变顺序。三个参数分别是:序列起始迭代器、分界点迭代器、序列结束迭代器。

任务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 
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-14 231816

 

问题1
 generate  算法的作用是利用指定的生成函数,为指定范围内的每个元素生成新值,以此填充或覆盖该范围内的元素。
问题2
 minmax_element  相比分别调用  min_element  和  max_element ,优势在于只需遍历一次序列就能同时找到最小值和最大值的迭代器,效率更高;且代码更简洁,一行代码即可同时获取两者相关信息。
问题3
lambda 表达式的适用场景为:需要在调用  generate  处直接定义生成逻辑,追求代码简洁紧凑,无需单独定义函数;生成逻辑为局部性的,不希望污染全局命名空间;或者需要灵活捕获外部变量(即使此例未捕获,也具备该潜力)的情况。

任务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     
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-14 231828

问题1
func 功能是将当前字母转换为后一个字母
问题2
 tolower 将大写字母转小写; toupper 将小写字母转大写。
问题3
 transform 四参数(以 transform(first1, last1, first2, result, op) 为例): first1 / last1 是第一个输入序列范围, first2 是第二个输入序列起始, result 是结果序列起始;把 参数 s2.begin() 改成 s1.begin() ,会改变第二个输入序列的元素来源,可能改变结果。

任务4:

源代码task4.cpp

 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     using namespace std;
10     string s;
11     
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 
21 //函数is_palindrome定义
22 bool is_palindrome(const std::string &s){
23     int left=0,right=s.size()-1;
24     while(left<right){
25         if(s[left]!=s[right]){
26             return false;
27         }
28         left++;
29         right--;
30     }
31     return true;
32 }
33 //函数is_palindrome_ignore_case定义
34 bool is_palindrome_ignore_case(const std::string &s){
35     //将字符串转换为小写
36     std::string s2;
37     for(auto c: s)
38          s2+=std::tolower(c);
39     int left=0,right=s2.size()-1;
40     while(left<right){
41         if(s2[left]!=s2[right]){
42             return false;
43         }
44         left++;
45         right--;
46     }
47     return true;     
48 }

 

运行结果截图:

屏幕截图 2025-10-14 231617

 cin >> s 无法读含空格的字符串,需改用 getline(cin, s) (可读取整行含空格内容,若之前有 cin 输入需先加 cin.ignore() 处理换行)。

任务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'; 
16     }
17 }
18 
19 //函数dec2n定义
20  std::string dec2n(int x,int n){
21      //处理x为0的特殊情况
22      if(x==0){
23          return "0";
24      } 
25      std::string result;
26      while(x>0){
27          int remainder=x%n;
28          char c;
29          //余数小于10时,直接转换为对应的数字字符 
30          if(remainder<10){
31              c='0'+remainder;
32          }
33          else{
34              //余数大于等于10时,转换为对应的大写字母(A-Z) 
35              c='A'+remainder-10;
36          }
37          result.push_back(c);
38          //继续处理商 
39          x/=n;
40      } 
41      //因为取余是从低位到高位生成字符,所以需要反转得到正确顺序 
42      std::reverse(result.begin(),result.end());
43      return result; 
44  }

 

运行结果截图:

屏幕截图 2025-10-15 154418

 

任务6:

源代码task6.cpp

 1 #include<iostream>
 2 #include<cstring>
 3 #include<algorithm>
 4 #include<iomanip>//用于setw格式化 
 5 using namespace std;
 6 
 7 int main(){
 8     char plain[]="abcdefghijklmnopqrstuvwxyz";//明文字母表
 9     int len=strlen(plain);
10     //输出首行明文,带空格 
11     cout<<setw(2)<<" ";//行号占位
12     for(int j=0;j<len;j++){
13         cout<<setw(2)<<plain[j];
14     } 
15     cout<<endl;
16     for(int i=1;i<=26;i++){
17         char cipher[27];
18         strcpy(cipher,plain);//复制明文到密文数组
19         //对cipher执行循环右移i位:将前i个元素移到末位 
20         rotate(cipher,cipher+i,cipher+len);
21         //输出行号和大写密文 
22         cout<<setw(2)<<i;
23         for(int j=0;j<27;j++){
24             cout<<setw(2)<<(char)(cipher[j]-32);//ASCII码'a'为97'A'为65,小写变大写 
25         }
26         cout<<endl;
27     } 
28     return 0;
29 }

 

运行结果截图:

屏幕截图 2025-10-15 164339

 

任务7:

源代码task7.cpp

 1 #include<iostream>
 2 #include<cstdlib>
 3 #include<ctime>
 4 #include<iomanip>
 5 using namespace std;//不使用的话cout应表示成std::cout 
 6 int main(){
 7     //初始化随机数种子,使每次运行随机数不同 
 8     srand(static_cast<unsigned int>(time(0)));
 9     int correctCount=0;
10     for(int i=0;i<10;i++){
11         //随机生成两个1到10的操作数
12         int num1=rand()%10+1;
13         int num2=rand()%10+1;
14         //随机生成运算符号(0:加,1:减,2:乘,3:除) 
15         int op=rand()%4;
16         int result;
17         char opChar;
18         //根据不同运算符号处理
19         switch(op){
20             case 0:  //加法
21                 result=num1+num2;
22                 opChar='+';
23                 break;
24             case 1:  //减法:确保num1>=num2
25                 while(num1<num2){
26                     num1=rand()%10+1;
27                     num2=rand()%10+1;
28                 } 
29                 result=num1-num2;
30                 opChar='-';
31                 break;
32             case 2:  //乘法
33                 result=num1*num2;
34                 opChar='*';
35                 break;
36             case 3:  //除法:确保num1能整除num2
37                 while(num2==0||num1%num2!=0){
38                     num1=rand()%10+1;
39                     num2=rand()%10+1;
40                 }        
41                 result=num1/num2;
42                 opChar='/';
43                 break;
44         } 
45         //输出题目,提示用户输入答案
46         cout<<num1<<" "<<opChar<<" "<<num2<<"=";
47         int userAnswer;
48         cin>>userAnswer;
49         //判断答案是否正确,正确则统计
50         if(userAnswer==result){
51             correctCount++;
52         }
53     }
54     //计算并输出正确率,保留两位小数
55     double accuracy=static_cast<double>(correctCount)/10*100;
56     cout<<"正确率:"<<fixed<<setprecision(2)<<accuracy<<"%"<<endl;
57     return 0; 
58 } 

 

运行结果截图:

屏幕截图 2025-10-15 171735

 

posted @ 2025-10-15 17:34  stezin-  阅读(5)  评论(0)    收藏  举报