要求
- 不要使用STL
- 封装线性表类,提供插入,删除,查找等操作
- 线性表实现使用数组描述方法(顺序存储结构)
描述
设通讯录中每一个联系人的内容有:姓名、电话号码、班级、宿舍。由标准输入读入联系人信息,使用线性表中操作实现通讯录管理功能,包括:插入、删除、编辑、查找(按姓名查找);键盘输入一班级,输出通讯录中该班级中所有人的信息。
格式
每个操作的第一个数为操作数(插入-0,删除-1,编辑-2,查找-3,输出一个班所有人员信息-4),具体格式如下:
0 姓名 电话 班级 宿舍
插入一条记录1 姓名
根据姓名删除一条记录2 姓名 编辑项目 项目新值
根据姓名编辑一条记录(编辑项目为1到3的整数,1代表编辑电话,2代表编辑班级,3代表编辑宿舍)3 姓名
根据姓名查找,找到输出1,未找到输出04 班级
输出该班级的所有成员的宿舍号的异或值
其中查找操作当找到相应的人时输出1,未找到输出0。输出一个班级的人员信息时输出所有成员的宿舍号的异或值。输入数据保证合法。
输入
第一行一个n(1<=n<=20000), 代表接下来操作的数目。接下来n行代表各项操作。
输出
当遇到查找和输出一个班所有人员信息操作时输出。
思路分析及注意内容
- 由于每个联系人有姓名、电话号码、班级、宿舍,因此选择结构体来存储个人信息
- 定义线性表类,实现插入、删除、编辑、查找、输出异或值的操作
- 不能使用string类、各种字符串函数,因此要注意字符数组不能直接比较是否相等,以及不能直接进行复制操作
- 在计算异或值的时候,注意查找条件是班级而不是宿舍号
- 号码不能使用 int 类型,原因在于会超过所能表示的最大数,因此要用字符数组
- 在编辑的时候若将号码与另两个合为一起,可能会不好操作(因为类型不同),因此可以用两个函数分别去实现编辑功能。最后根据输入的数来选择调用哪个函数。
AC代码
#include<iostream>
using namespace std;
struct People {//结构体存储联系人信息
char name[50];
char phone[50];
int classID;
int dormitory;
};
//改变一个一维数组长度
template<class T>
void changeLength(T*& a, int oldl, int newl) {
T* temp = new T[newl];//新数组
int number = (oldl < newl) ? oldl : newl;//需要复制的元素个数
for (int i = 0; i < number; i++) {
temp[i] = a[i];//复制
}
delete[]a;//释放老内存空间
a = temp;
}
class linearList {
private:
int size;//当前长度
People* peo;
int capacity;//一维数组的容量
public:
linearList(int n = 10);//构造函数
~linearList() { delete[]peo; };//析构函数
void insert(const char* name, const char* phone, int classid, int domitoryid);//插入
void erase(const char* name);//删除
void edit1(const char* name, char* newphone);//编辑电话
void edit2(const char* name, int choice, int value);//编辑班级或宿舍
bool check(const char* name);//查找
int output(int dormitoryid);//输出
};
//构造函数
linearList::linearList(int n) {
peo = new People[n];
capacity = n;
size = 0;
}
//插入到数组的最后
void linearList::insert(const char* name, const char* phone, int classid, int domitoryid) {
if (size == capacity) {//检查是否已满,满了扩容为2倍
changeLength(peo, capacity, 2 * capacity);
capacity *= 2;
}
//一个一个字符插入姓名
int i = 0;
while (i < 49 && name[i] != '\0') {//确保未达到数组长度限制和字符串结束符时进行插入
peo[size].name[i] = name[i];
i++;
}
peo[size].name[i] = '\0';
//插入电话
i = 0;
while (i < 49 && phone[i] != '\0') {
peo[size].phone[i] = phone[i];
i++;
}
peo[size].phone[i] = '\0';
peo[size].classID = classid;
peo[size].dormitory = domitoryid;
size++;//当前存储的数量+1
}
//删除
void linearList::erase(const char* name) {
int i = 0;
while (i < size) {//利用循环找匹配的姓名
int j = 0;
while (peo[i].name[j] == name[j] && peo[i].name[j] != '\0' && name[j] != '\0') {
j++;//在姓名字符匹配且未达到字符串结束符的情况下继续比较
}
if (peo[i].name[j] == '\0' && name[j] == '\0') {
break; // 找到匹配的姓名
}
i++;
}
if (i == size) {
return; // 没有找到匹配的姓名
}
for (int j = i; j < size - 1; j++) {
peo[j] = peo[j + 1];//移动元素填补空缺
}
size--;
}
//编辑电话
void linearList::edit1(const char* name, char* newphone) {
int i = 0;
while (i < size) {//遍历联系人
int j = 0;
while (peo[i].name[j] == name[j] && peo[i].name[j] != '\0' && name[j] != '\0') {//先找到要进行编辑的人的姓名
j++;
}
if (peo[i].name[j] == '\0' && name[j] == '\0') {
int k = 0;
while (k < 49 && newphone[k] != '\0') {
peo[i].phone[k] = newphone[k];//逐个字符复制号码数组
k++;
}
peo[i].phone[k] = '\0';
break;
}
i++;
}
}
//编辑宿舍号或班级
void linearList::edit2(const char* name, int choice, int value) {
int i = 0;
while (i < size) {
int j = 0;
while (peo[i].name[j] == name[j] && peo[i].name[j] != '\0' && name[j] != '\0') {
j++;
}
if (peo[i].name[j] == '\0' && name[j] == '\0') {
// 找到匹配的姓名,进行修改
switch (choice) {
case 2:
peo[i].classID = value;
break;
case 3:
peo[i].dormitory = value;
break;
default:
break;
}
}
i++;
}
}
//查找
bool linearList::check(const char* name) {
int i = 0;
while (i < size) {
int j = 0;
while (peo[i].name[j] == name[j] && peo[i].name[j] != '\0' && name[j] != '\0') {
j++;
}
if (peo[i].name[j] == '\0' && name[j] == '\0') {
return 1; // 找到匹配的姓名
}
i++;
}
return 0; // 未找到匹配的姓名
}
//输出异或值
int linearList::output(int classid) {
int num = 0;
for (int i = 0; i < size; i++) {
if (peo[i].classID== classid)//先找到对应的班级
num ^= peo[i].dormitory;//计算班级中成员宿舍号的异或值
}
return num;
}
int main() {
int n;
char name[50];
char phone[50];
int classid, domitoryid;
cin >> n;
linearList l;
for (int i = 0; i < n; i++) {//循环输入操作
int operation;
cin >> operation;//进行的操作数
switch (operation) {
case 0://插入
cin >> name;
cin >> phone;
cin >> classid;
cin >> domitoryid;
l.insert(name, phone, classid, domitoryid);
break;
case 1://删除
cin >> name;
l.erase(name);
break;
case 2://编辑
int choice, value;
char newphone[50];
cin >> name;
cin >> choice;
if (choice == 1) {//编辑号码
cin >> newphone;
l.edit1(name, newphone);
}
else {//编辑班级或宿舍号
cin >> value;
l.edit2(name, choice, value);
}
break;
case 3://查找
cin >> name;
cout << l.check(name) << endl;
break;
case 4://输出异或值
cin >> classid;
cout << l.output(classid) << endl;
break;
default:
break;
}
}
return 0;
}
改进:可以将字符串的操作写成函数,可以简化代码