实验1 现代C++编程初体验

实验任务1

源代码 task1.cpp


#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);
}

运行结果截图:

屏幕截图 2025-10-12 204504

观察与思考:

1.reverse 和 reverse_copy 有什么区别?

reverse函数将给定范围内的元素反转,而reverse_copy是将给定范围内的元素反转并复刻到另一范围内但不改变源范围内的元素顺序。

2.rotate 算法是如何改变元素顺序的?它的三个参数分别代表什么?

rotate将范围内的元素分割为两部分,在不改变前后两部分内元素顺序的前提下,将后半部分与前半部分交换位置,实现循环旋转。第一个参数为序列起始点,第二个为旋转点,第三个为序列终点。

 

实验任务2

源代码 task2.cpp

#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)); 
    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;
}

运行结果截图:

屏幕截图 2025-10-12 212152

观察与思考:

1.generate 算法的作用是什么?

generate算法用于产生一个在0到100内的随机数。

2.minmax_element 和分别调用 min_element 、 max_element 相比,有什么优势?

minmax_element 相比于min_element 、 max_element ,它仅需对序列进行一次遍历就可以得到最大值和最小值,效率比较高。
3.题目略
Lambda 表达式是 C++11 引入的一种匿名函数,它允许在代码中就地定义一个可调用对象(函数对象),而无需为其显式定义函数名。修改后的代码与修改前的代码效果相同。
 
实验任务3
源代码 task3.cpp
#include <iostream>
#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';
}

运行结果截图:

屏幕截图 2025-10-12 214850

观察与思考:

1.自定义函数 func 功能是什么?

func函数将传递来的字母转化为下一个字母,将字母z转化为a,字母Z转化为字母A,实现字母表的循环。

2.tolower 和 toupper 功能分别是什么?

tolower将给定字母转化为小写形态,若本身为小写,则直接返回。toupper将给定字母转化为大写形态,若本身为大写,则直接返回。

3.transform 的4个参数意义分别是什么?如果把第3个参数 s2.begin() 改成 s1.begin() ,有何区别?

第1、2个参数为一段序列的起始点和终点,第3个参数是一个新范围的起始点,第4个参数是一个操作,能接受原范围内的一个元素并将操作结果返回。

修改后操作的结果将直传给原范围s1,s2依旧是和s1等长的一段空序列。

 

实验任务4

源代码 task4.cpp

#include <iostream>
#include <string>
#include <algorithm>
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){
    std::string s1(s.size(), ' ');
    reverse_copy(s.begin(), s.end(), s1.begin());
    if(s1 == s)
        return true;
    else 
        return false;
}

bool is_palindrome_ignore_case(const std::string &s){
    std::string s1, s2;
    for(auto c: s)
        s1 += toupper(c);
    s2 = s1;
    reverse(s2.begin(), s2.end());
    if(s1 == s2)
        return true;
    else 
        return false;
}

运行结果截图:

屏幕截图 2025-10-12 230528

观察与思考:

使用 cin >> s 输入时,输入的字符串中不能包含空格。如果希望测试字符串包含空格(如 hello oop ),代码应如
何调整?
可以使用getline函数,将cin>>s改为getline(cin, s)。
 
实验任务5
源代码 task5.cpp
#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 ){
    std::string s;
    
    if(x == 0)
        return "0";
    while(x > 0){
        if(x % n <= 9){
            s += x%n + 48;
            x /= n;
        }
        else{
            s += x%n+55;
            x /= n;
        }    
    }
    reverse(s.begin(), s.end());
    return s;
}

运行结果截图:

屏幕截图 2025-10-12 234153

 

实验任务6

源代码 task6.cpp

#include <iostream>
#include <string>
#include <algorithm>
#include <iomanip> 
#include <cctype>

void show(){
    using namespace std;
    string s{ "ABCDEFGHIJKLMNOPQRSTUVWXYZ" };
    cout << "  ";
    for(auto c: s) 
        cout << " " << static_cast<char>(tolower(c));
    cout << "\n";
    for(int i = 1; i <= 26; i++){
        rotate(s.begin(), s.begin()+1, s.end());
        cout << right << setw(2) << i;
        for(auto c1: s)
        cout << " " << c1;
        cout << "\n"; 
    }
    
}
int main() {
    show();
}

运行结果截图:

屏幕截图 2025-10-13 163851

 

实验任务7

源代码 task7.cpp

#include <iostream>
#include <vector>
#include <algorithm>
#include <numeric>
#include <iomanip>
#include <cstdlib>
#include <ctime>

int generate_number();
char generate_operator(std::string &s);
int given();

int main(){
using namespace std;
srand(time(0));
int count = 0, result, r;
for(auto i = 1; i < 11; i++)
{
result = given();
cin >> r;
if(r == result)
count++;
}
cout << "正确率:" << fixed << setprecision(2) << static_cast<double>(count*10) << "%";
}

int generate_number(){
return std::rand() % 10 + 1;
}

char generate_operator(std::string &s){
return s[std::rand() % 4];
}

int given(){
using namespace std;
char c;
int a, b;
std::string op{"*/+-"};
c = generate_operator(op);
a = generate_number(), b = generate_number();
if(c == '/')
{

while(a%b != 0)
a = generate_number(), b = generate_number();
cout << a << " " << c << " " << b << " = ";
return a/b;
}
else if(c == '-'){
while(a < b)
a = generate_number(), b = generate_number();
cout << a << " " << c << " " << b << " = ";
return a-b;
}
else if(c == '+'){
cout << a << " " << c << " " << b << " = ";
return a+b;
}
else{
cout << a << " " << c << " " << b << " = ";
return a*b;
}
}

 

运行结果截图:

屏幕截图 2025-10-13 190720

屏幕截图 2025-10-13 190810

 

posted @ 2025-10-13 19:10  不吃虾仁饭  阅读(11)  评论(1)    收藏  举报