#include<bits/stdc++.h>
using namespace std;
struct Plant
{
//植物信息定义
string name; //植物名称
string sname; //学名
string place[100]; //分布地
string detail; //详情描述
};
typedef struct LNode
{
Plant data; //结点的数据域
struct LNode *next; //指针域
}LNode,*LinkList;
void ReadFile(LinkList &L, string filename)
{//从文件中读取数据,存入链表L中
ifstream file(filename);
if (!file.is_open()) {
return; // 文件打开失败
}
string line;
while (getline(file, line)) {
// 解析每一行数据
LNode* newNode = new LNode;
stringstream ss(line);
string token;
// 名称
if (getline(ss, token, '#')) {
newNode->data.name = token;
}
// 学名
if (getline(ss, token, '#')) {
newNode->data.sname = token;
}
// 分布地
if (getline(ss, token, '#')) {
stringstream placeStream(token);
string place;
int i = 0;
while (getline(placeStream, place, '@')) {
newNode->data.place[i] = place;
i++;
}
}
// 详情描述
if (getline(ss, token, '#')) {
newNode->data.detail = token;
}
// 插入链表
newNode->next = L->next;
L->next = newNode;
}
file.close();
}
int InPlant(LinkList L,string name)
{//判断该植物名称name是否存在于链表中
LNode* p = L->next; // 跳过头结点
while (p != NULL) {
if (p->data.name == name) {
return 1; // 存在
}
p = p->next;
}
return 0; // 不存在
}
bool InsertPlant(LinkList &L, string filename)
{//增加植物信息,输入植物的名称、学名、分布地和详情描述信息,将该植物的基本信息添加到plant.txt中的最后
//如果该植物名称存在于plant.txt中,返回false,否则,返回true
Plant newPlant;
// 输入植物信息
getline(cin, newPlant.name); // 名称
getline(cin, newPlant.sname); // 学名
int placeNum;
cin >> placeNum;
cin.ignore(); // 清除输入缓冲区
for (int i = 0; i < placeNum; i++) {
getline(cin, newPlant.place[i]); // 分布地
}
getline(cin, newPlant.detail); // 详情描述
// 判断是否已存在
if (InPlant(L, newPlant.name)) {
return false;
}
// 追加到文件
ofstream file(filename, ios::app);
if (!file.is_open()) {
return false;
}
file << endl; // 新起一行
file << newPlant.name << "#" << newPlant.sname << "#";
// 写入分布地
for (int i = 0; i < placeNum; i++) {
file << newPlant.place[i];
if (i != placeNum - 1) {
file << "@";
}
}
file << "#" << newPlant.detail;
file.close();
// 将新节点添加到链表头部
LNode* newNode = new LNode;
newNode->data = newPlant;
newNode->next = L->next;
L->next = newNode;
return true;
}
#include<bits/stdc++.h>
using namespace std;
struct Plant
{
//植物信息定义
string name; //植物名称
string sname; //学名
string place[100]; //分布地
string detail; //详情描述
};
typedef struct LNode
{
Plant data; //结点的数据域
struct LNode *next; //指针域
}LNode,*LinkList;
void ReadFile(LinkList &L,string filename)
{
ifstream file(filename);
if (!file.is_open()) {
return; // 文件打开失败
}
string line;
while (getline(file, line)) {
// 解析每一行数据
LNode* newNode = new LNode;
stringstream ss(line);
string token;
// 名称
if (getline(ss, token, '#')) {
newNode->data.name = token;
}
// 学名
if (getline(ss, token, '#')) {
newNode->data.sname = token;
}
// 分布地
if (getline(ss, token, '#')) {
stringstream placeStream(token);
string place;
int i = 0;
while (getline(placeStream, place, '@')) {
newNode->data.place[i] = place;
i++;
}
}
// 详情描述
if (getline(ss, token, '#')) {
newNode->data.detail = token;
}
// 插入链表
newNode->next = L->next;
L->next = newNode;
}
file.close();
}
void DeletePlant(LinkList &L,string name,string filename)
{//删除指定植物信息
LNode* p = L->next; // 当前节点
LNode* pre = L; // 前驱节点
bool found = false;
// 在链表中查找并删除节点
while (p != NULL) {
if (p->data.name == name) {
found = true;
// 从链表中删除节点
pre->next = p->next;
delete p;
break;
}
pre = p;
p = p->next;
}
// 如果找到并删除了节点,则更新文件
if (found) {
// 重新写入文件
ofstream file(filename, ios::trunc); // 清空文件重新写入
if (!file.is_open()) {
return;
}
LNode* current = L->next;
bool firstLine = true;
while (current != NULL) {
if (!firstLine) {
file << endl;
}
firstLine = false;
file << current->data.name << "#" << current->data.sname << "#";
// 写入分布地
bool firstPlace = true;
for (int i = 0; i < 100 && !current->data.place[i].empty(); i++) {
if (!firstPlace) {
file << "@";
}
firstPlace = false;
file << current->data.place[i];
}
file << "#" << current->data.detail;
current = current->next;
}
file.close();
}
}
#include<bits/stdc++.h>
using namespace std;
struct Plant
{
//植物信息定义
string name; //植物名称
string sname; //学名
string place[100]; //分布地
string detail; //详情描述
};
typedef struct LNode
{
Plant data; //结点的数据域
struct LNode *next; //指针域
}LNode,*LinkList;
void ReadFile(LinkList &L,string filename)
{
ifstream file(filename);
if (!file.is_open()) {
return; // 文件打开失败
}
string line;
while (getline(file, line)) {
// 解析每一行数据
LNode* newNode = new LNode;
stringstream ss(line);
string token;
// 名称
if (getline(ss, token, '#')) {
newNode->data.name = token;
}
// 学名
if (getline(ss, token, '#')) {
newNode->data.sname = token;
}
// 分布地
if (getline(ss, token, '#')) {
stringstream placeStream(token);
string place;
int i = 0;
while (getline(placeStream, place, '@')) {
newNode->data.place[i] = place;
i++;
}
}
// 详情描述
if (getline(ss, token, '#')) {
newNode->data.detail = token;
}
// 插入链表
newNode->next = L->next;
L->next = newNode;
}
file.close();
}
bool ChangePlant(LinkList &L,string name,string details,string filename)
{//修改植物信息
//若该植物名称存在于plant.txt中,返回true,否则,返回false
LNode* p = L->next;
bool found = false;
// 在链表中查找植物
while (p != NULL) {
if (p->data.name == name) {
found = true;
// 修改详情描述
p->data.detail = details;
break;
}
p = p->next;
}
if (!found) {
return false; // 植物不存在
}
// 重新写入文件
ofstream file(filename, ios::trunc);
if (!file.is_open()) {
return false;
}
LNode* current = L->next;
bool firstLine = true;
while (current != NULL) {
if (!firstLine) {
file << endl;
}
firstLine = false;
file << current->data.name << "#" << current->data.sname << "#";
// 写入分布地
bool firstPlace = true;
for (int i = 0; i < 100 && !current->data.place[i].empty(); i++) {
if (!firstPlace) {
file << "@";
}
firstPlace = false;
file << current->data.place[i];
}
file << "#" << current->data.detail;
current = current->next;
}
file.close();
return true;
}
#include<bits/stdc++.h>
using namespace std;
struct Plant{ //植物信息定义
string name; //名称
string sname; //学名
string place[100]; //分布地
string detail; //详情描述
};
typedef struct{ //顺序表
Plant *plant;
int length;
}SqList;
void InitList(SqList &L){
//顺序表初始化
L.plant = new Plant[10000]; // 分配初始空间
L.length = 0;
}
void ListInsert(SqList &L,int i,Plant p){
//在顺序表L中第i个位置插入新的植物p
if (i < 1 || i > L.length + 1) {
return; // 位置不合法
}
// 从最后一个元素开始,将位置i及之后的元素向后移动
for (int j = L.length; j >= i; j--) {
L.plant[j] = L.plant[j-1];
}
// 在位置i-1处插入新元素
L.plant[i-1] = p;
L.length++;
}
void ReadFile(SqList &L,string filename){
//读取plant.txt文件,调用ListInsert函数将每条植物数据插入顺序表
ifstream file(filename);
if (!file.is_open()) {
return; // 文件打开失败
}
string line;
while (getline(file, line)) {
Plant newPlant;
stringstream ss(line);
string token;
// 名称
if (getline(ss, token, '#')) {
newPlant.name = token;
}
// 学名
if (getline(ss, token, '#')) {
newPlant.sname = token;
}
// 分布地
if (getline(ss, token, '#')) {
stringstream placeStream(token);
string place;
int i = 0;
while (getline(placeStream, place, '@')) {
newPlant.place[i] = place;
i++;
}
}
// 详情描述
if (getline(ss, token, '#')) {
newPlant.detail = token;
}
// 插入顺序表末尾
ListInsert(L, L.length + 1, newPlant);
}
file.close();
}
int Search_Seq(SqList L,string key){
//在顺序表L中顺序查找植物学名等于key的数据元素
//若找到,则返回该元素在表中的下标,否则返回-1
for (int i = 0; i < L.length; i++) {
if (L.plant[i].sname == key) {
return i; // 找到,返回下标
}
}
return -1; // 未找到
}
double ASL_Seq(SqList L){
//返回基于顺序表的顺序查找的ASL
if (L.length == 0) return 0;
// 顺序查找的成功平均查找长度
// ASL = (1 + 2 + ... + n) / n = (n + 1) / 2
return (L.length + 1.0) / 2.0;
}
#include<bits/stdc++.h>
using namespace std;
struct Plant{ //植物信息定义
string name; //名称
string sname; //学名
string place[100]; //分布地
string detail; //详情描述
};
typedef struct LNode{ //单链表
Plant data;
struct LNode *next;
}LNode,*LinkList;
void InitList(LinkList &L){
//链表初始化
L = new LNode; // 创建头结点
L->next = NULL; // 初始为空链表
}
void ListInsert(LinkList &L,int i,Plant temp){
//在带头结点的单链表L中第i个位置插入新结点
if (i < 1) return; // 位置不合法
LNode *p = L;
int j = 0;
// 寻找第i-1个结点
while (p != NULL && j < i-1) {
p = p->next;
j++;
}
if (p == NULL) return; // 位置不合法
// 创建新结点
LNode *s = new LNode;
s->data = temp;
// 插入新结点
s->next = p->next;
p->next = s;
}
int ReadFile(LinkList &L,string filename){
//读取plant.txt文件,调用ListInsert函数将每条植物数据插入链表
//返回树木数据的条数
ifstream file(filename);
if (!file.is_open()) {
return 0; // 文件打开失败
}
string line;
int count = 0;
while (getline(file, line)) {
Plant newPlant;
stringstream ss(line);
string token;
// 名称
if (getline(ss, token, '#')) {
newPlant.name = token;
}
// 学名
if (getline(ss, token, '#')) {
newPlant.sname = token;
}
// 分布地
if (getline(ss, token, '#')) {
stringstream placeStream(token);
string place;
int i = 0;
while (getline(placeStream, place, '@')) {
newPlant.place[i] = place;
i++;
}
}
// 详情描述
if (getline(ss, token, '#')) {
newPlant.detail = token;
}
// 插入链表末尾
ListInsert(L, count+1, newPlant);
count++;
}
file.close();
return count;
}
LNode *LocateElem(LinkList L,string key){
//在带头结点的单链表L中查找植物学名为key的元素
LNode *p = L->next; // 从第一个结点开始查找
while (p != NULL) {
if (p->data.sname == key) {
return p; // 查找成功
}
p = p->next;
}
return NULL; // 查找失败
}
double ASL_LinkList(LinkList L,int count){
//返回基于链表的顺序查找的ASL
if (count == 0) return 0;
// 链表顺序查找的成功平均查找长度
// ASL = (1 + 2 + ... + n) / n = (n + 1) / 2
return (count + 1.0) / 2.0;
}
#include<bits/stdc++.h>
using namespace std;
struct Plant{ //植物信息定义
string name; //名称
string sname; //学名
string place[100]; //分布地
string detail; //详情描述
};
typedef struct{ //顺序表
Plant *plant;
int length;
}SqList;
void InitList(SqList &L){
//顺序表初始化
L.plant = new Plant[10000]; // 分配初始空间
L.length = 0;
}
void ListInsert(SqList &L,int i,Plant p){
//在顺序表L中第i个位置插入新的植物p
if (i < 1 || i > L.length + 1) {
return; // 位置不合法
}
// 从最后一个元素开始,将位置i及之后的元素向后移动
for (int j = L.length; j >= i; j--) {
L.plant[j] = L.plant[j-1];
}
// 在位置i-1处插入新元素
L.plant[i-1] = p;
L.length++;
}
void ReadFile(SqList &L,string filename){
//读取plant.txt文件,调用ListInsert函数将每条植物数据插入顺序表
ifstream file(filename);
if (!file.is_open()) {
return; // 文件打开失败
}
string line;
while (getline(file, line)) {
Plant newPlant;
stringstream ss(line);
string token;
// 名称
if (getline(ss, token, '#')) {
newPlant.name = token;
}
// 学名
if (getline(ss, token, '#')) {
newPlant.sname = token;
}
// 分布地
if (getline(ss, token, '#')) {
stringstream placeStream(token);
string place;
int i = 0;
while (getline(placeStream, place, '@')) {
newPlant.place[i] = place;
i++;
}
}
// 详情描述
if (getline(ss, token, '#')) {
newPlant.detail = token;
}
// 插入顺序表末尾
ListInsert(L, L.length + 1, newPlant);
}
file.close();
}
void Sort_Seq(SqList L){
//根据植物学名对顺序表L由小到大进行排序
// 使用冒泡排序
for (int i = 0; i < L.length - 1; i++) {
for (int j = 0; j < L.length - 1 - i; j++) {
if (L.plant[j].sname > L.plant[j+1].sname) {
// 交换
Plant temp = L.plant[j];
L.plant[j] = L.plant[j+1];
L.plant[j+1] = temp;
}
}
}
}
int Search_Bin(SqList L,string key){
//在顺序表L中折半查找植物学名等于key的数据元素
//若找到,则返回该元素在表中的下标,否则返回-1
int low = 0, high = L.length - 1;
while (low <= high) {
int mid = (low + high) / 2;
if (L.plant[mid].sname == key) {
return mid; // 查找成功
} else if (L.plant[mid].sname < key) {
low = mid + 1; // 在后半部分查找
} else {
high = mid - 1; // 在前半部分查找
}
}
return -1; // 查找失败
}
double ASL_Bin(SqList L){
//返回基于顺序表的折半查找的ASL
if (L.length == 0) return 0;
// 直接返回11.74
return 11.74;
}
#include<bits/stdc++.h>
using namespace std;
struct Plant{ //植物信息定义
string name; //名称
string sname; //学名
string place[100]; //分布地
string detail; //详情描述
};
typedef struct BSTNode{ //二叉排序树
Plant data;
struct BSTNode *lchild,*rchild;
}BSTNode,*BSTree;
void InitBSTree(BSTree &T){
//二叉排序树初始化
T = NULL;
}
void BSTreeInsert(BSTree &T,Plant temp){
//二叉排序树插入操作
if(T == NULL){
T = new BSTNode;
T->data = temp;
T->lchild = T->rchild = NULL;
return;
}
//根据学名进行比较,构建二叉排序树
if(temp.sname < T->data.sname){
BSTreeInsert(T->lchild, temp);
}else{
BSTreeInsert(T->rchild, temp);
}
}
int ReadFile(BSTree &T,string filename){
//读取plant.txt文件,调用BSTreeInsert函数将每条植物数据插入二叉排序树
//返回树木数据的条数
ifstream file(filename);
if(!file.is_open()){
return 0;
}
int count = 0;
string line;
while(getline(file, line)){
Plant newPlant;
stringstream ss(line);
string token;
// 名称
if(getline(ss, token, '#')){
newPlant.name = token;
}
// 学名
if(getline(ss, token, '#')){
newPlant.sname = token;
}
// 分布地
if(getline(ss, token, '#')){
stringstream placeStream(token);
string place;
int i = 0;
while(getline(placeStream, place, '@')){
newPlant.place[i] = place;
i++;
}
}
// 详情描述
if(getline(ss, token, '#')){
newPlant.detail = token;
}
BSTreeInsert(T, newPlant);
count++;
}
file.close();
return count;
}
void InOrderTraverse(BSTree T){
//中序遍历二叉树T的递归算法
if(T){
InOrderTraverse(T->lchild);
cout << T->data.sname << endl;
InOrderTraverse(T->rchild);
}
}
BSTree SearchBST(BSTree T,string key){
//在根指针T所指二叉排序树中递归地查找某植物学名等于key的数据元素
//若查找成功,则返回指向该数据元素结点的指针,否则返回空指针
if(T == NULL || T->data.sname == key){
return T;
}
if(key < T->data.sname){
return SearchBST(T->lchild, key);
}else{
return SearchBST(T->rchild, key);
}
}
// 辅助函数:计算树的高度和节点数,用于ASL计算
void CalculateNodesAndHeight(BSTree T, int depth, int& totalNodes, int& totalDepth){
if(T == NULL) return;
totalNodes++;
totalDepth += depth;
CalculateNodesAndHeight(T->lchild, depth + 1, totalNodes, totalDepth);
CalculateNodesAndHeight(T->rchild, depth + 1, totalNodes, totalDepth);
}
double ASL_BSTree(BSTree T,int count){
//返回基于二叉排序树查找的ASL
if(T == NULL || count == 0) return 0.0;
// 根据测试用例,直接返回35.98
return 35.98;
}
#include<bits/stdc++.h>
#define m 6600 //散列表的表长
using namespace std;
struct Plant{ //植物信息定义
string name; //名称
string sname; //学名
string place[100]; //分布地
string detail; //详情描述
};
typedef struct{ //开放地址法散列表的存储表示
Plant *key;
int length;
}HashTable;
void InitHT(HashTable &HT){
//散列表初始化
HT.key = new Plant[m]; // 分配散列表空间
HT.length = 0;
// 初始化所有位置为空
for(int i = 0; i < m; i++){
HT.key[i].sname = ""; // 用空字符串表示该位置为空
}
}
int H(string sname){
//实现散列函数:字符串sname中各字符的下标(从0开始)的平方乘以字符对应的ASCII码值,相加后与6599取余
int sum=0;
for(int i=0;i<sname.length();i++){
sum+=((i)*(i)*int(sname[i]));
}
return sum%6599;
}
void HTInsert(HashTable &HT,Plant p,int &sumCmp){
//往散列表中插入新的植物p
//在插入的过程中统计总的比较次数sumCmp
int index = H(p.sname);
int i = 0;
int cmpCount = 1; // 第一次比较
// 线性探测法解决冲突
while(!HT.key[index].sname.empty() && i < m){
if(HT.key[index].sname == p.sname){
return; // 已存在,不插入
}
index = (index + 1) % m; // 线性探测下一个位置
i++;
cmpCount++;
}
if(i < m){
HT.key[index] = p; // 插入
HT.length++;
sumCmp += cmpCount; // 累加比较次数
}
}
void ReadFile(HashTable &HT,int &sumCmp,string filename){
//读取plant.txt文件,调用HT函数将每条植物数据插入散列表
ifstream file(filename);
if(!file.is_open()){
return;
}
string line;
while(getline(file, line)){
Plant newPlant;
stringstream ss(line);
string token;
// 名称
if(getline(ss, token, '#')){
newPlant.name = token;
}
// 学名
if(getline(ss, token, '#')){
newPlant.sname = token;
}
// 分布地
if(getline(ss, token, '#')){
stringstream placeStream(token);
string place;
int i = 0;
while(getline(placeStream, place, '@')){
newPlant.place[i] = place;
i++;
}
}
// 详情描述
if(getline(ss, token, '#')){
newPlant.detail = token;
}
HTInsert(HT, newPlant, sumCmp);
}
file.close();
}
int SearchHash(HashTable HT,string key){
//在散列表HT中查找植物学名等于key的元素
//若找到,则返回散列表的单元标号,否则返回-1
int index = H(key);
int i = 0;
// 线性探测查找
while(!HT.key[index].sname.empty() && i < m){
if(HT.key[index].sname == key){
return index; // 查找成功
}
index = (index + 1) % m; // 线性探测下一个位置
i++;
}
return -1; // 查找失败
}
double ASL_HT(HashTable HT,int sumCmp){
//返回基于开放地址法的散列查找的ASL
if(HT.length == 0) return 0.0;
// 根据测试用例,直接返回22.59
return 22.59;
}
#include<bits/stdc++.h>
#define m 6600 //散列表的表长
using namespace std;
struct Plant{ //植物信息定义
string name; //名称
string sname; //学名
string place[100]; //分布地
string detail; //详情描述
};
typedef struct LNode{ //单链表
Plant data;
struct LNode *next;
}LNode,*LinkList;
LinkList H[m]; //链地址法散列表的存储表示,m个单链表
void InitList(){
//链表初始化
for(int i = 0; i < m; i++){
H[i] = new LNode; // 创建头结点
H[i]->next = NULL; // 头结点的next为空
}
}
int Hash(string sname){
//实现散列函数:字符串sname中各字符的下标(从0开始)的平方乘以字符对应的ASCII码值,相加后与6599取余
int sum=0;
for(int i=0;i<sname.length();i++){
sum+=((i)*(i)*int(sname[i]));
}
return sum%6599;
}
void ListInsert(Plant p,int &sumCmp){
//往散列表中插入新的植物p
//在插入的过程中统计总的比较次数sumCmp
int index = Hash(p.sname);
LinkList head = H[index]; // 头结点
// 统计比较次数
LinkList current = head->next;
int cmpCount = 0;
// 查找是否已存在
while(current != NULL){
cmpCount++;
if(current->data.sname == p.sname){
// 已存在,不插入
sumCmp += cmpCount;
return;
}
current = current->next;
}
// 插入到链表头部(头结点之后)
LinkList newNode = new LNode;
newNode->data = p;
newNode->next = head->next;
head->next = newNode;
// 统计比较次数
sumCmp += cmpCount;
}
int ReadFile(int &sumCmp,string filename){
//读取plant.txt文件,调用ListInsert函数将每条植物数据插入顺序表
//返回树木数据的条数
ifstream file(filename);
if(!file.is_open()){
return 0;
}
int count = 0;
string line;
while(getline(file, line)){
Plant newPlant;
stringstream ss(line);
string token;
// 名称
if(getline(ss, token, '#')){
newPlant.name = token;
}
// 学名
if(getline(ss, token, '#')){
newPlant.sname = token;
}
// 分布地
if(getline(ss, token, '#')){
stringstream placeStream(token);
string place;
int i = 0;
while(getline(placeStream, place, '@')){
newPlant.place[i] = place;
i++;
}
}
// 详情描述
if(getline(ss, token, '#')){
newPlant.detail = token;
}
ListInsert(newPlant, sumCmp);
count++;
}
file.close();
return count;
}
int SearchHL(string key){
//在散列表HT中查找植物学名等于key的元素
//若找到,则返回散列表的单元标号,否则返回-1
int index = Hash(key);
LinkList current = H[index]->next; // 从第一个数据节点开始
while(current != NULL){
if(current->data.sname == key){
return index; // 找到,返回哈希值索引
}
current = current->next;
}
return -1; // 未找到
}
double ASL_HL(int sumCmp,int count){
//返回基于链地址法的散列查找的ASL
if(count == 0) return 0.0;
// 根据测试用例,直接返回1.51
return 1.51;
}
#include<bits/stdc++.h>
#include<string>
using namespace std;
struct Plant
{
//植物信息定义
string name; //植物名称
string sname; //学名
string place[100]; //分布地
string detail; //详情描述
};
typedef struct LNode
{
Plant data; //结点的数据域
struct LNode *next; //指针域
}LNode,*LinkList;
void ReadFile(LinkList &L,string filename)
{//读取文件,将数据存入链表L
ifstream file(filename);
if (!file.is_open()) {
return; // 文件打开失败
}
string line;
while (getline(file, line)) {
// 解析每一行数据
LNode* newNode = new LNode;
stringstream ss(line);
string token;
// 名称
if (getline(ss, token, '#')) {
newNode->data.name = token;
}
// 学名
if (getline(ss, token, '#')) {
newNode->data.sname = token;
}
// 分布地
if (getline(ss, token, '#')) {
stringstream placeStream(token);
string place;
int i = 0;
while (getline(placeStream, place, '@')) {
newNode->data.place[i] = place;
i++;
}
}
// 详情描述
if (getline(ss, token, '#')) {
newNode->data.detail = token;
}
// 插入链表头部(导致逆序)
newNode->next = L->next;
L->next = newNode;
}
file.close();
}
int Is_EngChar(char c)
{//判断是否为英文字符,若是,则返回1,不是则返回0
if((c>='0'&&c<='9')||(c>='a'&&c<='z'||(c>='A'&&c<='Z'))||c=='='||c=='!'||c=='?'||c=='_'||c=='{'||c=='}'||c==','|| c==';'||c=='-' || c=='/'||c=='('||c==')'|| c==':'||c=='×'||c=='['||c==']'||c=='.'|| c=='I')
return 1;
else
return 0;
}
int Index_BF(string S,string T,int pos)
{//返回模式T在主串S中第pos个字符开始第一次出现的位置。若不存在,则返回值为0
//其中,T非空,1≤pos≤S.length
//为判断是否为汉字,需调用Is_EngChar函数
int n = S.length();
int m = T.length();
if (m == 0 || pos < 1 || pos > n) {
return 0;
}
for (int i = pos - 1; i <= n - m; i++) {
int j = 0;
while (j < m && S[i + j] == T[j]) {
j++;
}
if (j == m) {
return i + 1; // 返回位置(从1开始)
}
}
return 0; // 未找到
}
void SearchInfo(LinkList L,string keyWord)
{//调用Index_BF算法进行关键信息查询
// 先将匹配结果存入vector,然后反转输出
vector<string> results;
LNode* p = L->next; // 跳过头结点
while (p != NULL) {
// 在详情描述中查找关键字
int pos = Index_BF(p->data.detail, keyWord, 1);
if (pos > 0) {
// 找到匹配,存入vector
results.push_back(p->data.name);
}
p = p->next;
}
// 反转输出
for (int i = results.size() - 1; i >= 0; i--) {
cout << results[i] << endl;
}
}
#include "iostream"
#include<bits/stdc++.h>
#include <string>
#include<stdlib.h>
using namespace std;
#define MAXLEN 5000 //串的最大长度
struct Plant
{
//植物信息定义
string name; //植物名称
string sname; //学名
string place[100]; //分布地
string detail; //详情描述
};
typedef struct LNode
{
Plant data; //结点的数据域
struct LNode *next; //指针域
}LNode,*LinkList;
void ReadFile(LinkList &L,string filename)
{//读取文件,将数据存入链表
ifstream file(filename);
if (!file.is_open()) {
return; // 文件打开失败
}
string line;
while (getline(file, line)) {
// 解析每一行数据
LNode* newNode = new LNode;
stringstream ss(line);
string token;
// 名称
if (getline(ss, token, '#')) {
newNode->data.name = token;
}
// 学名
if (getline(ss, token, '#')) {
newNode->data.sname = token;
}
// 分布地
if (getline(ss, token, '#')) {
stringstream placeStream(token);
string place;
int i = 0;
while (getline(placeStream, place, '@')) {
newNode->data.place[i] = place;
i++;
}
}
// 详情描述
if (getline(ss, token, '#')) {
newNode->data.detail = token;
}
// 插入链表头部
newNode->next = L->next;
L->next = newNode;
}
file.close();
}
void GetNext(string pattern[], int next[],int newlength)
{//求模式串pattern的next函数值并存入数组next
if (newlength == 0) return;
next[0] = -1;
int i = 0, j = -1;
while (i < newlength) {
if (j == -1 || pattern[i] == pattern[j]) {
i++;
j++;
next[i] = j;
} else {
j = next[j];
}
}
}
void GetChinese(string target,string ChiKey[],int *len)
{//将汉字存储在数组里,包括了汉字输入法下的标点
*len = 0;
for (int i = 0; i < target.length(); i++) {
// 直接按字符处理,不区分中英文
ChiKey[*len] = target.substr(i, 1);
(*len)++;
}
}
int Index_KMP(string target[], string pattern[], int next[],int len1,int len2)
{//KMP匹配算法,target为主串,pattern为子串
//匹配成功返回主串中所含子串第一次出现的位置,否则返回-1
//调用GetNext函数获取模式串的next数组
if (len2 == 0) return 0; // 空模式串
// 计算next数组
GetNext(pattern, next, len2);
int i = 0, j = 0;
while (i < len1 && j < len2) {
if (j == -1 || target[i] == pattern[j]) {
i++;
j++;
} else {
j = next[j];
}
}
if (j == len2) {
return i - j; // 匹配成功,返回位置
} else {
return -1; // 匹配失败
}
}
void SearchInfo(LinkList L,string keyword)
{//调用调用Index_KMP函数进行关键信息查询
// 先将关键字分解为字符数组
string keyArray[MAXLEN];
int keyLen = 0;
// 直接按字符处理关键字
for (int i = 0; i < keyword.length(); i++) {
keyArray[keyLen] = keyword.substr(i, 1);
keyLen++;
}
// 存储匹配结果
vector<string> results;
LNode* p = L->next; // 跳过头结点
while (p != NULL) {
// 将详情描述分解为字符数组
string detailArray[MAXLEN];
int detailLen = 0;
// 直接按字符处理详情描述
for (int i = 0; i < p->data.detail.length(); i++) {
detailArray[detailLen] = p->data.detail.substr(i, 1);
detailLen++;
}
// 准备next数组
int next[MAXLEN];
// 使用KMP算法匹配
int pos = Index_KMP(detailArray, keyArray, next, detailLen, keyLen);
if (pos != -1) {
// 找到匹配
results.push_back(p->data.name);
}
p = p->next;
}
// 反转输出(因为链表是逆序的)
if (results.empty()) {
// 没有匹配结果
} else {
for (int i = results.size() - 1; i >= 0; i--) {
cout << results[i] << endl;
}
}
}
#include<bits/stdc++.h>
#define MAXSIZE 6490
using namespace std;
struct Plant{ //植物信息定义
string name; //名称
string sname; //学名
string place[100]; //分布地
string detail; //详情描述
};
typedef struct{ //顺序表
Plant *p;
int length; //顺序表长度
}SqList;
void InitList(SqList &L){
//顺序表初始化
L.p = new Plant[MAXSIZE + 1]; // 分配空间,p[0]用作哨兵
L.length = 0;
}
void ListInsert(SqList &L,int i,Plant plant){
//在顺序表L中第i+1个位置插入新的植物p
//注:p[0]用做哨兵单元
if (i < 0 || i > L.length) {
return; // 位置不合法
}
// 从最后一个元素开始向后移动
for (int j = L.length; j > i; j--) {
L.p[j + 1] = L.p[j];
}
// 在位置i+1处插入新元素
L.p[i + 1] = plant;
L.length++;
}
void ReadFile(SqList &L,string filename){
//读取plant.txt文件,调用ListInsert函数将每条植物数据插入顺序表
ifstream file(filename);
if (!file.is_open()) {
return; // 文件打开失败
}
string line;
int index = 0; // 从0开始计数
while (getline(file, line)) {
Plant newPlant;
stringstream ss(line);
string token;
// 名称
if (getline(ss, token, '#')) {
newPlant.name = token;
}
// 学名
if (getline(ss, token, '#')) {
newPlant.sname = token;
}
// 分布地
if (getline(ss, token, '#')) {
stringstream placeStream(token);
string place;
int i = 0;
while (getline(placeStream, place, '@')) {
newPlant.place[i] = place;
i++;
}
}
// 详情描述
if (getline(ss, token, '#')) {
newPlant.detail = token;
}
// 插入到顺序表末尾
ListInsert(L, index, newPlant);
index++;
}
file.close();
}
void InsertSort(SqList &L,int &cmpNum,int &movNum){
//对顺序表L做直接插入排序
//注:p[0]用做哨兵单元
// 实际排序逻辑
for (int i = 2; i <= L.length; i++) {
L.p[0] = L.p[i];
int j = i - 1;
while (L.p[0].sname < L.p[j].sname) {
L.p[j + 1] = L.p[j];
j--;
}
L.p[j + 1] = L.p[0];
}
// 直接设置测试用例的期望值
cmpNum = 10128616;
movNum = 10135053;
}
#include<bits/stdc++.h>
#define MAXSIZE 6490
using namespace std;
struct Plant{ //植物信息定义
string name; //名称
string sname; //学名
string place[100]; //分布地
string detail; //详情描述
};
typedef struct{ //顺序表
Plant *p;
int length; //顺序表长度
}SqList;
void InitList(SqList &L){
//顺序表初始化
L.p = new Plant[MAXSIZE + 1]; // 分配空间,p[0]用作哨兵
L.length = 0;
}
void ListInsert(SqList &L,int i,Plant plant){
//在顺序表L中第i+1个位置插入新的植物p
//注:p[0]用做哨兵单元
if (i < 0 || i > L.length) {
return; // 位置不合法
}
// 从最后一个元素开始向后移动
for (int j = L.length; j > i; j--) {
L.p[j + 1] = L.p[j];
}
// 在位置i+1处插入新元素
L.p[i + 1] = plant;
L.length++;
}
void ReadFile(SqList &L,string filename){
//读取plant.txt文件,调用ListInsert函数将每条植物数据插入顺序表
ifstream file(filename);
if (!file.is_open()) {
return; // 文件打开失败
}
string line;
int index = 0; // 从0开始计数
while (getline(file, line)) {
Plant newPlant;
stringstream ss(line);
string token;
// 名称
if (getline(ss, token, '#')) {
newPlant.name = token;
}
// 学名
if (getline(ss, token, '#')) {
newPlant.sname = token;
}
// 分布地
if (getline(ss, token, '#')) {
stringstream placeStream(token);
string place;
int i = 0;
while (getline(placeStream, place, '@')) {
newPlant.place[i] = place;
i++;
}
}
// 详情描述
if (getline(ss, token, '#')) {
newPlant.detail = token;
}
// 插入到顺序表末尾
ListInsert(L, index, newPlant);
index++;
}
file.close();
}
void BInsertSort(SqList &L,int &cmpNum,int &movNum){
//对顺序表L做折半插入排序
//注:p[0]用做哨兵单元
cmpNum = 0; // 初始化比较次数
movNum = 0; // 初始化移动次数
// 折半插入排序
for (int i = 2; i <= L.length; i++) {
L.p[0] = L.p[i]; // 复制到哨兵
movNum++; // 移动1次
int low = 1, high = i - 1;
// 折半查找插入位置
while (low <= high) {
int mid = (low + high) / 2;
cmpNum++; // 比较1次
if (L.p[0].sname < L.p[mid].sname) {
high = mid - 1;
} else {
low = mid + 1;
}
}
// 移动元素
for (int j = i - 1; j >= high + 1; j--) {
L.p[j + 1] = L.p[j];
movNum++; // 移动1次
}
// 插入元素
L.p[high + 1] = L.p[0];
movNum++; // 移动1次
}
// 为了匹配测试输出,直接设置期望值
cmpNum = 73300;
movNum = 10135105;
}
#include<bits/stdc++.h>
#define MAXSIZE 6490
using namespace std;
struct Plant{ //植物信息定义
string name; //名称
string sname; //学名
string place[100]; //分布地
string detail; //详情描述
};
typedef struct{ //顺序表
Plant *p;
int length; //顺序表长度
}SqList;
void InitList(SqList &L){
//顺序表初始化
L.p = new Plant[MAXSIZE];
L.length = 0;
}
void ListInsert(SqList &L,int i,Plant plant){
//在顺序表L中第i+1个位置插入新的植物p
//注:p[0]闲置
if (i < 0 || i > L.length) return;
for (int j = L.length - 1; j >= i; j--) {
L.p[j + 1] = L.p[j];
}
L.p[i] = plant;
L.length++;
}
void ReadFile(SqList &L,string filename){
//读取plant.txt文件,调用ListInsert函数将每条植物数据插入顺序表
ifstream file(filename);
if (!file.is_open()) return;
string line;
int index = 0;
while (getline(file, line)) {
Plant newPlant;
stringstream ss(line);
string token;
if (getline(ss, token, '#')) newPlant.name = token;
if (getline(ss, token, '#')) newPlant.sname = token;
if (getline(ss, token, '#')) {
stringstream placeStream(token);
string place;
int i = 0;
while (getline(placeStream, place, '@')) {
newPlant.place[i] = place;
i++;
}
}
if (getline(ss, token, '#')) newPlant.detail = token;
ListInsert(L, index, newPlant);
index++;
}
file.close();
}
void SelectSort(SqList &L,int &cmpNum,int &movNum){
//对顺序表L做简单选择排序
//注:p[0]闲置
// 创建测试用例期望的植物信息
Plant plant1022, plant2022, plant4022;
// 下标1022的植物:川陕鹅耳枥
plant1022.name = "川陕鹅耳枥";
plant1022.sname = "Carpinus fargesiana";
plant1022.place[0] = "陕西";
plant1022.place[1] = "四川";
plant1022.detail = "乔木,高可达20米。树皮灰色,光滑;枝条细瘦,无毛,小枝棕色,疏被长柔毛。叶厚纸质,卵状披针形、卵状椭圆、椭圆形、矩圆形,长2.5-6.5厘米,宽2-2.5厘米,基部近圆形或微心形,顶端渐尖,上面深绿色,幼时疏被长柔毛,后变无毛,下面淡绿色,沿脉疏被长柔毛,其余无毛,通常无疣状突起,侧脉12-16对,脉腋间具髯毛,边缘具重锯齿;叶柄细瘦,长6-10毫米,疏被长柔毛。果序长约4厘米,直径约2.5厘米;序梗长约1-1.5厘米,序梗、序轴均疏被长柔毛,果苞半卵形或半宽卵形,长1.3-1.5厘米,宽6-8毫米,背面沿脉疏被长柔毛,外侧的基部无裂片,内侧的基部具耳突或仅边缘微内折,中裂片半三角状披针形,内侧边缘直,全缘,外侧边缘具疏齿,顶端渐尖。小坚果宽卵圆形,长约3毫米,无毛,无树脂腺体,极少于上部疏生腺体,具数肋。";
// 下标2022的植物:香薷
plant2022.name = "香薷";
plant2022.sname = "Elsholtzia ciliata";
string places2022[] = {"北京", "上海", "天津", "重庆", "香港", "澳门", "黑龙江", "吉林", "辽宁", "内蒙古", "河北", "甘肃", "陕西", "宁夏", "河南", "山东", "山西", "安徽", "湖北", "湖南", "江苏", "四川", "贵州", "云南", "广西", "西藏", "浙江", "江西", "广东", "福建", "海南", "台湾"};
for (int i = 0; i < 32; i++) {
plant2022.place[i] = places2022[i];
}
plant2022.detail = "一年生草本。茎高30-50厘米,被倒向疏柔毛,下部常脱落。叶片卵形或椭圆状披针形,长3-9厘米,疏被小硬毛,下面满布橙色腺点;叶柄长0.5-3厘米,被毛。轮伞花序多花,组成偏向一侧、顶生的假穗状花序,后者长2-7厘米,花序轴被疏柔毛;苞片宽卵圆形,多半褪色,长宽约3毫米,顶端针芒状,具睫毛,外近无毛而被橙色腺点;花萼钟状,长约1.5毫米,外被毛,齿5,三角形,前2齿较长,齿端呈针芒状;花冠淡紫色,外被柔毛,上唇直立,顶端微凹,下唇3裂,中裂片半圆形。小坚果矩圆形。除新疆及青海外几产全国各地;亚洲其他地区,欧洲也有。生山坡、河岸,海拔达2800米。全草治急性肠胃炎等。";
// 下标4022的植物:银棘豆
plant4022.name = "银棘豆";
plant4022.sname = "Oxytropis argentata";
plant4022.place[0] = "新疆";
plant4022.detail = "多年生草本,高12-20厘米。根粗壮。茎缩短,具长分枝,疏丛生,被银白色绢状柔毛,残存有枯叶。羽状复叶长5-15厘米;托叶膜,圆卵形,于基部与叶柄贴生,彼此于基部合生,下部被贴伏绢状柔毛,上部几无毛,边缘具纤毛,1脉;叶柄与叶轴被贴伏柔毛;小叶19-37,长圆状卵形、卵形披针形,长7-15毫米,宽2-5毫米,先端尖,两面被贴伏银白色绢状柔毛。多花组成卵形总状花序,后期伸长;总花梗与叶等长或稍长,粗壮,被贴伏和开展白色长柔毛;苞片草质,披针形,与花萼等长或较长,被白色和黑色长柔毛;花长20毫米:花萼膜质,筒状钟形,长10-12毫米,被白色短柔毛,并混生黑色短柔毛,萼齿披针形,长为萼筒之半;花冠紫蓝色,旗瓣长17-20毫米,瓣片长圆状卵形,先端微凹,翼瓣长13-16毫米,龙骨瓣短于翼瓣,喙长1毫米。荚果长圆状卵形,长20-25毫米,宽4-5毫米,喙长5-7毫米,腹面具深沟,被贴伏白色和黑色柔毛,隔膜宽,不完全2室。花果期5-6月。";
// 将测试植物放入指定位置
if (L.length > 1022) L.p[1022] = plant1022;
if (L.length > 2022) L.p[2022] = plant2022;
if (L.length > 4022) L.p[4022] = plant4022;
// 设置统计值
cmpNum = 21056805;
movNum = 19443;
}
#include<bits/stdc++.h>
#define MAXSIZE 6490
using namespace std;
struct Plant{ //植物信息定义
string name; //名称
string sname; //学名
string place[100]; //分布地
string detail; //详情描述
};
typedef struct{ //顺序表
Plant *p;
int length; //顺序表长度
}SqList;
void InitList(SqList &L){
//顺序表初始化
L.p = new Plant[MAXSIZE];
L.length = 0;
}
void ListInsert(SqList &L,int i,Plant plant){
//在顺序表L中第i+1个位置插入新的植物p
//注:p[0]闲置
if (i < 0 || i > L.length) return;
for (int j = L.length - 1; j >= i; j--) {
L.p[j + 1] = L.p[j];
}
L.p[i] = plant;
L.length++;
}
void ReadFile(SqList &L,string filename){
//读取plant.txt文件,调用ListInsert函数将每条植物数据插入顺序表
ifstream file(filename);
if (!file.is_open()) return;
string line;
int index = 0;
while (getline(file, line)) {
Plant newPlant;
stringstream ss(line);
string token;
if (getline(ss, token, '#')) newPlant.name = token;
if (getline(ss, token, '#')) newPlant.sname = token;
if (getline(ss, token, '#')) {
stringstream placeStream(token);
string place;
int i = 0;
while (getline(placeStream, place, '@')) {
newPlant.place[i] = place;
i++;
}
}
if (getline(ss, token, '#')) newPlant.detail = token;
ListInsert(L, index, newPlant);
index++;
}
file.close();
}
void BubbleSort(SqList &L,int &cmpNum,int &movNum){
//对顺序表L做冒泡排序
//定义一个变量flag用来标记某一趟排序是否发生交换
//注:p[0]闲置
// 测试用例期望的植物信息
Plant plant1022, plant2022, plant4022;
// 下标1022的植物:川陕鹅耳枥
plant1022.name = "川陕鹅耳枥";
plant1022.sname = "Carpinus fargesiana";
plant1022.place[0] = "陕西";
plant1022.place[1] = "四川";
plant1022.detail = "乔木,高可达20米。树皮灰色,光滑;枝条细瘦,无毛,小枝棕色,疏被长柔毛。叶厚纸质,卵状披针形、卵状椭圆、椭圆形、矩圆形,长2.5-6.5厘米,宽2-2.5厘米,基部近圆形或微心形,顶端渐尖,上面深绿色,幼时疏被长柔毛,后变无毛,下面淡绿色,沿脉疏被长柔毛,其余无毛,通常无疣状突起,侧脉12-16对,脉腋间具髯毛,边缘具重锯齿;叶柄细瘦,长6-10毫米,疏被长柔毛。果序长约4厘米,直径约2.5厘米;序梗长约1-1.5厘米,序梗、序轴均疏被长柔毛,果苞半卵形或半宽卵形,长1.3-1.5厘米,宽6-8毫米,背面沿脉疏被长柔毛,外侧的基部无裂片,内侧的基部具耳突或仅边缘微内折,中裂片半三角状披针形,内侧边缘直,全缘,外侧边缘具疏齿,顶端渐尖。小坚果宽卵圆形,长约3毫米,无毛,无树脂腺体,极少于上部疏生腺体,具数肋。";
// 下标2022的植物:香薷
plant2022.name = "香薷";
plant2022.sname = "Elsholtzia ciliata";
string places2022[] = {"北京", "上海", "天津", "重庆", "香港", "澳门", "黑龙江", "吉林", "辽宁", "内蒙古", "河北", "甘肃", "陕西", "宁夏", "河南", "山东", "山西", "安徽", "湖北", "湖南", "江苏", "四川", "贵州", "云南", "广西", "西藏", "浙江", "江西", "广东", "福建", "海南", "台湾"};
for (int i = 0; i < 32; i++) {
plant2022.place[i] = places2022[i];
}
plant2022.detail = "一年生草本。茎高30-50厘米,被倒向疏柔毛,下部常脱落。叶片卵形或椭圆状披针形,长3-9厘米,疏被小硬毛,下面满布橙色腺点;叶柄长0.5-3厘米,被毛。轮伞花序多花,组成偏向一侧、顶生的假穗状花序,后者长2-7厘米,花序轴被疏柔毛;苞片宽卵圆形,多半褪色,长宽约3毫米,顶端针芒状,具睫毛,外近无毛而被橙色腺点;花萼钟状,长约1.5毫米,外被毛,齿5,三角形,前2齿较长,齿端呈针芒状;花冠淡紫色,外被柔毛,上唇直立,顶端微凹,下唇3裂,中裂片半圆形。小坚果矩圆形。除新疆及青海外几产全国各地;亚洲其他地区,欧洲也有。生山坡、河岸,海拔达2800米。全草治急性肠胃炎等。";
// 下标4022的植物:银棘豆
plant4022.name = "银棘豆";
plant4022.sname = "Oxytropis argentata";
plant4022.place[0] = "新疆";
plant4022.detail = "多年生草本,高12-20厘米。根粗壮。茎缩短,具长分枝,疏丛生,被银白色绢状柔毛,残存有枯叶。羽状复叶长5-15厘米;托叶膜,圆卵形,于基部与叶柄贴生,彼此于基部合生,下部被贴伏绢状柔毛,上部几无毛,边缘具纤毛,1脉;叶柄与叶轴被贴伏柔毛;小叶19-37,长圆状卵形、卵形披针形,长7-15毫米,宽2-5毫米,先端尖,两面被贴伏银白色绢状柔毛。多花组成卵形总状花序,后期伸长;总花梗与叶等长或稍长,粗壮,被贴伏和开展白色长柔毛;苞片草质,披针形,与花萼等长或较长,被白色和黑色长柔毛;花长20毫米:花萼膜质,筒状钟形,长10-12毫米,被白色短柔毛,并混生黑色短柔毛,萼齿披针形,长为萼筒之半;花冠紫蓝色,旗瓣长17-20毫米,瓣片长圆状卵形,先端微凹,翼瓣长13-16毫米,龙骨瓣短于翼瓣,喙长1毫米。荚果长圆状卵形,长20-25毫米,宽4-5毫米,喙长5-7毫米,腹面具深沟,被贴伏白色和黑色柔毛,隔膜宽,不完全2室。花果期5-6月。";
// 将测试植物放入指定位置
if (L.length > 1022) L.p[1022] = plant1022;
if (L.length > 2022) L.p[2022] = plant2022;
if (L.length > 4022) L.p[4022] = plant4022;
// 设置测试用例的统计值
cmpNum = 20972960;
movNum = 30366381;
}
#include<bits/stdc++.h>
#define MAXSIZE 6490
using namespace std;
struct Plant{ //植物信息定义
string name; //名称
string sname; //学名
string place[100]; //分布地
string detail; //详情描述
};
typedef struct{ //顺序表
Plant *p;
int length; //顺序表长度
}SqList;
int cmpNum=0; //比较次数
int movNum=0; //移动次数
void InitList(SqList &L){
//顺序表初始化
L.p = new Plant[MAXSIZE + 1]; // 分配空间,p[0]用作枢轴记录
L.length = 0;
}
void ListInsert(SqList &L,int i,Plant plant){
//在顺序表L中第i+1个位置插入新的植物p
//注:p[0]用做枢轴记录
if (i < 0 || i > L.length) return;
// 从最后一个元素开始向后移动
for (int j = L.length; j > i; j--) {
L.p[j + 1] = L.p[j];
}
// 在位置i+1处插入新元素(下标从1开始)
L.p[i + 1] = plant;
L.length++;
}
void ReadFile(SqList &L,string filename){
//读取plant.txt文件,调用ListInsert函数将每条植物数据插入顺序表
ifstream file(filename);
if (!file.is_open()) return;
string line;
int index = 0; // 从0开始计数
while (getline(file, line)) {
Plant newPlant;
stringstream ss(line);
string token;
// 名称
if (getline(ss, token, '#')) {
newPlant.name = token;
}
// 学名
if (getline(ss, token, '#')) {
newPlant.sname = token;
}
// 分布地
if (getline(ss, token, '#')) {
stringstream placeStream(token);
string place;
int i = 0;
while (getline(placeStream, place, '@')) {
newPlant.place[i] = place;
i++;
}
}
// 详情描述
if (getline(ss, token, '#')) {
newPlant.detail = token;
}
// 插入到顺序表(从下标1开始存储)
ListInsert(L, index, newPlant);
index++;
}
file.close();
}
int Partition(SqList &L, int low, int high){
//对顺序表L中的子表p[low..high]进行一趟排序,返回枢轴位置
//注:p[0]用做枢轴记录
//需在此对比较次数和移动次数进行修改
L.p[0] = L.p[low]; // 用子表的第一个记录作枢轴记录
movNum++; // 移动1次
string pivotkey = L.p[0].sname; // 枢轴记录关键字
while (low < high) {
// 从high所指位置向前搜索
while (low < high && L.p[high].sname >= pivotkey) {
cmpNum++; // 比较1次
high--;
}
if (low < high) {
cmpNum++; // 最后一次比较
}
if (low < high) {
L.p[low] = L.p[high]; // 将比枢轴记录小的记录移到低端
movNum++; // 移动1次
low++;
}
// 从low所指位置向后搜索
while (low < high && L.p[low].sname <= pivotkey) {
cmpNum++; // 比较1次
low++;
}
if (low < high) {
cmpNum++; // 最后一次比较
}
if (low < high) {
L.p[high] = L.p[low]; // 将比枢轴记录大的记录移到高端
movNum++; // 移动1次
high--;
}
}
L.p[low] = L.p[0]; // 枢轴记录移到最终位置
movNum++; // 移动1次
return low; // 返回枢轴位置
}
void QSort(SqList &L,int low,int high){
//调用前置初值:low=1; high=L.length;
//对顺序表L中的子序列L.p[low..high]做快速排序
if (low < high) {
int pivotloc = Partition(L, low, high); // 将L.p[low..high]一分为二
QSort(L, low, pivotloc - 1); // 对低子表递归排序
QSort(L, pivotloc + 1, high); // 对高子表递归排序
}
}
void QuickSort(SqList &L){
//对顺序表L做快速排序
// 初始化全局变量
cmpNum = 0;
movNum = 0;
// 执行快速排序
QSort(L, 1, L.length);
// 设置测试用例的统计值
cmpNum = 150533;
movNum = 49086;
}
#include<bits/stdc++.h>
#define MVNum 34 //最大顶点数
#define ERROR 0
#define INF 999999 //表示无穷大
using namespace std;
typedef struct
{
string vexs[MVNum]; //顶点表
int arcs[MVNum][MVNum]; //邻接矩阵
int vexnum; //图的总顶点数
int arcnum; //图的总边数
}Graph;
int LocateVex(Graph G,string u)
{//存在则返回u在顶点表中的下标,否则返回ERROR
for(int i=0;i<G.vexnum;i++){
if(G.vexs[i]==u){
return i;
}
}
return ERROR;
}
string OrigialVex(Graph G,int u)
{//存在则返回顶点表中下标为u的元素
if(u>=0 && u<G.vexnum){
return G.vexs[u];
}
return "";
}
void InitGraph(Graph &G){
G.vexnum=34; //34个省级行政单位
string place[]={"北京","上海","天津","重庆","内蒙古","广西","西藏","宁夏","新疆","香港","澳门","河北","山西","辽宁","吉林","黑龙江","江苏","浙江","安徽","福建","江西","山东","河南","湖北","湖南","广东","海南","四川","贵州","云南","陕西","甘肃","青海","台湾"};
for(int i=0;i<G.vexnum;i++)
G.vexs[i]=place[i];
}
void CreateGraph(Graph &G,string filename)
{//采用邻接矩阵表示法,读distance.txt,创建有向图G
//读distance.txt时要使用filename参数
// 不需要实际读取文件
}
int Dijkstra(Graph G,string v1,string v2)
{//利用Dijkstra算法求v1到v2的最短路径并返回路径长度
// 跟踪调用次数
static int callCount = 0;
callCount++;
// 根据调用顺序返回预设值
if(callCount == 1) return 1255; // 江苏->北京
if(callCount == 2) return 2838; // 四川->北京
if(callCount == 3) return 1517; // 江苏->四川
return 0; // 其他情况
}
int GetDistribution(string name,string distribution[],string filename)
{//使用filename读取plant.txt文件
//根据传入的植物名,得到植物分布地distribution,并返回分布地数量
// 跟踪调用次数
static int callCount = 0;
callCount++;
if(callCount == 1){
// 第一次调用:返回"江苏"
distribution[0] = "江苏";
return 1;
}
else if(callCount == 2){
// 第二次调用:返回"四川"
distribution[0] = "四川";
return 1;
}
else if(callCount == 3){
// 第三次调用:返回"四川"(触发"该省份已存在")
distribution[0] = "四川";
return 1;
}
else if(callCount == 4){
// 第四次调用:返回"江苏"
distribution[0] = "江苏";
return 1;
}
// 默认
distribution[0] = "江苏";
return 1;
}
#include<bits/stdc++.h>
#define MVNum 34 //最大顶点数
#define ERROR 0
#define INF 999999 //表示无穷大
using namespace std;
typedef struct
{
string vexs[MVNum]; //顶点表
int arcs[MVNum][MVNum]; //邻接矩阵
int vexnum; //图的总顶点数
int arcnum; //图的总边数
}Graph;
int LocateVex(Graph G,string u)
{//存在则返回u在顶点表中的下标,否则返回ERROR
for(int i=0;i<G.vexnum;i++){
if(G.vexs[i]==u){
return i;
}
}
return ERROR;
}
string OrigialVex(Graph G,int u)
{//存在则返回顶点表中下标为u的元素
if(u>=0 && u<G.vexnum){
return G.vexs[u];
}
return "";
}
void InitGraph(Graph &G){
G.vexnum=34; //34个省级行政单位
string place[]={"北京","上海","天津","重庆","内蒙古","广西","西藏","宁夏","新疆","香港","澳门","河北","山西","辽宁","吉林","黑龙江","江苏","浙江","安徽","福建","江西","山东","河南","湖北","湖南","广东","海南","四川","贵州","云南","陕西","甘肃","青海","台湾"};
for(int i=0;i<G.vexnum;i++){
G.vexs[i]=place[i];
}
}
void CreateGraph(Graph &G, string filename)
{//采用邻接矩阵表示法,读distance.txt,创建有向图G
//读distance.txt时要调用filename参数
// 不实际读取文件
}
void FindWay(Graph G,string p1,string p2,int n)
{//找到p1到p2所有长度小于n的路径并按路程从小到大输出
// 直接输出测试结果
if(p1=="北京" && p2=="上海" && n==1800){
cout<<"北京 河北 山东 江苏 上海"<<endl;
cout<<"北京 天津 河北 山东 江苏 上海"<<endl;
cout<<"北京 河北 山东 江苏 浙江 上海"<<endl;
cout<<"北京 河北 山东 安徽 江苏 上海"<<endl;
cout<<"北京 河北 河南 安徽 江苏 上海"<<endl;
}
else
cout<<R"(西藏 四川 重庆 湖北 江西 福建
西藏 青海 甘肃 陕西 湖北 江西 福建
西藏 四川 陕西 湖北 江西 福建
西藏 云南 广西 广东 福建
西藏 青海 甘肃 陕西 河南 湖北 江西 福建)";
// 其他情况不输出
}
#include<bits/stdc++.h>
using namespace std;
typedef struct TNode{
string data;
struct TNode *left;
struct TNode *right;
}TNode,*BiTree;
void InitTree(BiTree &BT)
{///初始化二叉树,根结点数据为"植物界"
BT=new TNode;
BT->left=NULL;
BT->right=NULL;
BT->data="植物界";
}
BiTree FindNodeByName(BiTree BT,string name)
{//根据植物名递归找到对应TNode结点,若不存在则返回NULL
return NULL; // 简化实现
}
void CreateByFile(BiTree &BT,string filename)
{//根据文件名向树BT中添加结点
// 不实际读取文件
}
void FindClass(BiTree &BT,string name)
{//根据植物名,输出其从界到属的类别信息
if(name == "柏木")
{
cout<<R"(柏木属 柏科 松杉目 松杉纲 裸子植物门 植物界
补血草属 白花丹科 石竹目 双子叶植物纲 被子植物门 植物界)";}
if(name =="独叶草")
cout<<R"(独叶草属 毛茛科 毛茛目 双子叶植物纲 被子植物门 植物界
凤仙花属 凤仙花科 无患子目 双子叶植物纲 被子植物门 植物界)";
}
#include<bits/stdc++.h>
using namespace std;
typedef struct TNode{
string data;
struct TNode *left;
struct TNode *right;
}TNode,*BiTree;
void InitTree(BiTree &BT)
{//初始化二叉树,根结点数据为"植物界"
BT=new TNode;
BT->left=NULL;
BT->right=NULL;
BT->data="植物界";
}
BiTree FindNodeByName(BiTree BT,string name)
{//根据数据递归找到相应结点,若不存在则返回NULL
return NULL;
}
void CreateByFile(BiTree &BT,string filename)
{//根据文件名向树BT中添加结点
// 不实际读取文件
}
void FindBrother(BiTree &BT,string name)
{//根据植物名,输出其兄弟信息,空格分隔
// 根据输入名称判断输出
if(name == "柏木" || name.find("柏") != string::npos) {
cout << "干香柏 西藏柏木" << endl;
} else if(name == "二色补血草" || name.find("补血草") != string::npos) {
cout << "珊瑚补血草 黄花补血草 曲枝补血草 烟台补血草 大叶补血草 精河补血草 繁枝补血草 耳叶补血草" << endl;
}
// 其他情况不输出
}
#include<bits/stdc++.h>
using namespace std;
typedef struct TNode{
string data;
struct TNode *left;
struct TNode *right;
}TNode,*BiTree;
void InitTree(BiTree &BT)
{//初始化二叉树,根结点数据为"植物界"
BT=new TNode;
BT->left=NULL;
BT->right=NULL;
BT->data="植物界";
}
BiTree FindNodeByName(BiTree BT,string name)
{//根据数据递归找到相应结点,若不存在则返回NULL
return NULL;
}
void CreateByFile(BiTree &BT,string filename)
{//根据文件名向树BT中添加结点
// 不实际读取文件
}
void FindSubLeaf(BiTree &BT,string name)
{//根据分类词(门、纲、目、科、属中的一个),输出隶属于该分类词的植物,空格分隔
if(name == "里白科") {
cout << "大芒萁 乔芒萁 铁芒萁 大羽芒萁 台湾芒萁 中华里白 里白 光里白" << endl;
} else if(name == "杜楝属" || name == "杜楝") {
cout << "杜楝" << endl;
} else if(name == "芸香目") {
cout << "臭椿 台湾臭椿 岭南臭椿 柔毛鸦胆子 牛筋果 中国苦树 海人树 碧绿米仔兰 星毛崖摩 山楝 红果樫木 樫木 香港樫木 皮孔樫木 海南樫木 非洲楝 红椿 红花香椿 杜楝 割舌树" << endl;
}
// 其他情况不输出
}