实验1_CPP
实验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 seed
std::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 time
auto 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 random
double 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;
}