【数据结构】实验3_数组描述线性表 A通讯录

要求

  1. 不要使用STL
  2. 封装线性表类,提供插入,删除,查找等操作
  3. 线性表实现使用数组描述方法(顺序存储结构)

描述

设通讯录中每一个联系人的内容有:姓名、电话号码、班级、宿舍。由标准输入读入联系人信息,使用线性表中操作实现通讯录管理功能,包括:插入、删除、编辑、查找(按姓名查找);键盘输入一班级,输出通讯录中该班级中所有人的信息。

格式

每个操作的第一个数为操作数(插入-0,删除-1,编辑-2,查找-3,输出一个班所有人员信息-4),具体格式如下:

  • 0 姓名 电话 班级 宿舍 插入一条记录
  • 1 姓名 根据姓名删除一条记录
  • 2 姓名 编辑项目 项目新值 根据姓名编辑一条记录(编辑项目为1到3的整数,1代表编辑电话,2代表编辑班级,3代表编辑宿舍)
  • 3 姓名 根据姓名查找,找到输出1,未找到输出0
  • 4 班级 输出该班级的所有成员的宿舍号的异或值

其中查找操作当找到相应的人时输出1,未找到输出0。输出一个班级的人员信息时输出所有成员的宿舍号的异或值。输入数据保证合法。

输入

第一行一个n(1<=n<=20000), 代表接下来操作的数目。接下来n行代表各项操作。

输出

当遇到查找和输出一个班所有人员信息操作时输出。

思路分析及注意内容

  1. 由于每个联系人有姓名、电话号码、班级、宿舍,因此选择结构体来存储个人信息
  2. 定义线性表类,实现插入、删除、编辑、查找、输出异或值的操作
  3. 不能使用string类、各种字符串函数,因此要注意字符数组不能直接比较是否相等,以及不能直接进行复制操作
  4. 在计算异或值的时候,注意查找条件是班级而不是宿舍号
  5. 号码不能使用 int 类型,原因在于会超过所能表示的最大数,因此要用字符数组
  6. 在编辑的时候若将号码与另两个合为一起,可能会不好操作(因为类型不同),因此可以用两个函数分别去实现编辑功能。最后根据输入的数来选择调用哪个函数。

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

改进:可以将字符串的操作写成函数,可以简化代码

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值