实验3 数组描述线性表
要求
- 不要使用 STL
- 封装线性表类,提供插入,删除,查找等操作
- 线性表实现使用数组描述方法(顺序存储结构)
描述
设通讯录中每一个联系人的内容有:姓名、电话号码、班级、宿舍。由标准输入读入联系人信息,使用线性表中操作实现通讯录管理功能,包括:插入、删除、编辑、查找(按姓名查找);键盘输入一班级,输出通讯录中该班级中所有人的信息。
格式
每个操作的第一个数为操作数(插入-0,删除-1,编辑-2,查找-3,输出一个班所有人员信息-4),具体格式如下:
0 姓名 电话 班级 宿舍
插入一条记录1 姓名
根据姓名删除一条记录2 姓名 编辑项目 项目新值
根据姓名编辑一条记录(编辑项目为1到3的整数,1代表编辑电话,2代表编辑班级,3代表编辑宿舍)3 姓名
根据姓名查找,找到输出1,未找到输出04 班级
输出该班级的所有成员的宿舍号的异或值
其中查找操作当找到相应的人时输出1,未找到输出0。输出一个班级的人员信息时输出所有成员的宿舍号的异或值。输入数据保证合法。
输入
第一行一个n(1<=n<=20000), 代表接下来操作的数目。接下来n行代表各项操作。
输出
当遇到查找和输出一个班所有人员信息操作时输出。
思路与探讨
线性表数组描述
整体思路描述
-
先定义联系人个人信息结构体
每一个联系人的内容有:姓名、电话号码、班级、宿舍。因此这里用结构体来存储最合适。
-
然后定义线性表类(抽象数据类型),注意改变一维数组长度,原始数组空间容量有可能不够,所以需要对数组扩容,使用动态数组对老数组进行清除并扩容。
-
之后利用结构体,实现对数组元素信息进行删除、编辑、查找、输出等操作。
若已看懂思路,试着自己写~
实现代码
#include<iostream>
#include<string>
using namespace std;
//构造联系人结构体
struct student
{
string name;//姓名
string phone;//电话号码
int class_;//班级
int home;//宿舍
};
//改变一个一维数组长度 (参考课本)
template<class T>
void changelength(T *&a,int oldlength,int newlength)
{
T *temp = new T[newlength];//新数组
int number = min(oldlength,newlength);// 需要复制的元素个数
copy(a,a + number,temp);
delete []a;//释放老数组的内存空间
a = temp;
}
//定义线性表
class Linearlist
{
public:
Linearlist(int n = 10);//构造函数
~Linearlist() {delete [] stu;}//析构函数
void insert(string &name,string &phone,int &class_,int &home);//插入
void erase(string &name);//删除
void edit1(string& name,string& new_phone);//编辑电话
void edit2(string& name,int choose,int& new_message);//编辑班级和宿舍
bool search(string &name);//查找
int output(int &class_);//输出
private:
struct student*stu;
int capacity;//一维数组的容量
int listsize;//线性表的元素个数
} ;
//构造函数初始化
Linearlist::Linearlist(int n)
{
stu = new student[n];
capacity = n;
listsize = 0;
}
//插入0 ——插入一条记录(这里是直接在末尾插入,所以不用考虑其他元素移动问题)
void Linearlist::insert(string &name,string &phone,int &class_,int &home)
{
if(capacity == listsize)
{//数组空间已满,数组长度倍增
changelength(stu,capacity,capacity*2);
capacity *= 2;
}
stu[listsize].name = name;
stu[listsize].phone=phone;
stu[listsize].class_=class_;
stu[listsize].home=home;
//插入元素后元素个数更新
listsize++;
}
//删除1——根据姓名删除一条记录
void Linearlist::erase(string &name)
{
int i=0;
//找到对应索引
while(stu[i].name!=name&&i<listsize)
i++;
//移动索引大于i的元素 (把i+1一直到listsize-1的元素向左移动一个位置)
for(int j = i + 1;j < listsize;j++)
{
stu[j-1] = stu[j];
}
//调用析构函数 listSize-1
stu[--listsize].~student();
}
//编辑2.1——根据姓名编辑电话
void Linearlist::edit1(string& name,string& new_phone)
{
int i = 0;
while(stu[i].name != name && i < listsize)
i++;
stu[i].phone = new_phone;
}
//编辑2.2 0r 2.3——根据姓名编辑班级或宿舍
void Linearlist::edit2(string& name,int choose,int& new_message)
{
int i = 0;
while(stu[i].name != name && i < listsize)
i++;
if(choose == 2) stu[i].class_ = new_message;
else if(choose == 3) stu[i].home = new_message;
}
//查找3——根据姓名查找,找到输出1,未找到输出0
bool Linearlist::search(string &name)
{
int i = 0;
while(stu[i].name != name && i < listsize)
i++;
if(i >= listsize)
return 0;
else
return 1;
}
//输出4——输出该班级的所有成员的宿舍号的异或值
int Linearlist::output(int &class_)
{
int index = 0;
for(int i = 0;i < listsize;i++)
{
if(stu[i].class_ == class_)
index ^= stu[i].home;
}
return index;
}
int main()
{
int x,n;
string name,phone,new_phone;
int choose,new_message,home,class_;
cin >> n;
Linearlist L;
int *a = new int[n];
for(int j = 0;j < n;j++)
{
cin >> x;
switch(x){
case 0:
cin >> name;
cin >> phone;
cin >> class_;
cin >> home;
L.insert(name,phone,class_,home);
break;
case 1:
cin >> name;
L.erase(name);
break;
case 2:
cin >> name;
cin >> choose;
if(choose == 1)
{
cin >> new_phone;
L.edit1(name,new_phone);
}
else
{
cin >> new_message;
L.edit2(name,choose,new_message);
}
break;
case 3:
cin >> name;
cout << L.search(name) << endl;
break;
case 4:
cin >> class_;
cout << L.output(class_) << endl;
break;
default:
break;
}
}
return 0;
}