OOP-实验1

任务1

task1.cpp

 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 12 int main() { 13 std::cout<<"测试1: \n"; 14 test1(); 15 std::cout<<"\n测试2: \n"; 16 test2(); 17 std::cout<<"\n测试3: \n"; 18 test3(); 19 } 20 //输出c中的元素 21 template <typename T> 22 void output(const T &c) { 23 for(auto &i:c) 24 std::cout<<i<<' '; 25 std::cout<<'\n'; 26 } 27 28 void test1() { 29 using namespace std; 30 string s0{"0123456789"}; 31 cout<<"s0 = "<<s0<< endl; 32 string s1(s0); 33 //反转s1自身 34 reverse(s1.begin(),s1.end()); 35 cout<<"s1 = "<<s1<<endl; 36 string s2(s0.size(),' '); 37 //将s0反转后结果拷贝到s2, s0自身不变 38 reverse_copy(s0.begin(),s0.end(),s2.begin()); 39 cout<<"s2 = "<<s2<<endl; 40 } 41 42 void test2() { 43 using namespace std; 44 vector<int> v0{2,0,4,9}; 45 cout << "v0: "; output(v0); 46 vector<int> v1{v0}; 47 reverse(v1.begin(),v1.end()); 48 cout << "v1: "; output(v1); 49 vector<int> v2{v0}; 50 reverse_copy(v0.begin(),v0.end(),v2.begin()); 51 cout << "v2: "; output(v2); 52 } 53 54 void test3() { 55 using namespace std; 56 vector<int> v0{0,1,2,3,4,5,6,7,8,9}; 57 cout << "v0: "; output(v0); 58 vector<int> v1{v0}; 59 //循环左移1位 60 rotate(v1.begin(),v1.begin()+1,v1.end()); 61 cout << "v1: "; output(v1); 62 vector<int> v2{v0}; 63 //元素循环左移2位 64 rotate(v2.begin(),v2.begin()+2,v2.end()); 65 cout << "v2: "; output(v2); 66 vector<int> v3{v0}; 67 //循环右移1位 68 rotate(v3.begin(),v3.end()-1,v3.end()); 69 cout << "v3: "; output(v3); 70 vector<int> v4{v0}; 71 //循环右移2位 72 rotate(v4.begin(),v4.end()-2,v4.end()); 73 cout << "v4: "; output(v4); 74 }
运行测试截图

image

 

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

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)); //添加随机种子,time(0)每秒都不一样 
19     std::cout<<"测试1: \n";
20     test1();  
21     std::cout<<"测试2:\n";
22     test2();
23     return 0;
24 }
25 //输出c中元素 
26 template<class 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 void test1(){
38     using namespace std;
39     vector<int> v0(10);
40     generate(v0.begin(),v0.end(),generate_random_number);
41     cout<<"v0: "; 
42     output(v0);
43     
44     vector<int> v1{v0};
45     sort(v1.begin(),v1.end()); //对v1排序 
46     cout<<"v1: ";
47     output(v1);
48     
49     vector<int> v2{v0};
50     sort(v2.begin()+1, v2.end()-1); //对除首尾以外的元素排序 
51     cout << "v2: "; 
52     output(v2);
53 } 
54 
55 void test2(){
56     using namespace std;
57     vector<int> v0(10);
58     generate(v0.begin(),v0.end(),generate_random_number);
59     cout<<"v0: ";
60     output(v0);
61     
62     //求最大值和最小值
63     auto  min_iter=min_element(v0.begin(),v0.end());
64     auto  max_iter=max_element(v0.begin(),v0.end());
65     cout<<"min: "<<*min_iter<<endl;
66     cout<<"max: "<<*max_iter<<endl;
67     
68     //同时求最大值和最小值 
69     auto ans=minmax_element(v0.begin(),v0.end());
70     cout<<"min: "<<*(ans.first)<<endl;
71     cout<<"max: "<<*(ans.second)<<endl;
72     
73     //求平均值
74     double avg1=accumulate(v0.begin(),v0.end(),0.0)/v0.size();
75     cout<<"average: "<<fixed<<setprecision(2)<<avg1<<endl;
76     sort(v0.begin(),v0.end());
77     double avg2=accumulate(v0.begin()+1,v0.end()-1,0.0)/(v0.size()-2);
78     cout<<"去掉最大、最小值之后average: "<<avg2<<endl;
79      
80 } 

 

运行结果截图

image

 

问题1: generate 算法的作用是什么?
  生成一系列值填充到指定的迭代器范围(所给的参数)中。
问题2: minmax_element 和分别调用 min_element 、 max_element 相比,有什么优势?
  只需要调用一次既可获得最小和最大值,更便捷。
问题3:查询 generate 第3个参数 [](){return std::rand()%101;} 用法,与使用自定义函数
generate_random_number 相比,lambda表达式适用场景是什么?
  适用场景:代码逻辑非常简单;只需要临时使用一次而不需要重复用;需要捕获外部变量。
 
任务3
task3.cpp
 1 #include<iostream>
 2 #include<string>
 3 #include<algorithm>
 4 #include<cctype>
 5 
 6 unsigned char func(unsigned char c);
 7 
 8 void test1();
 9 void test2();
