实验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);
}

 

运行结果截图:

image

问题:

reverse:原地反转,直接修改原容器。
reverse_copy:复制反转,不改变原容器,将反转结果复制到新容器中。
改变顺序:以中间迭代器为界,将后半部分元素移到前面,前半部分移到后面(循环左移)。
 三个参数:first(区间起点),middle(旋转分界点,旋转后成为新首元素),last(区间终点)。

 

 

任务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;
}

 

 运行结果截图:

屏幕截图 2026-10-22 223030

问题:

1. 遍历指定区间,将无参函数的返回值依次赋值给区间内的每个元素(常用于填充数据)。

2.效率更高:只需遍历一次容器,就能同时找到最大值和最小值,减少了遍历次数。

3.适用于简短、只用一次的代码逻辑,无需单独定义函数,使代码更紧凑直观(如示例中的生成随机数)。

 

 

任务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';
}

运行结果截图:

屏幕截图 2026-10-22 224237

问题:

1.将字母替换为字母表中的下一个字母('z'变'a','Z'变'A'),非字母字符不变。

2.tolower:将大写字母转为小写。
   toupper:将小写字母转为大写。

3.改为 s1.begin() 会将转换结果直接覆盖到原字符串 s1 上(原地修改);使用 s2.begin() 则是将结果存入新字符串,不改变原串。

 

任务4

源代码task4.cpp

#include <iostream>
#include <string>
#include <algorithm>

bool is_palindrome(const std::string &s) {
    return std::equal(s.begin(), s.begin() + s.size() / 2, s.rbegin());
}

bool is_palindrome_ignore_case(const std::string &s) {
    std::string s_lower = s;
    std::transform(s_lower.begin(), s_lower.end(), s_lower.begin(), ::tolower);
    return is_palindrome(s_lower);
}

int main() {
    using namespace std;
    string s;
    while(cin >> s) {
        cout << "区分大小写: " << (is_palindrome(s) ? "true" : "false") << "\n"
             << "不区分大小写: " << (is_palindrome_ignore_case(s) ? "true" : "false") << "\n\n";
    }
    return 0;
}

运行结果截图:

屏幕截图 2026-10-22 224921

思考:输入带空格的字符串不能用 cin >> s,应该用 getline(cin, s),它会读取整行直到遇到换行符。

 

任务5

源代码task5.cpp

#include <iostream>
#include <string>
#include <algorithm>

std::string dec2n(int x, int n = 2) {
    if (x == 0) return "0";
    std::string res;
    const char digits[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    while (x > 0) {
        res += digits[x % n];
        x /= n;
    }
    std::reverse(res.begin(), res.end());
    return res;
}

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

运行结果截图:

屏幕截图 2026-10-22 225244

 

 

任务6

源代码tassk6.cpp

#include <iostream>

int main() {
    char letters[] = "abcdefghijklmnopqrstuvwxyz";
    std::cout << "  " << letters << '\n';
    for (int i = 1; i <= 26; ++i) {
        if (i < 10) std::cout << ' ';
        std::cout << i << ' ';
        for (int j = 0; j < 26; ++j) {
            char upper_c = static_cast<char>('A' + (j + i - 1) % 26);
            std::cout << upper_c;
        }
        std::cout << '\n';
    }
    return 0;
}

运行结果截图:

屏幕截图 2026-10-22 225453

 

 

任务7

源代码task7.cpp

#include <iostream>
#include <cstdlib>
#include <ctime>
#include <iomanip>

int main() {
    std::srand(std::time(0));
    int correct_count = 0;
    char ops[] = {'+', '-', '*', '/'};

    for (int i = 0; i < 10; ++i) {
        int a = std::rand() % 10 + 1;
        int b = std::rand() % 10 + 1;
        char op = ops[std::rand() % 4];
        int ans = 0;

        if (op == '-') {
            if (a < b) std::swap(a, b);
            ans = a - b;
        } else if (op == '/') {
            ans = a / b; 
            a = ans * b; 
        } else if (op == '+') {
            ans = a + b;
        } else if (op == '*') {
            ans = a * b;
        }

        std::cout << a << " " << op << " " << b << " = ";
        int user_ans;
        std::cin >> user_ans;

        if (user_ans == ans) {
            correct_count++;
        }
    }

    double accuracy = (double)correct_count / 10.0 * 100;
    std::cout << "正确率: " << std::fixed << std::setprecision(2) << accuracy << "%" << std::endl;

    return 0;
}

运行结果截图:

屏幕截图 2026-10-22 225824

 

 

实验总结:这次实验让我感觉C++比C语言写起来省事多了。不用自己费劲写循环去处理数组和字符串,直接调用现成的vector、string和自带的算法(比如排序、反转)就能轻松搞定,代码又短又好读。我还体验了Lambda表达式和自动循环这些新写法,确实很灵活。不过也踩了点小坑,比如混用cin和getline读数据时会出错,得加ignore清理一下。总的来说,这次实验让我初步摸到了C++方便高效的编程路子。

 

 

 

posted @ 2026-10-22 23:02  温水A  阅读(0)  评论(0)    收藏  举报