实验一
任务一:
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 // 测试1:组合使用算法库、迭代器、string反转字符串 27 void test1() { 28 using namespace std; 29 string s0{ "0123456789" }; 30 cout << "s0 = " << s0 << endl; 31 string s1(s0); 32 // 反转s1自身 33 reverse(s1.begin(), s1.end()); 34 cout << "s1 = " << s1 << endl; 35 string s2(s0.size(), ' '); 36 // 将s0反转后结果拷贝到s2, s0自身不变 37 reverse_copy(s0.begin(), s0.end(), s2.begin()); 38 cout << "s2 = " << s2 << endl; 39 } 40 // 测试2:组合使用算法库、迭代器、vector反转动态数组对象vector内数据 41 void test2() { 42 using namespace std; 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 // 测试3:组合使用算法库、迭代器、vector实现元素旋转移位 53 void test3() { 54 using namespace std; 55 vector<int> v0{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; 56 cout << "v0: "; output(v0); 57 vector<int> v1{v0}; 58 // 将[v1.begin(), v1.end())区间内元素循环左移1位 59 rotate(v1.begin(), v1.begin()+1, v1.end()); 60 cout << "v1: "; output(v1); 61 vector<int> v2{v0}; 62 // 将[v1.begin(), v1.end())区间内元素循环左移2位 63 rotate(v2.begin(), v2.begin()+2, v2.end()); 64 cout << "v2: "; output(v2); 65 vector<int> v3{v0}; 66 // 将[v1.begin(), v1.end())区间内元素循环右移1位 67 rotate(v3.begin(), v3.end()-1, v3.end()); 68 cout << "v3: "; output(v3); 69 vector<int> v4{v0}; 70 // 将[v1.begin(), v1.end())区间内元素循环右移2位 71 rotate(v4.begin(), v4.end()-2, v4.end()); 72 cout << "v4: "; output(v4); 73 }
问题一:
reverse 直接修改原字符串
reverse_copy 将反转后的字符串结果复制到另一个串中
问题二:
rotate算法将范围内的元素进行循环左移
first:范围的起始位置
middle:将成为新范围起始位置的元素
last:范围的结束位置
任务二:
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 // 添加随机种子 19 std::cout << "\n测试2: \n"; 20 test2(); 21 } 22 // 输出容器对象c中的元素 23 template <typename T> 24 void output(const T& c) { 25 for (auto& i : c) 26 std::cout << i << ' '; 27 std::cout << '\n'; 28 } 29 // 返回[0, 100]区间内的一个随机整数 30 int generate_random_number() { 31 return std::rand() % 101; 32 } 33 // 测试1:对容器类对象指定迭代器区间赋值、排序 34 void test1() { 35 using namespace std; 36 vector<int> v0(10); // 创建一个动态数组对象v0, 对象大小为10 37 generate(v0.begin(), v0.end(), generate_random_number); // 生成随机数填充v0 38 cout << "v0: "; output(v0); 39 vector<int> v1{ v0 }; 40 sort(v1.begin(), v1.end()); // 对整个vector排序 41 cout << "v1: "; output(v1); 42 vector<int> v2{ v0 }; 43 sort(v2.begin() + 1, v2.end() - 1); // 只对中间部分排序,不包含首尾元素 44 cout << "v2: "; output(v2); 45 } 46 // 测试2:对容器类对象指定迭代器区间赋值、计算最大值/最小值/均值 47 void test2() { 48 using namespace std; 49 vector<int> v0(10); 50 generate(v0.begin(), v0.end(), generate_random_number); 51 cout << "v0: "; output(v0); 52 // 求最大值和最小值 53 auto min_iter = min_element(v0.begin(), v0.end()); 54 auto max_iter = max_element(v0.begin(), v0.end()); 55 cout << "最小值: " << *min_iter << endl; 56 cout << "最大值: " << *max_iter << endl; 57 // 同时求最大值和最小值 58 auto ans = minmax_element(v0.begin(), v0.end()); 59 cout << "最小值: " << *(ans.first) << endl; 60 cout << "最大值: " << *(ans.second) << endl; 61 // 求平均值 62 double avg1 = accumulate(v0.begin(), v0.end(), 0.0) / v0.size(); 63 cout << "均值: " << fixed << setprecision(2) << avg1 << endl; 64 sort(v0.begin(), v0.end()); 65 double avg2 = accumulate(v0.begin() + 1, v0.end() - 1, 0.0) / (v0.size() - 2); 66 cout << "去掉最大值、最小值之后,均值: " << avg2 << endl; 67 }
问题一:
generate函数的作用是用随机数填充数组
问题二:
只需一次遍历
问题三:
随机产生一个100以内的随机数,简短、一次性使用的函数对象
任务三:
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 int main() { 9 std::cout << "测试1: 字符串大小写转换\n"; 10 test1(); 11 std::cout << "\n测试2: 字符变换\n"; 12 test2(); 13 } 14 unsigned char func(unsigned char c) { 15 if (c == 'z') 16 return 'a'; 17 if (c == 'Z') 18 return 'A'; 19 if (std::isalpha(c)) 20 return static_cast<unsigned char>(c + 1); 21 return c; 22 } 23 void test1() { 24 std::string s1{ "Hello World 2049!" }; 25 std::cout << "s1 = " << s1 << '\n'; 26 std::string s2; 27 for (auto c : s1) 28 s2 += std::tolower(c); 29 std::cout << "s2 = " << s2 << '\n'; 30 std::string s3; 31 for (auto c : s1) 32 s3 += std::toupper(c); 33 std::cout << "s3 = " << s3 << '\n'; 34 } 35 void test2() { 36 std::string s1{ "I love cosmos!" }; 37 std::cout << "s1 = " << s1 << '\n'; 38 std::string s2(s1.size(), ' '); 39 std::transform(s1.begin(), s1.end(), 40 s2.begin(), 41 func); 42 std::cout << "s2 = " << s2 << '\n'; 43 }
问题一:func函数的作用是将英文字母变成其后的一个字母
问题二:
tolower的作用是将英文字母变成小写,toupper则是变成大写
问题三:
源字符串起点,源字符串终点,目标字符串起点,s2不会受到影响
任务四:
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 12 << "区分大小写: " << is_palindrome(s) << "\n" 13 << "不区分大小写: " << is_palindrome_ignore_case(s) << "\n\n"; 14 } 15 } 16 bool is_palindrome(const std::string& s) { 17 std::string s1(s.size(), ' '); 18 reverse_copy(s.begin(), s.end(), s1.begin()); 19 int n = 0; 20 while (n < s.size()) { 21 if (s[n] != s1[n]) { 22 return false; 23 } 24 n++; 25 } 26 return true; 27 28 } 29 bool is_palindrome_ignore_case(const std::string& s) { 30 std::string s1(s.size(), ' '); 31 reverse_copy(s.begin(), s.end(), s1.begin()); 32 int n = 0; 33 while (n < s.size()) { 34 if (!(s[n] == s1[n] || std::tolower(s[n]) == s1[n] || std::toupper(s[n]) == s1[n])) { 35 return false; 36 } 37 n++; 38 } 39 return true; 40 }
问题1:
将cin>>s变为std::getline(std::cin, s);
任务五:
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 std::string s; 18 19 int count = 0, w = 0; 20 if (x == 0) { 21 s += '0'; 22 } 23 while(x != 0) { 24 w = x % n; 25 x /= n; 26 if (w < 10) { 27 s += w + '0'; 28 } 29 else { 30 s += w - 10 + 'A'; 31 } 32 } 33 reverse(s.begin(), s.end()); 34 return s; 35 }
任务六:
1 #include<iostream> 2 #include<iomanip> 3 4 void num(int a, int b) { 5 if (a == 0 && b == 0) { 6 std::cout << std::left << std::setw(3) << ' '; 7 } 8 if (a == 0 && b != 0) { 9 std::cout << std::left << std::setw(3) <<(char)('a' - 1 + b); 10 } 11 if (a != 0 && b == 0) { 12 std::cout << std::left << std::setw(3) << a; 13 } 14 if (a != 0 && b != 0) { 15 std::cout << std::left << std::setw(3) << (char)((a + b - 1) % 26 + 'A'); 16 } 17 } 18 19 int main() { 20 for (int i = 0; i < 27; i++) { 21 for (int j = 0; j < 27; j++){ 22 num(i, j); 23 24 } 25 std::cout << std::endl; 26 } 27 28 29 }
任务七:
1 #include<iostream> 2 #include<ctime> 3 #include<iomanip> 4 int get_random_number(bool no_zreo = false); 5 6 int get_random_syn() { 7 return std::rand() % 4; 8 } 9 10 int main() { 11 std::srand(std::time(0)); 12 int count = 0,countcorrect = 0; 13 std::string s = { '+','-','*','/' }; 14 while (count < 10) { 15 int num1 = get_random_number(); 16 int num2 = get_random_number(true); 17 int syn = get_random_syn(); 18 int ans1,ans; 19 switch (syn) { 20 case 0: 21 ans = num1 + num2; 22 break; 23 case 1: 24 ans = num1 - num2; 25 if (ans < 0) { 26 int t = num2; 27 num2 = num1; 28 num1 = t; 29 ans = num1 - num2; 30 } 31 break; 32 case 2: 33 ans = num1 * num2; 34 break; 35 case 3: 36 ans = num1 / num2; 37 if (num1 % num2 != 0) { 38 num1 -= num1 % num2; 39 num1 += num2; 40 ans++; 41 if (num1 >= 10) { 42 num1 -= num2; 43 ans--; 44 } 45 } 46 break; 47 } 48 std::cout << num1 << s[syn] << num2 << '='; 49 std::cin >> ans1; 50 if (ans1 == ans) { 51 countcorrect++; 52 53 } 54 count++; 55 } 56 std::cout << "正确率:" <<std::fixed<<std::setprecision(2)<<countcorrect*10.0<<"%"; 57 } 58 int get_random_number(bool no_zreo) { 59 int a = 0; 60 if (no_zreo == false) { 61 return std::rand() % 10; 62 } 63 else { 64 while (a == 0) { 65 a = std::rand() % 10; 66 } 67 return a; 68 } 69 }