1、采用顺序表表示集合,编程求集合运算(A-B)∪(B-A)的结果。
#include<iostream>
#include<unordered_set>
using namespace std;
typedef int Status;
typedef char ElemType;
#define MAXSIZE 52
#define OK 1
#define ERROR 0
#define OVERFLOW -1
//顺序表
struct SqList
{
ElemType* arr;
int length;
};
//初始化并给顺序表赋值,默认长度为0
Status Init(SqList& sq,int len=0);
//使用顺序表给顺序表赋值
Status Init(const SqList& sq,SqList& result);
//遍历顺序表
Status Display(const SqList& sq);
//集合求差
Status SubSq(const SqList& L1,const SqList& L2,SqList &L);
//集合求和
Status AddSq(const SqList& L1, const SqList& L2, SqList &L);
int main()
{
SqList A, B,tempA, tempB, ans;
Status key;
//初始化A输入错误重输
do
{
cout << "How many elements in A?\n";
int lenA;
cin >> lenA;
if (lenA >= 0 && lenA <= MAXSIZE)
{
cout << "Input A:\n";
}
key = Init(A, lenA);
} while (key!=OK);
//初始化B输入错误重输
do
{
cout << "How many elements in B?\n";
int lenB;
cin >> lenB;
if (lenB >= 0 && lenB <= MAXSIZE)
{
cout << "Input B:\n";
}
key = Init(B, lenB);
} while (key != OK);
cout << "********************************\n";
cout << "A is: ";
Display(A);
cout << "B is: ";
Display(B);
//执行A-B正确执行则打印结果表
if (SubSq(A, B, tempA))
{
cout << "A-B is: ";
Display(tempA);
}
//执行B-A正确执行则打印结果表
if (SubSq(B, A, tempB))
{
cout << "B-A is: ";
Display(tempB);
}
//执行(A-B)∪(B-A),正确执行则打印结果表
cout << "(A-B)∪(B-A) is: ";
if (AddSq(tempA, tempB, ans))
{
Display(ans);
}
return 0;
}
Status Init(SqList& sq, int len)
{
if (len > MAXSIZE)
{
cout << "超过顺序表长度\n";
return OVERFLOW;
}
if (len < 0)
{
cout << "顺序表长度应大于等于0\n";
return ERROR;
}
//分配内存,并存入数据,同时将sq.length修改为顺序表内元素的个数
sq.arr = new ElemType[MAXSIZE];
sq.length = len;
for (int i = 0; i < len; ++i)
{
cin >> sq.arr[i];
}
return OK;
}
Status Init(const SqList& sq, SqList& result)
{
//将sq表中的元素放入result表中
for (int i = 0; i < sq.length; ++i)
{
result.arr[result.length] = sq.arr[i];
result.length++;
}
return OK;
}
Status Display(const SqList& sq)
{
if (sq.length == 0)
{
cout << "顺序表为空\n";
return ERROR;
}
//遍历顺序表中的元素
for (int i = 0; i < sq.length; i++)
{
cout << sq.arr[i] << ' ';
}
cout << endl;
return OK;
}
Status SubSq(const SqList& L1, const SqList& L2, SqList &L)
{
//先为L分配内存,长度设置为0
Init(L);
//无序表记录顺序表L2的数据并去重
unordered_set<ElemType> book;
for (int i = 0; i < L2.length; i++)
{
book.insert(L2.arr[i]);
}
//若L1中有L2中未出现的元素,则存入L中
for (int i = 0; i < L1.length; i++)
{
//判断L2中是否有此元素
if (!book.count(L1.arr[i]))
{
L.arr[L.length] = L1.arr[i];
L.length++;
}
}
return OK;
}
Status AddSq(const SqList& L1, const SqList& L2, SqList &L)
{
Init(L);
int sum = L1.length + L2.length;
//实际上此题不许要考虑溢出,因为结果元素数量一定不超过52
if (sum > MAXSIZE)
{
cout << "集合相加结果溢出\n";
return OVERFLOW;
}
L.arr = new ElemType[sum];
if (sum == 0)
{
cout << "集合相加结果为空\n";
return ERROR;
}
//显然L是L1,L2元素和,将L1和L2中的元素存入L中
Init(L1, L);
Init(L2, L);
return OK;
}
2、一个长度为n(n≥1)的升序排列顺序表La,处在第n/2个位置的数称为La的中位数。
/*
两个等长升序排列顺序表,合并之后求中位数(向上取整)
*/
#include<iostream>
using namespace std;
typedef int Status;
typedef int ElemType;
#define MAXSIZE 100
#define OK 1
#define ERROR 0
#define OVERFLOW -1
//顺序表
struct SqList
{
ElemType* arr;
int length;
};
Status Init(SqList& sq, int len);
Status Display(const SqList& sq);
//查找中位数
Status find(const SqList& sq1, const SqList& sq2, int count, ElemType& ans);
void qucikSort(ElemType* arr,int start,int end);
int main()
{
SqList La, Lb;
Status key;
int len;
//初始化La,输入长度不合法则要求重新输入长度
do
{
cout << "线性表中元素的个数?\n";
cin >> len;
if (len >= 0 && len <= MAXSIZE)
{
cout << "请输入La中的元素:\n";
}
key = Init(La, len);
} while (key != OK);
//初始化Lb
cout << "请输入Lb中的元素:\n";
Init(Lb, len);
//对La,Lb排序
qucikSort(La.arr,0,La.length-1);
cout << "调整之后的La为:";
Display(La);
qucikSort(Lb.arr, 0, Lb.length - 1);
cout << "调整之后的Lb为:";
Display(Lb);
int ans;
///找中位数,两个表等长,则中位数一定再是第La.length个
find(La, Lb, La.length, ans);
cout << "两表合并之后的中位数: \n" << ans;
}
Status Init(SqList& sq, int len)
{
if (len > MAXSIZE)
{
cout << "超过顺序表长度\n";
return OVERFLOW;
}
if (len < 0)
{
cout << "顺序表长度应大于等于0\n";
return ERROR;
}
//开辟顺序表内存,存入元素,并修改顺序表的长度
sq.arr = new ElemType[MAXSIZE];
sq.length = len;
for (int i = 0; i < len; ++i)
{
cin >> sq.arr[i];
}
return OK;
}
Status find(const SqList& sq1, const SqList& sq2,int count,ElemType &ans)
{
//按照顺序找第count个
int i = 0, j = 0;
while (count--)
{
//两个表都是递增序列,当前下标处值比较小的序列,下标后移再进行判断,每移一次都是走向更大的数,直到找到第count大的数
if (sq1.arr[i] >= sq2.arr[j])
{
ans = sq2.arr[j];
++j;
}
else
{
ans = sq1.arr[i];
++i;
}
}
return OK;
}
Status Display(const SqList& sq)
{
if (sq.length == 0)
{
cout << "顺序表为空\n";
return ERROR;
}
//顺序输出顺序表
for (int i = 0; i < sq.length; ++i)
{
cout << sq.arr[i] << ' ';
}
cout << endl;
return OK;
}
void qucikSort(ElemType* arr, int start, int end)
{
if (start <= end)
{
int i = start, j = end;
int key = arr[end];
while (i<j)
{
while (arr[i]<key)
{
++i;
}
if (i < j)
{
arr[j] = arr[i];
--j;
}
while (arr[j]>key)
{
--j;
}
if (i < j)
{
arr[i] = arr[j];
++i;
}
}
arr[i] = key;
qucikSort(arr, start, i-1);
qucikSort(arr, i + 1, end);
}
return;
}
3设计一个图书信息管理系统,每本图书包含ISBN号、书名、定价信息,要求实现取值、查找、插入、删除等功能,运行效果如下图所示。
/*
数据元素:id,名称,价格
功能: 1.取值:按下标查找书
2.查找:按书名查找,告知所有书名符合的书的下标
3.插入:指定位置插入书本位置和信息(指定位置有书则这些书后移一位)
4.删除:按位置删除
5.输出:输出顺序表中全部书的所有信息
0.退出
*/
#include<iostream>
#include<string>
#include<iomanip>
using namespace std;
typedef int Status;
//线性表数组大小
#define MAXSIZE 100
#define OK 1
#define ERROR 0
#define OVERFLOW -1
//输出字符宽度
#define CSIZE 18
struct book
{
int id;
string name;
float price;
//赋值book信息
void set(int id, string name, float price)
{
this->id = id;
this->name = name;
this->price = price;
}
//重载<<,输出book信息
friend ostream& operator<<(ostream& os,const book &b)
{
//设置输出格式,字符宽度为CSIZE,左对齐,定点小数,小数点后两位
os << left << setw(CSIZE) << b.id << setw(CSIZE) << b.name << setw(CSIZE) << fixed << setprecision(2) << b.price << endl;
return os;
}
//重载==,用于判断书名和字符串是否相等
friend bool operator==(const book& b, string s)
{
if (b.name.compare(s)==0)
{
return true;
}
else
{
return false;
}
}
};
struct SqList
{
book* arr;
int length;
};
//初始化
Status Init(SqList& sq);
//1.取值:按下标查找书,这里只判断下标是否存在
Status GetInfo(const SqList& sq,int index);
//2.查找:按书名查找,告知所有书名符合的书的下标
Status Select(const SqList& sq, string bookName);
//3.插入:指定位置插入书本位置和信息(指定位置有书则这些书后移一位)
Status Insert(SqList& sq, int index, int id, string name, float price);
//4.删除:按下标删除
Status Delete(SqList& sq, int index);
//5.输出:输出顺序表中全部书的所有信息
Status Show(const SqList& sq);
//0.退出
Status Menu();
int main()
{
Menu();
}
Status Init(SqList& sq)
{
sq.arr = new book[MAXSIZE];
sq.length = 0;
cout << "请输入图书信息:\n";
while (true)
{
int id;
string name;
float price;
cout << "请输入图书的id号(以0结束):\n";
cin >> id;
if (id == 0)
{
break;
}
cout << "请输入图书的名称:\n";
cin >> name;
cout << "请输入图书的价格:\n";
cin >> price;
sq.arr[sq.length].set(id, name, price);
++sq.length;
}
return OK;
}
//1.取值:按下标查找书,并输出信息
Status GetInfo(const SqList& sq, int index)
{
if (index > sq.length)
{
cout << "超过顺序表长度";
return OVERFLOW;
}
//<<运算符已经重载,直接用来输出book信息
cout << "查找成功\n"
<< "第"<<index<<"本图书的信息是:\n"
<< sq.arr[index - 1];
return OK;
}
Status Select(const SqList& sq, string bookName)
{
//设置标识判断是否找到书
bool key = true;
for (int i = 0; i < sq.length; ++i)
{
//==运算符已经重载,直接用来比较
if (sq.arr[i] == bookName)
{
//只要找到一本就修改标志
key = false;
cout << bookName << "是第" << i + 1 << "本书\n";
}
}
if (key)
{
cout << "没有找到书名为<<" << bookName << ">>的书\n";
return ERROR;
}
return OK;
}
//3.插入:指定位置插入书本位置和信息(指定位置有书则这些书后移一位)
Status Insert(SqList& sq, int index, int id, string name, float price)
{
if (index-1 > sq.length)
{
cout << "插入位置不应该超过" << sq.length+1 << endl;
return OVERFLOW;
}
if (index-1 > MAXSIZE)
{
cout << "超出顺序表长度\n";
return OVERFLOW;
}
if (index <= 0)
{
cout << "插入位置不应该为负数\n";
return ERROR;
}
//index之后所有元素后移一位。注意顺序表中下标应该为index-1;
for (int i = sq.length; i > index-1; --i)
{
//赋值构造函数直接赋值
sq.arr[i] = sq.arr[i - 1];
}
sq.arr[index - 1].set(id, name, price);
++sq.length;
return OK;
}
//4.删除:按下标删除
Status Delete(SqList& sq, int index)
{
if (index > sq.length)
{
cout << "删除位置不应该超过" << sq.length << endl;
return OVERFLOW;
}
if (index > MAXSIZE)
{
cout << "超出顺序表长度\n";
return OVERFLOW;
}
if (index <= 0)
{
cout << "删除位置不应该为负数\n";
return ERROR;
}
//直接元素前移把他盖住,再修改sq.length:
for (int i = index - 1; i < sq.length; ++i)
{
sq.arr[i] = sq.arr[i + 1];
}
--sq.length;
return OK;
}
//5.输出:输出顺序表中全部书的所有信息
Status Show(const SqList& sq)
{
if (sq.length == 0)
{
cout << "顺序表为空";
return ERROR;
}
for (int i = 0; i < sq.length; ++i)
{
cout << sq.arr[i];
}
return OK;
}
Status Menu()
{
SqList sq;
int index,id;
float price;
string name;
Init(sq);
while (true)
{
cout << "欢迎进入图书资料管理系统\n"
<< "\t1.取值\n"
<< "\t2.查找\n"
<< "\t3.插入\n"
<< "\t4.删除\n"
<< "\t5.输出\n"
<< "\t0.退出\n"
<< endl;
int key;
cin >> key;
switch (key)
{
case 1:
cout << "请输入要查找的图书序号:\n";
cin >> index;
GetInfo(sq, index);
break;
case 2:
cout << "请输入所要查找的书名:";
cin >> name;
Select(sq, name);
break;
case 3:
cout << "请输入插入的位置和书本信息,包括:编号 书名 价格(用空格隔开):";
cin >> index >> id >> name >> price;
if (Insert(sq, index, id, name, price)==OK)
{
cout << "插入成功\n";
}
break;
case 4:
cout << "请输入所要删除的书籍的位置:";
cin >> index;
if (Delete(sq, index)==OK)
{
cout << "删除成功\n";
}
break;
case 5:
cout << "当前图书系统信息(顺序表)读出:\n\n";
//设置输出格式,字符宽度为CSIZE,左对齐
cout << left << setw(CSIZE) << "ID号" << setw(CSIZE) << "名称" << setw(CSIZE) << "价格" << endl;
Show(sq);
break;
case 0:
cout << "感谢使用!再见!";
default:
break;
}
if (key == 0)
{
return OK;
}
cout << "---------------------------------------\n";
}
}