实验1
源代码
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>template <typename T>
void output(const T &c);void test1();
void test2();
void test3();int main()
{std::cout << "run test1\n";test1();std::cout << "run test2\n";test2();std::cout << "run test3\n";test3();return 0;
}template <typename T>
void output(const T &c)
{for (auto& i : c){std::cout << i << ' ';}std::cout << std::endl;
}void test1()
{using namespace std;string s0{ "0123456789" };cout << "s0 = " << s0 << endl;string s1(s0);reverse(s1.begin(), s1.end());cout << "s1 = " << s1 << endl;string s2(s0.size(),' ');reverse_copy(s0.begin(), s0.end(), s2.begin());cout << "s2 = " << s2 << endl;
}
void test2()
{using namespace std;vector<int> v0{ 2,0,4,9 };cout << "v0: ";output(v0);vector<int> v1{ v0 };reverse(v1.begin(), v1.end());cout << "v1: ";output(v1);vector<int> v2{ v0 };reverse_copy(v0.begin(), v0.end(), v2.begin());cout << "v2: ";output(v2);
}void test3()
{using namespace std;vector<int> v0{ 0,1,2,3,4,5,6,7,8,9 };cout << "v0: "; output(v0);vector<int> v1{ v0 };rotate(v1.begin(), v1.begin() + 1, v1.end());cout << "v1: "; output(v1);vector<int> v2{ v0 };rotate(v2.begin(), v2.begin() + 2, v2.end());cout << "v2: "; output(v2);vector<int> v3{ v0 };rotate(v3.begin(), v3.end() - 1, v3.end());cout << "v3: "; output(v3);vector<int> v4{ v0 };rotate(v4.begin(), v4.end() - 2, v4.end());cout << "v4: "; output(v4);
}
运行测试结果
问题回答
问题1
reverse函数的作用是将一个顺序表容器内指定范围内的元素顺序反转,直接修改原容器;reverse_copy函数的作用是将一个顺序表容器内指定范围的元素顺序反转后,保存在目标容器中,且不修改原有容器中元素的顺序。
问题2
rotate算法通过调整元素位置,使设定的“middle”位置处的元素作为新的起始元素,第一个参数(first)标定修改区域的起始点,第二个参数(middle)标定修改区域新的起始点,第三个参数(last)标定修改区域的截止点的后一个位置。
实验2
源代码
#include <iostream>
#include <vector>
#include <algorithm>
#include <numeric>
#include <iomanip>
#include <cstdlib>
#include <ctime>template <typename T>
void output(const T& c);int generate_random_number();
void test1();
void test2();int main()
{std::srand(std::time(0));//get random seedstd::cout << "run test1: \n";test1();std::cout << "run test2: \n";test2();return 0;
}template <typename T>
void output(const T& c)
{for (auto& i : c)std::cout << i << ' ';std::cout << '\n';
}int generate_random_number()
{return std::rand() % 101;
}void test1()
{using namespace std;vector<int> v0(10);generate(v0.begin(), v0.end(), generate_random_number);cout << "v0: "; output(v0);vector<int> v1{ v0 };sort(v1.begin(), v1.end());cout << "v1: "; output(v1);vector<int> v2{ v0 };sort(v2.begin() + 1, v2.end() - 1);cout << "v2: "; output(v2);
}void test2()
{using namespace std;vector<int> v0(10);generate(v0.begin(), v0.end(), generate_random_number);cout << "v0: "; output(v0);auto min_iter = min_element(v0.begin(), v0.end());auto max_iter = max_element(v0.begin(), v0.end());cout << "minimum: " << *min_iter << endl;cout << "maximum; " << *max_iter << endl;//max and min_same timeauto ans = minmax_element(v0.begin(), v0.end());cout << "minimum; " << *(ans.first) << endl;cout << "maximum: " << *(ans.second) << endl;double avg1 = accumulate(v0.begin(), v0.end(), 0.0) / v0.size();cout << "average: " << fixed << setprecision(2) << avg1 << endl;sort(v0.begin(), v0.end());double avg2 = accumulate(v0.begin() + 1, v0.end() - 1, 0.0) / (v0.size() - 2);cout << "average without max and min: " << avg2 << endl;
}
运行测试结果
问题回答
问题1
generate算法的作用是调用传入的可调用对象生成数据,填充传入的[First,Last)这个范围内的元素。
问题2
minmax_element在获取最大值和最小值时,只需要遍历一次该动态数组,运行效率更高,代码更为紧凑;同时,minmax_element可保证最小元素和最大元素是基于同一轮遍历的容器状态得到的,单次遍历可防止容器被以外修改造成影响。
问题3
lambda表达式是一种匿名函数,[]内是捕获列表,指定lambda可访问的外部变量;()内是参数列表,用于接收传入的参数;-> return-type指定函数返回值类型,简单情况可省略,复杂情况下需要显式指定;{}内是函数体。lambda可以在需要函数的地方直接定义和使用,无需提前声明,可在需要临时使用简单逻辑处使用,省去了另写一个函数的麻烦,可与sort这类的STL算法结合,简化回调逻辑。
实验3
源代码
#include <iostream>
#include <string>
#include <algorithm>
#include <cctype>unsigned char func(unsigned char c);void test1();
void test2();int main()
{std::cout << "test1: string caps switch\n";test1();std::cout << '\n';std::cout << "test2: char switch\n";test2();
}unsigned char func(unsigned char c)
{if (c == 'z')return 'a';if (c == 'Z')return 'A';if (isalpha(c))return static_cast<unsigned char>(c + 1);return c;
}void test1()
{using namespace std;string s1{ "Hello World 2077!" };cout << "s1 = " << s1 << endl;string s2;for (auto& c : s1)s2 += tolower(c);cout << "s2 = " << s2 << endl;string s3;for (auto& c : s1)s3 += toupper(c);cout << "s3 = " << s3 << endl;
}void test2()
{using namespace std;string s1{ "Long Live The Republic!" };cout << "s1 = " << s1 << endl;string s2(s1.size(),' ');transform(s1.begin(), s1.end(), s2.begin(), func);cout << "s2 = " << s2 << endl;
}
运行测试结果
问题回答
问题1
func的功能是:如果传入的字符是字母,则返回该字母后的一个字母,z(Z)则循环至a(A);否则,返回传入的字符。
问题2
tolower的功能是将字母字符变为小写字母,toupper的功能是将字母字符变为大写字母。
问题3
transform函数第一、二个参数分别是被操作区域的起始、结束位置,第三个参数是函数的输出目标位置,第四个参数是执行操作的函数指针。若把第三个参数改为s1.begin()则相当于在原容器中执行转化操作,会更改原有数据。
实验4
源代码
include
include
include
bool is_palindrome(const std::string& s);
bool is_palindrome_ignore_case(const std::string& s);
int main()
{
using namespace std;
string s;
while (cin >> s)
{cout << boolalpha<< "case: " << is_palindrome(s) << endl<< "ignore_case: " << is_palindrome_ignore_case(s) << endl << endl;
}
}
bool is_palindrome(const std::string& s)
{
using namespace std;
string s0(s.size(),' ');
reverse_copy(s.begin(), s.end(), s0.begin());
if (s == s0)
return true;
return false;
}
bool is_palindrome_ignore_case(const std::string& s)
{
using namespace std;
string s1;
for (auto& c : s)
{
s1 += tolower(c);
}
string s2(s1.size(), ' ');
reverse_copy(s1.begin(), s1.end(), s2.begin());
if (s1 == s2)
return true;
return false;
}
运行测试结果
问题回答
可用getline(cin,s)以输入含空格的字符串
实验5
源代码
#include <iostream>
#include <string>
#include <algorithm>std::string dec2n(int x, int n = 2);int main()
{using namespace std;int x;while (cin >> x){cout << "十进制" << x << endl<< "二进制" << dec2n(x) << endl<< "八进制" << dec2n(x, 8) << endl<< "十二进制" << dec2n(x, 12) << endl<< "十六进制" << dec2n(x, 16) << endl<< "三十二进制" << dec2n(x, 32) << endl << endl;}return 0;
}
std::string dec2n(int x, int n)
{std::string list{ "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" };std::string res;while (x != 0){res += *(list.begin() + x % n);x /= n;}reverse(res.begin(), res.end());return res;
}
运行测试结果
实验6
源代码
#include <iostream>
#include <string>
#include <iomanip>int main()
{using namespace std;string list{ "abcdefghijklmnopqrstuvwxyz" };string s0;cout << setw(2) << ' ';for (auto& i : list){cout << setw(2) << i;s0 += toupper(i);}cout << endl;for (int i = 1; i <= 26; i++){cout << setw(2) << i;string s1{ s0 };rotate(s1.begin(), s1.begin() + i % 26, s1.end());for (auto& j : s1)cout << setw(2) << j;cout << endl;}return 0;
}
运行测试结果
实验7
源代码
#include <iostream>
#include <ctime>
#include <iomanip>
#include <Windows.h>
enum math
{plus = 0,minus,multiply,divide
};
int generate();
int main()
{using namespace std;srand(time(0));//get seed of randomdouble cnt = 0;for (int i = 1; i <= 10; i++){int ans;int res = generate();cin >> ans;if (ans == res)cnt++;}cnt *= 10;cout << "正确率为: ";cout << fixed << setprecision(2) << cnt << '%';return 0;
}int generate()
{using namespace std;int op = []() {return std::rand() % 4; }();int a, b, res;switch (op){case 0:a = []() {return std::rand() % 10 + 1; }();Sleep([]() {return std::rand() % 10 + 1; }());b = []() {return std::rand() % 10 + 1; }();res = a + b;cout << a << ' ' << '+' << ' ' << b << ' ' << '=' << ' ';break;case 1:a = []() {return std::rand() % 10 + 1; }();Sleep([]() {return std::rand() % 10 + 1; }());b = [a]() {return std::rand() % a + 1; }();res = a - b;cout << a << ' ' << '-' << ' ' << b << ' ' << '=' << ' ';break;case 2:a = []() {return std::rand() % 10 + 1; }();Sleep([]() {return std::rand() % 10 + 1; }());b = []() {return std::rand() % 10 + 1; }();res = a * b;cout << a << ' ' << '*' << ' ' << b << ' ' << '=' << ' ';break;case 3:a = []() {return std::rand() % 10 + 1; }();Sleep([]() {return std::rand() % 10 + 1; }());while (1){b = [a]() {return std::rand() % a + 1; }();if (a % b == 0)break;}res = a / b;cout << a << ' ' << '/' << ' ' << b << ' ' << '=' << ' ';break;}return res;
}