实验1_实验报告

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

四、实验结论

1. 实验任务1

运行测试截图

image

问题与思考

  1. reverse 和 reverse_copy 有什么区别?

    reverse和reverse_copy都是algorithm库中提供的算法。string通过begin和end取字符串的处理范围。

    其中,reverse是在字符串的原地反转,直接修改原对象;而reverse_copy是将源字符串反转以后,放入第三个参数指定的字符串的
    开头。而新的容器需要提前指定空间来存放倒置的字符串。

    对于vector,同样的原理,使用后者一样要提前开辟空间。

  2. rotate 算法是如何改变元素顺序的?它的三个参数分别代表什么?
    rotate的三个参数分别是first,middle,last,其实质是迭代器(类似于指针,指向元素的位置)。rotate将first-middle,middle-last的元素进行反转。如果追究内部的实现,可以理解成1)在first-middle内部,middle-last内部分别进行反转,然后在整体first-last反转。

    如果形象理解三个参数的话,分别可以是:旋转范围的起点,旋转后第一个元素的位置,旋转范围的终点

2. 实验任务2

运行测试截图

image-2

问题与思考

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

    generate算法根据三个参数:生成的起始和终止位置,以及用于生成的函数。通过生成函数的返回值,在指定的容器的范围内生成元素。

  2. minmax_element 和分别调用 min_element、max_element 相比,有什么优势?
    前者只需要一次便遍历,同时取得了最大最小值对应元素的迭代器,然后用迭代器皆因用得到最终元素。这样的效率更高,相当于把最大最小的迭代器组成了pair,在结构上也便于对问题的理解,简化了程序。

  3. 与自定义函数 generate_random_number 相比,lambda 表达式适合什么场景?
    lambda表达式直接写在使用位置且没有名称,相当于嵌入代码上下文逻辑的一个函数体。
    这种嵌入的架构带来便利也就是:只使用一次、代码较短、逻辑比较简单的场景使用非常简练,而且lambda还可以通过[]捕获列表,直接在代码块内部捕获参数值甚至通过&引用来在代码块内部修改参数。如果整个代码的思路是一体的,那么使用lambda表达式非常合适,方便且符合理解的逻辑。

    相比generate_random_number这样在外部声明的函数可复用,具有解耦的特性,lambda更加简洁快速,而且便于集成。

3. 实验任务3

运行测试截图

image-3

问题与思考

  1. 自定义函数 func 的功能是什么?
    func中,一般情况下,使用isalpha(包含在cctype中)判断输入是否是字符。

    unsigned char是为了让所有字节都保持非负,并能够传递给isalpha。

    对于字母表的结尾Z,z需要进行循环转换的补充。这样实现了字符向后变换一个的功能。

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

    分别将字符转换成对应的小写、大写形式。

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

    第一、二个参数代表原始数据的范围,第三个参数代表转换后的对象放入的容器的开始位置,第四个参数代表转换使用的函数

    操作发现,如果改动,那么s2输出为空,s1输出为转换后的对象。应证了对于第三个参数意义的判断,此时s1转换后的对象又存入s1。

4. 实验任务4

源代码

bool is_palindrome(const std::string &s) {
    (void)s;
    using namespace std;
    string s1(s);
    reverse(s1.begin(),s1.end());
    
    return s1==s;   
}

bool is_palindrome_ignore_case(const std::string &s) {
    (void)s;
    using namespace std;
    string s1(s);
    string s2(s);
    transform(s1.begin(),s1.end(),s1.begin(),::tolower);
    reverse(s1.begin(),s1.end());
    transform(s2.begin(),s2.end(),s2.begin(),::tolower);

    return s1==s2;
}

运行测试截图

image-4

问题与思考

使用 cin >> s 时无法输入含空格的字符串。如果需要测试 hello oop,代码应如何调整?
可以使用getline(cin,s)来读取包含空格的输入

 while (getline(cin, s)) {

image-5

5. 实验任务5

源代码

std::string dec2n(int x, int n) {
    (void)x;
    (void)n;
    using namespace std;
    if(x==0){
        return "0";
    }
    if(n<2||n>36){
        throw logic_error("进制数n必须在[2,36]区间内");
    }
    vector<int> v;
    vector<char> v1;
    while(x>0){
        v.push_back(x%n);
        x/=n;
    }
    while(!v.empty()){
        int i = v.back();
        v.pop_back();
        if(i>=10){
            v1.push_back(static_cast<char>('A'+i-10));
        }else{
            v1.push_back(static_cast<char>('0'+i));
        }
    }

    return string(v1.begin(),v1.end());

}

运行测试截图

image-6

6. 实验任务6

源代码

#include <iostream>
using namespace std;
void printcode();
int main() {
    printf("  ");
    for(char i='a';i<='z';i++)
    {
        printf("%2c",i);
    }
    printf("\n");
    printcode();

    return 0;
}
void printcode()
{
    vector<char> v(26);
    for(int i=0;i<26;i++)
    {
        v[i]='A'+i;
    }
    for(int i=1;i<=26;i++)
    {
        rotate(v.begin(),v.begin()+1,v.end());
        printf("%2d",i);
        for(int j=0;j<26;j++)
        {
            printf("%2c",v[j]);
        }
        printf("\n");
    }

    return;
}

运行测试截图

image-7

7. 实验任务7

源代码

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

using namespace std;

int main() {
    // TODO(学生): 完成10道随机四则运算题的生成、输入、评测和正确率输出。
    // 要求摘要:
    // - 操作数为 [1, 10] 的整数,运算符为 + - * /。
    // - 减法的第一个操作数 >= 第二个操作数。
    // - 除法必须整除。
    // - 正确率以百分数输出,保留两位小数。
    // - 可用 std::srand(std::time(nullptr)) 设置随机种子。
    
    int count = 0;
    for(int i=0;i<10;i++)
    {
        srand(time(nullptr));
        int a = rand()%10+1;
        int b = rand()%10+1;
        int op = rand()%4;
        int ans;
        char op_char;
        switch (op) {
    case 0:
        ans = a + b;
        op_char = '+';
        break;

    case 1:
        if (a < b) {
            swap(a, b);
        }
        ans = a - b;
        op_char = '-';
        break;

    case 2:
        ans = a * b;
        op_char = '*';
        break;

    case 3: {
        b = rand() % 10 + 1;
        int q = rand() % (10 / b) + 1;
        a = b * q;
//10/b表示最大商,+1表示从1开始,然后同样得到在最大商到1的随机数
        ans = q;
        op_char = '/';
        break;
    }
}   
        cout << "第" << i + 1 << "题: " << a << ' ' << op_char << ' ' << b << " = ";
        int user_ans;
        cin >> user_ans;
        if (user_ans == ans) {
            count++;
        } 
    }
    printf("正确率: %.2f%%\n", (count / 10.0) * 100);
}

运行测试截图

image-8

五、实验总结

1.学习到了新的概念:迭代器,rotate,reverse,reverse_copy通过迭代器实现容器内元素的变换

2.task5:结合数据结构课上学到的栈先进先出的特点,使用栈完成了进制转换的实现。但是仍有疑问:是不是可以不使用整个容器进行存储,直接将输出拼接到字符串的末尾呢?源代码开了两个vector是否有必要?

3.task7:在实现除法出题时,考虑还可以把所有情况进行枚举,因为数据量很小

posted @ 2026-10-18 15:43  Morever11  阅读(7)  评论(0)    收藏  举报