#实验任务1
##代码
1 #include <iostream> 2 #include <string> 3 #include <vector> 4 #include <algorithm> 5 using namespace std; 6 template<typename T> 7 void output(const T &c); 8 9 void test1(); 10 void test2(); 11 void test3(); 12 13 int main(){ 14 cout << "测试1:\n"; 15 test1(); 16 cout << "\n测试2:\n"; 17 test2(); 18 cout << "\n测试3:\n"; 19 test3(); 20 } 21 22 template <typename T> 23 void output(const T &c) { 24 for(auto &i : c) 25 cout << i << ' '; 26 cout <<'\n'; 27 } 28 29 30 void test1(){ 31 string s0{"0123456789"}; 32 cout <<"s0 = "<< s0 << endl; 33 string s1(s0); 34 reverse(s1.begin(),s1.end()); 35 cout <<"s1 = "<< s1 << endl; 36 37 string s2(s0.size(),' '); 38 reverse_copy(s0.begin(),s0.end(),s2.begin()); 39 cout <<"s2 = "<< s2 << endl; 40 } 41 42 void test2(){ 43 vector<int> v0{2,0,4,9}; 44 cout << "v0: ";output(v0); 45 vector<int> v1{v0}; 46 reverse(v1.begin(),v1.end()); 47 cout << "v1: ";output(v1); 48 vector<int> v2{v0}; 49 reverse_copy(v0.begin(),v0.end(),v2.begin()); 50 cout << "v2: ";output(v2); 51 } 52 53 void test3(){ 54 vector<int> v0{0,1,2,3,4,5,6,7,8,9}; 55 cout << "v0: ";output(v0); 56 vector<int> v1{v0}; 57 rotate(v1.begin(),v1.begin()+1,v1.end()); 58 cout << "v1: ";output(v1); 59 vector<int> v2{v0}; 60 rotate(v2.begin(),v2.begin()+2,v2.end()); 61 cout << "v2: ";output(v2); 62 vector<int> v3{v0}; 63 rotate(v3.begin(),v3.end()-1,v3.end()); 64 cout << "v3: ";output(v3); 65 vector<int> v4{v0}; 66 rotate(v4.begin(),v4.end()-2,v4.end()); 67 cout << "v4: ";output(v4);
##实验结果
##问题回答
问题1:reverse 函数是将字符串原地反转 reverse-copy函数将字符串反转后的结果复制到另一字符串
问题2:rotate函数改变元素顺序的核心思想为:将区间 [first, middle)
和 [middle, last)
的元素交换位置,但保持这两个子区间内部的元素顺序不变。
first:旋转范围的起始位置
middle:旋转后成为新的第一个元素的位置
last:旋转范围的结束位置
#实验任务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 int generate_random_number(); 12 void test1(); 13 void test2(); 14 int main() { 15 std::srand(std::time(0)); 16 std::cout << "测试1: \n"; 17 test1(); 18 std::cout << "\n测试2: \n"; 19 test2(); 20 } 21 22 template <typename T> 23 void output(const T &c) { 24 for(auto &i: c) 25 std::cout << i << ' '; 26 std::cout << '\n'; 27 } 28 29 int generate_random_number() { 30 return std::rand() % 101; 31 } 32 33 void test1() { 34 using namespace std; 35 vector<int> v0(10); 36 generate(v0.begin(), v0.end(), generate_random_number); 37 cout << "v0: "; output(v0); 38 vector<int> v1{v0}; 39 sort(v1.begin(), v1.end()); 40 cout << "v1: "; output(v1); 41 vector<int> v2{v0}; 42 sort(v2.begin()+1, v2.end()-1); 43 cout << "v2: "; output(v2); 44 } 45 46 void test2() { 47 using namespace std; 48 vector<int> v0(10); 49 generate(v0.begin(), v0.end(), generate_random_number); 50 cout << "v0: "; output(v0); 51 auto min_iter = min_element(v0.begin(), v0.end()); 52 auto max_iter = max_element(v0.begin(), v0.end()); 53 cout << "最小值: " << *min_iter << endl; 54 cout << "最大值: " << *max_iter << endl; 55 auto ans = minmax_element(v0.begin(), v0.end()); 56 cout << "最小值: " << *(ans.first) << endl; 57 cout << "最大值: " << *(ans.second) << endl; 58 double avg1 = accumulate(v0.begin(), v0.end(), 0.0) / v0.size(); 59 cout << "均值: " << fixed << setprecision(2) << avg1 << endl; 60 sort(v0.begin(), v0.end()); 61 double avg2 = accumulate(v0.begin()+1, v0.end()-1, 0.0) / (v0.size()-2); 62 cout << "去掉最大值、最小值之后,均值: " << avg2 << endl; 63 }
##运行结果
##问题回答
问题1:generate函数在我看来就是为指定的容器填充数据,这个数据是随机的
问题2:minimax_element只需要遍历容器一次,而分别调用mini_element 和 max_element 需要遍历容器两次,相较之下,使用minimax_element可以使代码更加简化,且可以保持数据的一致性,因为只遍历了一次
问题3:效果等同 Lambda 表达式把函数看作对象。Lambda 表达式可以像对象一样使用,比如可以将它们赋给变量和作为参数传递,还可以像函数一样对其求值。
##实验任务3
#代码
1 #include<iostream> 2 #include<string> 3 #include<algorithm> 4 #include<cctype> 5 using namespace std; 6 7 unsigned char func(unsigned char c); 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 } 17 unsigned char func(unsigned char c){ 18 if(c == 'z') 19 return 'a'; 20 21 if(c == 'Z') 22 return 'A'; 23 24 if(std::isalpha(c)) 25 return static_cast<unsigned char>(c+1); 26 27 return c; 28 } 29 30 void test1(){ 31 string s1{"Hello World 2049!"}; 32 cout << "s1 = " << s1 << endl; 33 34 string s2; 35 for(auto c:s1) 36 s2 +=tolower(c); 37 cout << "s2 = " << s2 << endl; 38 39 string s3; 40 for(auto c:s1) 41 s3 += toupper(c); 42 cout << "s3 = " << s3 << endl; 43 44 } 45 46 47 void test2(){ 48 string s1{"I love cosmos!"}; 49 cout << "s1 = " << s1 << endl; 50 51 string s2(s1.size(),' '); 52 transform(s1.begin(),s1.end(),s2.begin(),func); 53 cout << "s2 = " << s2 << endl; 54 55 }
#运行结果
#问题回答
问题1:func函数的具体功能是实现字符变换,具体规则为:1.如果字符是小写字母 'z',则变换为 'a'
2.如果字符是大写字母 'Z',则变换为 'A'
3.如果字符是其他字母,则变换为字母表中的下一个字母
4.如果字符不是字母,则保持不变(isalpha用来判断c是否是一个字母)
问题2: tolower 的功能是将字符串中的大写字母转换成对应小写字母,非大写字母不变
toupper 的功能是将字符串中的小写字母转换成对应大写字母,非小写字母不变
问题3:第一个参数是要进行变换的元素的起始位置 第二个参数是要进行变换的元素的结束位置
第三个参数是指定变换结果的存储位置 第四个参数是一个函数,是对前面序列需要进行的操作
参数修改后 原来执行结果是非就地操作,即把s1变换后的结果存储在s2中 修改后执行就地操作,s1原来的数据丢失,s1包含变换后的新内容
##实验任务4
#代码
1 #include<iostream> 2 #include<string> 3 #include<algorithm> 4 using namespace std; 5 6 bool is_palindrome(const std::string &s); 7 bool is_palindrome_ignore_case(const std::string &s); 8 9 int main(){ 10 11 string s; 12 while(cin>>s){ 13 cout << boolalpha 14 << "区分大小写:" << is_palindrome(s) << "\n" 15 << "不区分大小写:" << is_palindrome_ignore_case(s) << "\n\n"; 16 } 17 } 18 bool is_palindrome(const std::string &s){ 19 string s1(s); 20 reverse(s1.begin(),s1.end()); 21 return s == s1; 22 } 23 bool is_palindrome_ignore_case(const std::string &s){ 24 string s1(s); 25 string s2(s); 26 transform(s1.begin(),s1.end(),s1.begin(),::tolower); 27 transform(s2.begin(),s2.end(),s2.begin(),::tolower); 28 reverse(s2.begin(),s2.end()); 29 return s1 == s2; 30 31 }
#运行结果
#问题回答
要想实现空格输入,可以引入getline函数,部分代码如下
1 int main(){ 2 string s; 3 cout << "请输入字符串(输入'q'退出):" << endl; 4 5 while (getline(cin, s)) { // 使用getline读取包含空格的完整行 6 if (s == "q" || s == "Q") { // 添加退出条件 7 break; 8 } 9 10 cout << boolalpha 11 << "区分大小写:" << is_palindrome(s) << "\n" 12 << "不区分大小写:" << is_palindrome_ignore_case(s) << "\n\n"; 13 14 15 } 16 17 return 0;}
##实验任务5
#代码
1 #include <iostream> 2 #include <string> 3 #include <algorithm> 4 using namespace std; 5 string dec2n(int x, int n = 2); 6 7 int main() { 8 int x; 9 while(cin >> x) { 10 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\n"; 16 } 17 } 18 19 // 函数dec2n定义 20 string dec2n(int x, int n) 21 { 22 if (x == 0) { 23 return "0"; 24 } 25 26 string result; 27 28 while (x > 0) { 29 int t = x % n; 30 result += (t>=10) ? ('A' + (t - 10)) : ('0' + t); 31 x /= n; 32 } 33 34 reverse(result.begin(), result.end()); 35 return result; 36 }
#运行结果
##实验任务6
#代码
1 #include <iostream> 2 #include <string> 3 #include <vector> 4 #include <algorithm> 5 using namespace std; 6 template<typename T> 7 void output(const T &c); 8 void test1(); 9 int main(){ 10 test1(); 11 } 12 template <typename T> 13 void output(const T &c) { 14 for(auto &i : c) 15 cout << i << ' '; 16 cout <<'\n'; 17 } 18 void test1(){ 19 vector<char> v0{'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'}; 20 cout << " ";output(v0); 21 vector<char> v01(v0); 22 transform(v01.begin(),v01.end(),v01.begin(),::toupper); 23 vector<char> v1(v01); 24 rotate(v1.begin(),v1.begin()+1,v1.end()); 25 cout << " 1 ";output(v1); 26 vector<char> v2(v01); 27 rotate(v2.begin(),v2.begin()+2,v2.end()); 28 cout << " 2 ";output(v2); 29 vector<char> v3(v01); 30 rotate(v3.begin(),v3.begin()+3,v3.end()); 31 cout << " 3 ";output(v3); 32 vector<char> v4(v01); 33 rotate(v4.begin(),v4.begin()+4,v4.end()); 34 cout << " 4 ";output(v4); 35 vector<char> v5(v01); 36 rotate(v5.begin(),v5.begin()+5,v5.end()); 37 cout << " 5 ";output(v5); 38 vector<char> v6(v01); 39 rotate(v6.begin(),v6.begin()+6,v6.end()); 40 cout << " 6 ";output(v6); 41 vector<char> v7(v01); 42 rotate(v7.begin(),v7.begin()+7,v7.end()); 43 cout << " 7 ";output(v7); 44 vector<char> v8(v01); 45 rotate(v8.begin(),v8.begin()+8,v8.end()); 46 cout << " 8 ";output(v8); 47 vector<char> v9(v01); 48 rotate(v9.begin(),v9.begin()+9,v9.end()); 49 cout << " 9 ";output(v9); 50 vector<char> v10(v01); 51 rotate(v10.begin(),v10.begin()+10,v10.end()); 52 cout << "10 ";output(v10); 53 vector<char> v11(v01); 54 rotate(v11.begin(),v11.begin()+11,v11.end()); 55 cout << "11 ";output(v11); 56 vector<char> v12(v01); 57 rotate(v12.begin(),v12.begin()+12,v12.end()); 58 cout << "12 ";output(v12); 59 vector<char> v13(v01); 60 rotate(v13.begin(),v13.begin()+13,v13.end()); 61 cout << "13 ";output(v13); 62 vector<char> v14(v01); 63 rotate(v14.begin(),v14.begin()+14,v14.end()); 64 cout << "14 ";output(v14); 65 vector<char> v15(v01); 66 rotate(v15.begin(),v15.begin()+15,v15.end()); 67 cout << "15 ";output(v15); 68 vector<char> v16(v01); 69 rotate(v16.begin(),v16.begin()+16,v16.end()); 70 cout << "16 ";output(v16); 71 vector<char> v17(v01); 72 rotate(v17.begin(),v17.begin()+17,v17.end()); 73 cout << "17 ";output(v17); 74 vector<char> v18(v01); 75 rotate(v18.begin(),v18.begin()+18,v18.end()); 76 cout << "18 ";output(v18); 77 vector<char> v19(v01); 78 rotate(v19.begin(),v19.begin()+19,v19.end()); 79 cout << "19 ";output(v19); 80 vector<char> v20(v01); 81 rotate(v20.begin(),v20.begin()+20,v20.end()); 82 cout << "20 ";output(v20); 83 vector<char> v21(v01); 84 rotate(v21.begin(),v21.begin()+21,v21.end()); 85 cout << "21 ";output(v21); 86 vector<char> v22(v01); 87 rotate(v22.begin(),v22.begin()+22,v22.end()); 88 cout << "22 ";output(v22); 89 vector<char> v23(v01); 90 rotate(v23.begin(),v23.begin()+23,v23.end()); 91 cout << "23 ";output(v23); 92 vector<char> v24(v01); 93 rotate(v24.begin(),v24.begin()+24,v24.end()); 94 cout << "24 ";output(v24); 95 vector<char> v25(v01); 96 rotate(v25.begin(),v25.begin()+25,v25.end()); 97 cout << "25 ";output(v25); 98 vector<char> v26(v01); 99 rotate(v26.begin(),v26.begin()+26,v26.end()); 100 cout << "26 ";output(v26); 101 }
第一想法就是暴力求解,一个一个列出来,写完以后手都敲得累了,于是尝试进行优化,优化后代码如下
1 #include <iostream> 2 #include <string> 3 #include <vector> 4 #include <algorithm> 5 using namespace std; 6 template<typename T> 7 void output(const T &c); 8 void test1(); 9 int main(){ 10 test1(); 11 } 12 template <typename T> 13 void output(const T &c) { 14 for(auto &i : c) 15 cout << i << ' '; 16 cout <<'\n'; 17 } 18 void test1(){ 19 vector<char> v0{'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'}; 20 cout << " ";output(v0); 21 vector<char> v01(v0); 22 transform(v01.begin(),v01.end(),v01.begin(),::toupper); 23 for(int i=1;i<=26;i++){ 24 vector<char> vi(v01); 25 rotate(vi.begin(),vi.begin()+i,vi.end()); 26 if(i<10){ 27 cout << " " << i << " "; 28 } 29 else{ 30 cout << i << " "; 31 } 32 output(vi); 33 } 34 }
#运行结果
##实验任务7
#代码
1 #include<iostream> 2 #include<cstdlib> 3 #include<ctime> 4 #include<iomanip> 5 #include<string> 6 using namespace std; 7 8 int generaterandomnumber(int min,int max); 9 void generateaddition(int &a,int &b,string &operation); 10 void generatesubtraction(int &a,int &b,string &operation); 11 void generatemultiplication(int &a,int &b,string &operation); 12 void generatedivison(int &a,int &b,string &operation); 13 int calculateanswer(int a,int b,string operation); 14 int main(){ 15 srand(time(0)); 16 int total=10; 17 int correctcount=0; 18 cout << "小学生算术运算" << endl; 19 20 for(int i=1 ;i <= total; i++){ 21 int a,b; 22 string operation; 23 int operationtype=generaterandomnumber(1,4); 24 25 switch(operationtype){ 26 case 1: 27 generateaddition(a,b,operation); 28 break; 29 case 2: 30 generatesubtraction(a,b,operation); 31 break; 32 case 3: 33 generatemultiplication(a,b,operation); 34 break; 35 case 4: 36 generatedivison(a,b,operation); 37 break; 38 } 39 int correctanswer = calculateanswer(a,b,operation); 40 int useranswer; 41 cout << a << " " << operation << " " << b << " = "; 42 cin >> useranswer; 43 if(useranswer == correctanswer){ 44 correctcount++;} 45 cout << endl; 46 } 47 double accuracy = (static_cast<double>(correctcount)/total)*100; 48 cout << "正确率:" << fixed << setprecision(2) << accuracy << "%" << endl; 49 50 } 51 52 53 int generaterandomnumber(int min,int max){ 54 return rand()%(max-min+1)+min; 55 } 56 void generateaddition(int &a,int &b,string &operation){ 57 a=generaterandomnumber(1,10); 58 b=generaterandomnumber(1,10); 59 operation="+"; 60 } 61 void generatesubtraction(int &a,int &b,string &operation){ 62 a=generaterandomnumber(1,10); 63 b=generaterandomnumber(1,a); 64 operation="-"; 65 } 66 67 void generatemultiplication(int &a,int &b,string &operation){ 68 a=generaterandomnumber(1,10); 69 b=generaterandomnumber(1,10); 70 operation="*"; 71 } 72 void generatedivison(int &a,int &b,string &operation){ 73 b=generaterandomnumber(1,10); 74 int maxresult =10/b; 75 int result =generaterandomnumber(1,maxresult); 76 a=result*b; 77 operation="/"; 78 } 79 int calculateanswer(int a,int b,string operation){ 80 if(operation == "+"){ 81 return a+b; 82 } 83 if(operation == "-"){ 84 return a-b; 85 } 86 if(operation == "*"){ 87 return a*b; 88 } 89 if(operation == "/"){ 90 return a/b; 91 } 92 return 0; 93 }
#运行结果
##实验总结
说实话,这次实验花了我不少时间,从刚开始的对代码的陌生到一步步去了解,去熟悉,去搞明白各个陌生函数的参数含义,具体用法,这个过程是非常值得的,让我真切的感受到了面向对象的方便,算法思路也是我在这次实验中感觉比较难的东西,如何拿到一段内容要求敲出代码,我觉得首先得把思路厘清,这次实验前几个任务刚做的时候没什么感觉,就是敲一遍老师给的代码然后去熟悉它们的功能,直到做到第5个以及后面几个,才发现是前面学习内容的应用,可谓是收货颇多,还需继续努力!!