文章中涉及到的是某互联网知名大厂的面试最后一题,文中有详细的函数实现以及注释,文末有整个工程的完整可运行代码,如果觉得不错,麻烦给博主来个一键三连+评论区互动,谢谢各位
题目要求:
定义一个Student的结构体,包含name和age两个成员,用vector对Student对象进行管理。
1、实现init函数,向vector中放入三个student元素(“Siri”, 17), (“Xiaoai”, 20), (“Xiaoyi”, 19);
2、实现sort_student函数,对vector中所有student对象按照年龄从小到大排序
3、实现add_student函数,可以让外部调用往vector中增加一个student,增加一个(“Siri”, 18)
4、实现delete函数,可以让外部调用删除指定名字的所有student,删除所有名字叫Siri的student
开始解答:
定义结构体:
typedef struct _STUDENT_ { string name;//姓名 int age;//年龄 }STUDENT, *PSTUDENT;
我们来定义一个结构体,默认其中包括两个成员,一个是姓名,一个是年龄,姓名是string类型,年龄是int类型。
完成第一个要求,实现init函数,在其中完成三个成员的初始化工作:
/* 函数是用来初始化三个成员,并且将成员存放到vector数组中去 参数:vector<STUDENT>& Parameter 是外部传参的引用,改变这个参数, 也就是改变外部的那个实参 */ void Init(vector<STUDENT>& Parameter) { STUDENT student_1[3];//用来存放三个学生的信息 student_1[0].name = "Siri"; student_1[0].age = 17; student_1[1].name = "Xiaoai"; student_1[1].age = 20; student_1[2].name = "Xiaoyi"; student_1[2].age = 19; for (int i = 0; i < 3; i++) { Parameter.push_back(student_1[i]);//向vector数组中压入参数 } }
我们用以上函数完成对vector数组的初始化工作。注意参数是引用类型,也就意味着形参的改变会直接影响到实参的值。
接着我们实现sort_student的的,把vector数组中的成员按照age大小,从小到大排序:
/* 函数用来对vector数组进行排序 参数:vector<STUDENT>& Parameter 是外部传参的引用,改变这个参数, 也就是改变外部的那个实参 */ void sort_student(vector<STUDENT>& Parameter) { //sort函数是algorithm库下的一个函数,用来实现比较排序的功能 sort(Parameter.begin(), Parameter.end(), compare);//注意该函数的第三参数是函数指针 } /* 函数用来对比较年龄大小,并且返回比较结果 参数1:const STUDENT& a 是一个常量引用 参数2:const STUDENT& a 是一个常量引用 返回值:bool类型,是true或者false */ bool compare(const STUDENT& a, const STUDENT& b) { return a.age < b.age; }
我们使用algorithm中的sort函数,来进行年龄大小的比较并排序,在这个函数执行之后,所有的成员按照年龄由小到大排序。
实现add_student的要求,对vector中添加新的学生成员(“Siri”, 18),代码如下:
/* 函数实现对外部变量的添加功能,通过传入的参数,将新成员增加到vector数组中 参数1:vector<STUDENT>& Parameter 是外部传参的引用,改变这个参数, 也就是改变外部的那个实参 参数2:const char* name 常量字符指针,用来传输外部新增成员的名字 参数3:int age 年龄,外部输入新增成员的年龄 */ void add_student(vector<STUDENT>& Parameter, const char* name,int age) { STUDENT Student; Student.name = name; Student.age = age; Parameter.push_back(Student); sort_student(Parameter);//加入完学生的信息,再次进行排序 }
我们通过传参来把需要新增的学生信息传递进来之后,在里面声明局部结构体变量用来存放这些信息,最后压入vector数组中之后,将学生进行再次排序。
实现delete函数,让外部调用删除所有名字叫Siri的student:
/* 函数实现了对指定学生的删除,通过姓名来搜索匹配,最终进行删除 参数1:vector<STUDENT>& Parameter 是外部传参的引用,改变这个参数, 也就是改变外部的那个实参 参数2:const char* name 常量字符指针,用来存放需要删除的学生姓名 返回值:bool类型,是为了告诉调用者是否删除成功 */ bool delete_student(vector<STUDENT>& Parameter, const char* name) { bool IsOk = false; //for循环中涉及到了vector的迭代器的使用,也就是vector<STUDENT>::iterator v1 //一定要小心“野”迭代器的发生,所以for循环的++操作,被我放在了ifelse语句中 for (vector<STUDENT>::iterator v1 = Parameter.begin(); v1 != Parameter.end();) { //比较名字是否和我们要删除的一致 if (strcmp((*v1).name.c_str(), name) == 0) { IsOk = true; //返回的就是删除之后的一个元素 v1 = Parameter.erase(v1);//进行数据擦除 //被erase之后变成了一个“野迭代器”,对其进行++操作会发生奔溃 } else { v1++; } } return IsOk; }
其实delete的实现,是最需要主义的一个地方,因为其中涉及到野迭代器的问题,就是使用vector::erase之后,会把当前数组的下一个迭代器作为返回值返回,而当前迭代器因为erase操作已经变得失效了,是一个野迭代器,直接进行++操作会导致程序崩溃。
对于面试题的基本要求其实已经完成了,然后我又写了个改和查的功能,毕竟既然写了增和删,就顺便写个改和查吧,其实改和查相比起删除来说,还是有点像的,话不多说,先看一个修改信息的代码:
bool change_student(vector<STUDENT>& Parameter, const char* old_name, const char* new_name = "default", int new_age = 0); /* change_student函数是想修改之前已经存放好的信息,如果学生的姓名出错,可以修改,年龄出错也可以修改 参数1:vector<STUDENT>& Parameter 是外部传参的引用,改变这个参数, 也就是改变外部的那个实参 参数2:const char* old_name 需要信息的学生姓名 参数3:const char* new_name 需要改成的新的名字,默认值为default 参数4:int new_age 需要修改成的新年龄,默认值为0 返回值:bool类型,是为了告诉调用者是否删除成功 */ bool change_student(vector<STUDENT>& Parameter, const char* old_name, const char* new_name, int new_age) { bool IsOk = false; for (vector<STUDENT>::iterator v1 = Parameter.begin(); v1 != Parameter.end();) { if (strcmp((*v1).name.c_str(), old_name) == 0) { IsOk = true; if (strcmp(new_name, "default") != 0) { //看名字是否是需要修改,如果不为default 则需要修改 (*v1).name = new_name; } if (new_age != 0) { //看年龄是否是需要修改,如果不为0 则需要修改 (*v1).age = new_age; } v1++;//迭代器后移 } else { v1++; } } return IsOk; }
以上代码我列出了函数的声明和定义,声明时候出现了参数默认值,参数默认赋值的意思,就是说这些参数如果不传的话,是可以将默认值传入进去的。
最后再来一个根据学生姓名查找学生信息的函数,来完成我们这次代码的简单工作:
/* 函数实现了学生信息的查找,通过姓名来搜索匹配,最终输出结果 参数1:vector<STUDENT>& Parameter 是外部传参的引用,改变这个参数, 也就是改变外部的那个实参 参数2:const char* name 常量字符指针,用来存放需要查找的学生姓名 */ void find_student(vector<STUDENT>& Parameter, const char* name) { bool IsOk = false; for (vector<STUDENT>::iterator v1 = Parameter.begin(); v1 != Parameter.end();) { //比较名字是否和我们要查找的一致 if (strcmp((*v1).name.c_str(), name) == 0) { cout << "Student Name is " << name << endl; cout << "Student age is " << (*v1).age << endl; v1++;//迭代器后移 } else { v1++; } } }
就是很简单的从外部传入学生的姓名,然后使用迭代器对vector数组进行遍历,判断匹配之后,输出学生的信息。
完整可运行代码如下:
//头文件 main.h #pragma once #include<iostream> #include<string> #include<vector> #include<algorithm> using namespace std; typedef struct _STUDENT_ { string name; int age; }STUDENT, *PSTUDENT; void Init(vector<STUDENT>& Parameter); void add_student(vector<STUDENT>& Parameter, const char* name, int age); bool delete_student(vector<STUDENT>& Parameter, const char* name); void sort_student(vector<STUDENT>& Parameter); bool compare(const STUDENT& a, const STUDENT& b); bool change_student(vector<STUDENT>& Parameter, const char* old_name, const char* new_name = "default", int new_age = 0); void find_student(vector<STUDENT>& Parameter, const char* name);
//cpp main.cpp #include"main.h" /* 函数是用来初始化三个成员,并且将成员存放到vector数组中去 参数:vector<STUDENT>& Parameter 是外部传参的引用,改变这个参数, 也就是改变外部的那个实参 */ void Init(vector<STUDENT>& Parameter) { STUDENT student_1[3];//用来存放三个学生的信息 student_1[0].name = "Siri"; student_1[0].age = 17; student_1[1].name = "Xiaoai"; student_1[1].age = 20; student_1[2].name = "Xiaoyi"; student_1[2].age = 19; for (int i = 0; i < 3; i++) { Parameter.push_back(student_1[i]);//向vector数组中压入参数 } } /* 函数用来对vector数组进行排序 参数:vector<STUDENT>& Parameter 是外部传参的引用,改变这个参数, 也就是改变外部的那个实参 */ void sort_student(vector<STUDENT>& Parameter) { //sort函数是algorithm库下的一个函数,用来实现比较排序的功能 sort(Parameter.begin(), Parameter.end(), compare);//注意该函数的第三参数是函数指针 } /* 函数用来对比较年龄大小,并且返回比较结果 参数1:const STUDENT& a 是一个常量引用 参数2:const STUDENT& a 是一个常量引用 返回值:bool类型,是true或者false */ bool compare(const STUDENT& a, const STUDENT& b) { return a.age < b.age; } /* 函数实现对外部变量的添加功能,通过传入的参数,将新成员增加到vector数组中 参数1:vector<STUDENT>& Parameter 是外部传参的引用,改变这个参数, 也就是改变外部的那个实参 参数2:const char* name 常量字符指针,用来传输外部新增成员的名字 参数3:int age 年龄,外部输入新增成员的年龄 */ void add_student(vector<STUDENT>& Parameter, const char* name,int age) { STUDENT Student; Student.name = name; Student.age = age; Parameter.push_back(Student); sort_student(Parameter);//加入完学生的信息,再次进行排序 } /* 函数实现了对指定学生的删除,通过姓名来搜索匹配,最终进行删除 参数1:vector<STUDENT>& Parameter 是外部传参的引用,改变这个参数, 也就是改变外部的那个实参 参数2:const char* name 常量字符指针,用来存放需要删除的学生姓名 返回值:bool类型,是为了告诉调用者是否删除成功 */ bool delete_student(vector<STUDENT>& Parameter, const char* name) { bool IsOk = false; //for循环中涉及到了vector的迭代器的使用,也就是vector<STUDENT>::iterator v1 //一定要小心“野”迭代器的发生,所以for循环的++操作,被我放在了ifelse语句中 for (vector<STUDENT>::iterator v1 = Parameter.begin(); v1 != Parameter.end();) { //比较名字是否和我们要删除的一致 if (strcmp((*v1).name.c_str(), name) == 0) { IsOk = true; //返回的就是删除之后的一个元素 v1 = Parameter.erase(v1);//进行数据擦除 //被erase之后变成了一个“野迭代器”,对其进行++操作会发生奔溃 } else { v1++; } } return IsOk; } /* change_student函数是想修改之前已经存放好的信息,如果学生的姓名出错,可以修改,年龄出错也可以修改 参数1:vector<STUDENT>& Parameter 是外部传参的引用,改变这个参数, 也就是改变外部的那个实参 参数2:const char* old_name 需要信息的学生姓名 参数3:const char* new_name 需要改成的新的名字,默认值为default 参数4:int new_age 需要修改成的新年龄,默认值为0 返回值:bool类型,是为了告诉调用者是否删除成功 */ bool change_student(vector<STUDENT>& Parameter, const char* old_name, const char* new_name, int new_age) { bool IsOk = false; for (vector<STUDENT>::iterator v1 = Parameter.begin(); v1 != Parameter.end();) { if (strcmp((*v1).name.c_str(), old_name) == 0) { IsOk = true; if (strcmp(new_name, "default") != 0) { //看名字是否是需要修改,如果不为default 则需要修改 (*v1).name = new_name; } if (new_age != 0) { //看年龄是否是需要修改,如果不为0 则需要修改 (*v1).age = new_age; } v1++;//迭代器后移 } else { v1++; } } return IsOk; } /* 函数实现了学生信息的查找,通过姓名来搜索匹配,最终输出结果 参数1:vector<STUDENT>& Parameter 是外部传参的引用,改变这个参数, 也就是改变外部的那个实参 参数2:const char* name 常量字符指针,用来存放需要查找的学生姓名 */ void find_student(vector<STUDENT>& Parameter, const char* name) { bool IsOk = false; for (vector<STUDENT>::iterator v1 = Parameter.begin(); v1 != Parameter.end();) { //比较名字是否和我们要查找的一致 if (strcmp((*v1).name.c_str(), name) == 0) { cout << "Student Name is " << name << endl; cout << "Student age is " << (*v1).age << endl; v1++;//迭代器后移 } else { v1++; } } } int main() { vector<STUDENT> Student; Init(Student);//初始化三个学生的信息 sort_student(Student); add_student(Student, "Siri",18); delete_student(Student, "Siri"); change_student(Student, "Xiaoai","Xiaobu"); find_student(Student, "Xiaoyi"); return 0; }
还是那句话:如果喜欢博主的文章,关注之后,我们慢慢处。
今日励志句子 “You made a choice. Don’t look back.”