10 
11 int main(){
12     std::cout<<"测试1:字符串的大小写转换\n";
13     test1();
14     std::cout<<"\n测试2:字符变换\n";
15     test2();
16     return 0;
17 }
18 
19 unsigned char func(unsigned char c){
20     if(c=='z') return 'a';
21     if(c=='Z') return 'A';
22     
23     if(std::isalpha(c)) return static_cast<unsigned char>(c+1);
24     
25     return c;
26 }
27 
28 void test1(){
29     std::string s1{"Hello World 2049!"};
30     std::cout<<"s1="<<s1<<std::endl;
31     
32     std::string s2;
33     for(auto c:s1) s2+=std::tolower(c);
34     std::cout<<"s2="<<s2<<std::endl;
35     
36     std::string s3;
37     for(auto c:s1) s3+=std::toupper(c);
38     std::cout<<"s3="<<s3<<"\n";    
39 }
40 
41 void test2(){
42     std::string s1{"I love cosmos!"};
43     std::cout<<"s1="<<s1<<"\n";
44     
45     std::string s2(s1.size(),' ');
46     std::transform(s1.begin(),s1.end(),s2.begin(),func);
47     std::cout<<"s2="<<s2<<"\n";
48 }

 

运行结果截图

image

 

1 自定义函数 func 功能是什么?
如果输入的是字符z/Z  返回字符a/A,如果输入其他字母,返回它的下一个字母,如果输入的不是字母,就返回本身。
 
2 tolower 和 toupper 功能分别是什么?
分别将字母转化成小/大写
 
3 transform 的4个参数意义分别是什么?如果把第3个参数 s2.begin() 改成 s1.begin() ,有何区别?
前两个参数是需要用到的容器内元素的起始迭代器和末尾迭代器,第四个参数是一个转换函数,将前两个迭代器范围的元素转换后写入第三个参数迭代器位置。
如果把第三个参数s2.begin()改成s1.begin(),将s1元素进行转换后会直接写入s1自身。
 
任务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( std::string s);
 7 
 8 int main(){
 9     using namespace std;
10     string s;
11     while(cin >> s) {
12         cout << boolalpha //流操纵符控制bool输出为true/false,而不是1/0 
13         << "区分大小写: " << is_palindrome(s) << "\n"
14         << "不区分大小写: " << is_palindrome_ignore_case(s) << "\n\n";
15     }
16 }
17 
18 bool is_palindrome(const std::string &s){
19     for(int i=0;i<s.size()/2;i++){
20         if(s[i]!=s[s.size()-1-i]) return false;
21     } 
22     return true;
23 }
24 
25 bool is_palindrome_ignore_case( std::string s){
26     transform(s.begin(),s.end(),s.begin(),[](char c){
27         return static_cast<char>(std::toupper(static_cast<unsigned char>(c))); 
28     });
29     for(int i=0;i<s.size()/2;i++){
30         if(s[i]!=s[s.size()-1-i]) return false;
31     } 
32     return true;
33 }

 

运行结果截图:

image

 

1 使用 cin >> s 输入时,输入的字符串中不能包含空格。如果希望测试字符串包含空格(如 hello oop ),代码应如何调整?
  改为getline(cin,s),这样可以整行读取

 

任务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,2)<<"\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 std::string dec2n(int x,int n){
20     std::string res;
21     if(!x) return "0";
22     while(x>0){
23         int temp=x%n;
24         x/=n;
25         if(temp<10){
26             res.insert(0,1,temp+'0');
27         }else{
28             res.insert(0,1,(temp-10)+'A');
29         }
30     }
31     return res;
32 }

 

运行截图

image

 

 任务6
task6.cpp
 1 #include<iostream>
 2 #include<algorithm>
 3 #include<iomanip>
 4 using namespace std;
 5 int main(){
 6     cout<<fixed<<setw(2)<<" ";
 7     vector<char> a;  //字母表 
 8     for(int i=0;i<26;i++){
 9         cout<<fixed<<setw(2)<<static_cast<char>(i+'a');
10         a.push_back(i+'A');
11     }
12     cout<<"\n";
13     for(int i=1;i<=26;i++){
14         rotate(a.begin(), a.begin()+1, a.end());  //移位 
15         cout<<fixed<<setw(2)<<i;
16         for(auto i:a)
17             cout<<fixed<<setw(2)<<i;
18         cout<<"\n";
19     }
20     return 0;
21 }

 运行截图

image

 

任务7

task7.cpp

 1 #include<iostream>
 2 #include<vector> 
 3 #include<cstdlib>
 4 #include<ctime>
 5 #include<iomanip>
 6 using namespace std;
 7 int main(){
 8     srand(time(0));
 9     vector<char> v={'+','-','*','/'}; //四个运算符数组 
10     int n=10;  //记录答对的题目数量 
11     int count=0;
12     while(n--){
13         char c=v[rand()%4];  //本题的运算符号
14         int ans,right_ans;
15         //a,b两个随机生成的运算数字 
16         switch (c){
17             case '+':{
18                 int a=rand()%10+1,b=rand()%10+1;
19                 right_ans=a+b;
20                 cout<<a<<" + "<<b<<" = "; break;
21             }case '*':{
22                 int a=rand()%10+1,b=rand()%10+1;
23                 right_ans=a*b;
24                 cout<<a<<" * "<<b<<" = "; break;
25             }case '-':{
26                 int a=rand()%10+1,b=rand()%(a+1);
27                 right_ans=a-b;
28                 cout<<a<<" - "<<b<<" = "; break;
29             }case '/':{
30                 int a=rand()%10+1,b=rand()%a+1;
31                 while(a%b!=0) b=rand()%a+1;  //如果不是整除关系,重新生成b
32                 cout<<(int)a<<" / "<<(int)b<<" = "; 
33                 right_ans=a/b ;break;
34             }
35         } 
36         cin>>ans;
37         //cout<<"\n"<<"right_ans:"<<right_ans<<" ans:"<<ans<<"\n";
38         if(ans==right_ans) count++;
39     }
40     cout<<"正确率:"<<fixed<<setprecision(2)<<count*10.0<<"%"<<endl;
41 } 

 

 运行结果:

image

 

 

posted @ 2025-10-11 21:42  fg-ever  阅读(19)  评论(1)    收藏  举报