实验1
任务一
代码
#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);
}
运行截图

回答问题
1.resverse是直接反转原数据,改变原容器里的内容,不需要额外的存储空间;resverse_copy是不改变原容器里的内容,而是将原数据反转后复制到一个新的容器中,需要新的存储空间。
2.rotate算法是将中间的数据移动到首位,原本前面的数据按序移动到后面,保持原先的相对顺序不变。
第一个参数是指起始位置,表示区间的开始;第二个参数是指新的起始元素位置;第三个参数是指结束的位置,是数据序列的末尾。
任务二
代码
#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));
std::cout<<"测试1: \n";
test1();
std::cout<<"\n测试2: \n";
test2();
}
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<<"最小值: "<<*min_iter<<endl;
cout<<"最大值: "<<*max_iter<<endl;
auto ans=minmax_element(v0.begin(),v0.end());
cout<<"最小值: "<<*(ans.first)<<endl;
cout<<"最大值: "<<*(ans.second)<<endl;
double avg1=accumulate(v0.begin(),v0.end(),0.0)/v0.size();
cout<<"均值: "<<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<<"去掉最大值、最小值之后,均值: "<<avg2<<endl;
}
运行截图

回答问题
1.generate算法的作用是指遍历指定的区间,并调用可调用对象返回给区间内的元素,可以生成随机数填到vector中。
2.maxmin_element的效率更高,可以在一次遍历中同时找到最大值和最小值,而分别调用需要遍历两次;并且使用maxmin_element所需要写的代码行数更少,更简洁。
3.效果等同;generate算法是第三个参数是可调用对象,替换后传入的是Lambda表达式,它可以定义一个没有名字的函数,接收0个参数返回0~100个随机数。
任务三
代码
#include<string>
#include<algorithm>
#include<cctype>
unsigned char func(unsigned char c);
void test1();
void test2();
int main()
{
std::cout<<"测试1:字符串大小转换\n";
test1();
std::cout<<"\n测试2:字符变换\n";
test2();
}
unsigned char func(unsigned char c)
{
if(c=='z')
return 'a';
if(c=='Z')
return 'A';
if(std::isalpha(c))
return static_cast<unsigned char>(c+1);
return c;
}
void test1()
{
std::string s1{"Hello world 2049!"};
std::cout<<"s1= "<<s1<<'\n';
std::string s2;
for(auto c: s1)
s2+=std::tolower(c);
std::cout<<"s2= "<<s2<<'\n';
std::string s3;
for(auto c: s1)
s3+=std::toupper(c);
std::cout<<"s3= "<<s3<<'\n';
}
void test2()
{
std::string s1{"I love cosmos!"};
std::cout<<"s1= "<<s1<<'\n';
std::string s2(s1.size(),' ');
std::transform(s1.begin(),s1.end(),s2.begin(),func);
std::cout<<"s2= "<<s2<<'\n';
}
运行截图

回答问题
1.func函数的功能是若传入的是小写字母z,返回a;大写Z,返回A;如果传入的是其他字母,将其ASCII码值加1,返回字母表中下一个字母
2.tolower(c)的功能是如果参数是大写字母,则返回其对应的小写字母;如果不是大写字母则返回原值。
toupper(c)的功能是如果参数是小写字母,则返回其对应的大写字母;如果不是小写字母则返回原值
3.第一个参数是指容器的起始迭代,第二个参数是指容器的结束迭代,第三个参数是指目标容器的起始位置,存放转换后的结果,第四个参数是指一个函数用来定义转换规则。如果将第三个参数改为s1.begin(),transform会将处理后的结果直接写回字符串s1,修改后s1的内容会改变而s2不变
任务四
代码
#include<string>
#include<algorithm>
#include<cctype>
using namespace std;
bool is_palindrome(const std::string &s);
bool is_palindrome_ignore_case(const std::string &s);
int main()
{
string s;
cout<<"输入字符串,按Ctrl+Z结束"<<endl;
while(cin>>s)
{
cout<<"区分大小写:"<<(is_palindrome(s)?"true":"false")<<"\n";
cout<<"不区分大小写:"<<(is_palindrome_ignore_case(s)?"true":"false")<<"\n\n";
}
return 0;
}
bool is_palindrome(const std::string &s)
{
string reversed_s=s;
reverse(reversed_s.begin(),reversed_s.end());
return s==reversed_s;
}
bool is_palindrome_ignore_case(const std::string &s)
{
string lower_s=s;
for(char &c:lower_s)
c=tolower(c);
return is_palindrome(lower_s);
}
运行截图

回答问题
使用cin>>s在读取数据时遇到空格会自动停止读取,使用getline()函数可以一直读取输入直到遇到换行符再停止,改为while(getline(cin,s)),可以将空格包含在字符串中。
任务五
代码
#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";
}
return 0;
}
std::string dec2n(int x,int n)
{
if(x==0)
return "0";
std::string result="";
std::string digits="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
while(x>0)
{
int remainder=x%n;
result+=digits[remainder];
x=x/n;
}
std::reverse(result.begin(),result.end());
return result;
}
运行截图

任务六
代码
#include<iomanip>
using namespace std;
int main()
{
cout << " ";
for (int i=0;i<26;i++)
{
char lower_char='a'+i;
cout<<lower_char<<" ";
}
cout<<endl;
for (int j=1;j<=25;j++)
{
cout<<setw(2)<<j<<" ";
for (int k=0;k<26;k++)
{
char upper_char='A'+(k+j)%26;
cout<<upper_char<<" ";
}
cout<<endl;
}
cout<<setw(2)<<26<<" ";
for(int i=0;i<26;i++)
{
cout<<char('A'+i)<<" ";
}
cout<<endl;
return 0;
}
运行截图

任务七
代码
#include<cstdlib>
#include<ctime>
#include<iomanip>
using namespace std;
int main()
{
srand(time(0));
int correct_count=0;
const int question=10;
for(int i=0;i<question;i++)
{
int num1,num2,answer;
int correct_answer;
int op;
op=rand()%4;
if(op==0)
{
num1=rand()%10+1;
num2=rand()%10+1;
correct_answer=num1+num2;
cout<<num1<<"+"<<num2<<"=";
}
else if(op==1)
{
num1=rand()%10+1;
num2=rand()%10+1;
if(num1<num2)
{
int t=num1;
num1=num2;
num2=t;
}
correct_answer=num1-num2;
cout<<num1<<"-"<<num2<<"=";
}
else if(op==2)
{
num1=rand()%10+1;
num2=rand()%10+1;
correct_answer=num1*num2;
cout<<num1<<"*"<<num2<<"=";
}
else
{
int a=rand()%10+1;
int b=rand()%10+1;
num1=a*b;
num2=a;
correct_answer=b;
cout<<num1<<"/"<<num2<<"=";
}
cin>>answer;
if(answer==correct_answer)
correct_count++;
}
double accuracy=(double)correct_count/question*100;
cout<<"正确率: ";
cout<<accuracy<<"%"<<endl;
return 0;
}
运行截图


实验总结
认识了Lambda函数,它可以接收0个参数返回0~100个随机数,在写代码的过程中更加简洁方便,了解了maxmin_element和min_element,max_element的区别以及优点,但是对部分函数和代码的理解还不准确

浙公网安备 33010602011771号