实验一:现代C++初体验
实验一
源代码
#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 << "测试1: \n";
test1();
std::cout << "\n测试2: \n";
test2();
std::cout << "\n测试3: \n";
test3();
}
template <typename T>
void output(const T &c) {
for(auto &i : c)
std::cout << i << ' ';
std::cout << '\n';
}
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);
}
运行截图

问题回答
reverse函数会把输入的字符串进行反转操作;reverse_copy函数则是把输入的字符串单独复制一份进行反转,不改变原字符串顺序。rotate函数在置入字符串的头部与尾部后可以通过设定中间的形参来控制字符串移动相应的位数,其中begin+n则跳过n个字符作为首位,跳过的字符到最后;end-n则尾部n个字符优先排在队伍首位。
实验二
源代码
#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;
}
运行截图

问题回答
generate函数规定了动态数组的头尾位置后,第三个参数则为每一位的值的设定规则,在代码中,使用的是随机数生成,则v0,v1,v2则为随机数组成的动态数组;minmaxelement函数的优势在于一次性将最大值最小值分别计算好,不需要额外申请两个辅助变量,只需要一个即可,减轻了编写者的工作量;- 首先,lambda表达式指的是Lambda表达式是一种在被调用的位置或作为参数传递给函数的位置定义匿名函数对象(闭包)的简便方法,
[capture list] (parameter list) -> return type { function body }在目前情况下,lambda表达式和额外编写函数的效果雷同,更为方便。
实验三
源代码
#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;
}
运行结果

问题回答
func函数将字符进行加密,加密方法为所有字符(除了z)后移一个字符的凯撒变换;z变成a,这是特殊情况。tolower的功能是将字母字符变为小写字母,toupper的功能是将字母字符变为大写字母。- 第一个:从哪里开始;第二个:到哪里结束;第三个:开始执行的位置;第四个:传递时附加的规则;改变后,会在原始容器内部执行操作。
实验四
源代码
#include <iostream>
#include <string>
#include <algorithm>
#include <cctype>
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
<< "区分大小写:" << is_palindrome(s) << "\n"
<< "不区分大小写:" << is_palindrome_ignore_case(s) << "\n\n";
}
}
// 以下两个函数需要补全
bool is_palindrome(const std::string &s) {
using namespace std;
string t=s;
reverse(t.begin(),t.end()) ;
if(t.compare(s)==0){
return true;
}
else{
return false;
}
}
bool is_palindrome_ignore_case(const std::string &s) {
using namespace std;
string t=s,sl;
for(auto i : s){
sl+=tolower(i);
}
reverse(t.begin(),t.end()) ;
string tl;
for(auto i : t){
tl+=tolower(i);
}
if(tl.compare(sl)==0){
return true;
}
else{
return false;
}
}
运行截图

问题回答
- 如果需要可以将字符串整体后移一个字符进行比对。
实验五
源代码
#include <iostream>
#include <string>
#include <algorithm>
std::string dec2n(int x, int n = 2);
int main() {
int x;
while(std::cin >> x) {
std::cout << "十进制: " << x << '\n'
<< "二进制: " << dec2n(x) << '\n'
<< "八进制: " << dec2n(x, 8) << '\n'
<< "十二进制: " << dec2n(x, 12) << '\n'
<< "十六进制: " << dec2n(x, 16) << '\n'
<< "三十二进制: " << dec2n(x, 32) << "\n\n";
}
}
// 以下函数需要补全
std::string dec2n(int x, int n) {
int t;
std::string res;
while (x > 0)
{
t = x % n;
if (t<10)
{
res += (char)(t + '0');
}
else
{
res += (char)(t - 10 + 'A');
}
x /= n;
}
std::reverse(res.begin(), res.end());
return res;
}
测试截图

实验六
源代码
#include <iostream>
#include <iomanip>
#include <string>
#include <algorithm>
using namespace std;
int main(){
string s{"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 "};
cout << " " << s << endl;
string t;
for (auto i:s)
{
t+=toupper(i);
}
for (int i = 1; i <= 26; i++)
{
cout << setw(2) << i << " ";
rotate(t.begin(), t.begin() + 2, t.end());
cout << t << endl;
}
}
运行截图

实验七
源代码
#include <iostream>
#include <iomanip>
#include <string>
#include <algorithm>
#include <ctime>
#include <cstdlib>
#include <vector>
int main(){
std::srand(std::time(0));
using namespace std;
enum calculator {ADD=1, SUB, MUL, DIV};
int ans = 0;
int co = 0;
for(int i=0; i<10; i++){
int a = std::rand() % 10+1;
int b = std::rand() % 10+1;
int op = std::rand() % 4 + 1;
switch(op){
case ADD:
cout << a << " + " << b << " = ";
cin >> ans;
if(ans == a+b) co+=1;
break;
case SUB:
if (a<b)
{
i--;
continue;
}
cout << a << " - " << b << " = ";
cin >> ans;
if(ans == a-b) co+=1;
break;
case MUL:
cout << a << " * " << b << " = ";
cin >> ans;
if(ans == a*b) co+=1;
break;
case DIV:
if (a%b!=0)
{
i--;
continue;
}
cout << a*b << " / " << b << " = ";
cin >> ans;
if(ans == a) co+=1;
}
}
cout << "正确率:" << (co/10.0)*100 << "%" << endl;
return 0;
}
运行截图

实验总结
- 个人认为C++相比C语言,一定程度上C++更加方便:有更多的封装函数使得程序员不需要额外编写基本函数,更好地实现功能;弊端在于函数与方法的语法没有很好的规范,导致好多函数需要额外记忆。
- 出现的函数如下:
一、标准库算法函数
1. 容器操作算法
reverse(begin, end):反转指定范围内的元素顺序
reverse_copy(src_begin, src_end, dest_begin):将反转后的结果复制到目标容器,原容器不变
rotate(begin, middle, end):循环移动元素,使middle成为新的第一个元素
sort(begin, end):对指定范围进行升序排序
generate(begin, end, generator):用生成器函数填充容器元素
2. 数值计算算法
accumulate(begin, end, init):计算范围内元素的累加和
min_element(begin, end):返回最小元素的迭代器
max_element(begin, end):返回最大元素的迭代器
minmax_element(begin, end):同时返回最小和最大元素的迭代器对
3. 字符串转换算法
transform(src_begin, src_end, dest_begin, op):对范围内每个元素应用操作函数
tolower(c):将字符转换为小写
toupper(c):将字符转换为大写

浙公网安备 33010602011771号