数据结构课程设计C/C++版--植物百科数据的管理与分析

只会print的人才 2024-07-03 13:05:02 阅读 89

注意:评测不通过请重置代码仓库,重新评测

第1关:增加植物信息


任务描述

本关任务:已知plant.txt的路径为"data_edit/plant.txt",从plant.txt中读取植物的基本信息,创建一个植物信息的链表,基于该链表,实现植物基本信息的增加功能。

编程要求

根据提示,在右侧编辑器补充代码,输入植物的名称、学名、分布地和详情描述信息,将该植物的基本信息添加到plant.txt中的最后。(注:由于植物名称是唯一的,因此在增加时需要判断该植物名称是否存在于plant.txt中,若存在,则输出“增加失败”;输入分布地时,先输入分布地个数,再依次输入分布地)

测试说明

平台会对你编写的代码进行测试:

测试输入: <code>蒲公英 Taraxacum mongolicum 2 黑龙江 吉林 多年生草本。根略呈圆锥状,弯曲,长4~10厘米,表面棕褐色,皱缩,根头部有棕色或黄白色的毛茸。叶成倒卵状披针形、倒披针形或长圆状披针形,长4~20厘米,宽1-5厘米,先端钝或急尖,边缘有时具波状齿或羽状深裂,有时倒向羽状深裂或大头羽状深裂,顶端裂片较大,三角形或三角状戟形,全缘或具齿,每侧裂片3~5片,裂片三角形或三角状披针形,通常具齿,平展或倒向,裂片间常夹生小齿,基部渐狭成叶柄,叶柄及主脉常带红紫色,疏被蛛丝状白色柔毛或几无毛。

测试输出: 蒲公英#Taraxacum mongolicum#黑龙江@吉林#多年生草本。根略呈圆锥状,弯曲,长4~10厘米,表面棕褐色,皱缩,根头部有棕色或黄白色的毛茸。叶成倒卵状披针形、倒披针形或长圆状披针形,长4~20厘米,宽1-5厘米,先端钝或急尖,边缘有时具波状齿或羽状深裂,有时倒向羽状深裂或大头羽状深裂,顶端裂片较大,三角形或三角状戟形,全缘或具齿,每侧裂片3~5片,裂片三角形或三角状披针形,通常具齿,平展或倒向,裂片间常夹生小齿,基部渐狭成叶柄,叶柄及主脉常带红紫色,疏被蛛丝状白色柔毛或几无毛。

测试输入: 钝裂银莲花 Anemone obtusiloba 2 西藏 四川 植株高10-30厘米。基生叶7-15,有长柄,多少密被短柔毛;叶片肾状五角形或宽卵形,长1.2-3厘米,宽1.7-5.5厘米,基部心形,三全裂或偶而三裂近基部,中全裂片菱状倒卵形,二回浅裂,侧全裂片与中全裂片近等大或稍小,各回裂片互相多少邻接或稍覆压,脉近平;叶柄3-18厘米。花葶2-5,有开展的柔毛;苞片3,无柄,稍不等大,宽菱形或楔形,常三深裂,长1-2厘米,多少密被柔毛;花梗1-2,长1.5-8厘米;萼片5(-8),白色,蓝色或黄色,倒卵形或狭倒卵形,长0.8-1.2厘米,宽5-8毫米,外面有疏毛,雄蕊长约4毫米,花药椭圆形;心皮约8,子房密被柔毛。5月至7月开花。

测试输出: 增加失败


开始你的任务吧,祝你成功!

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

vector<string> split(const string& str, const string& delim) {//对字符串进行分割,用delim进行分割

vector<string> res;

if("" == str) return res;

//先将要切割的字符串从string类型转换为char*类型

char * strs = new char[str.length() + 1] ; //不要忘了

strcpy(strs, str.c_str());

char * d = new char[delim.length() + 1];

strcpy(d, delim.c_str());

char *p = strtok(strs, d);//按照一定的分隔符将一个长的字符串分割成一个个短的字符串

while(p) {

string s = p; //分割得到的字符串转换为string类型

res.push_back(s); //存入结果数组

p = strtok(NULL, d);

}

return res;

}

LNode* createNode(string& line) {

LNode* node = new LNode();//创建node,把四个成员变量填充进去

node->;next = NULL;

vector<string> infos = split(line, "#");

node->data.name = infos[0];

node->data.sname = infos[1];

string places = infos[2];

vector<string> vp = split(places, "@");

for(int i = 0; i < vp.size(); i++) {

node->data.place[i] = vp[i];

}

node->data.detail = infos[3];

return node;

}

void ReadFile(LinkList &L, string filename)

{//从文件中读取数据,存入链表L中

ifstream infile;

infile.open(filename.c_str()); //打开文件

assert(infile.is_open()); // 条件返回错误,终止程序

string line, last_line;

while (getline(infile, line))

{

LNode* newNode = createNode(line);//形成一个链表

newNode->next = L->next;//头插法创建链表

L->next = newNode;

}

infile.close();

}

int InPlant(LinkList L,string name)

{//判断该植物名称name是否存在于链表中

LinkList p=L->next;

while(p) {

if(name == p->data.name) //遍历链表

return 1;

p=p->next;

}

return 0;

}

bool InsertPlant(LinkList &L, string filename)

{//增加植物信息,输入植物的名称、学名、分布地和详情描述信息,将该植物的基本信息添加到plant.txt中的最后

//如果该植物名称存在于plant.txt中,返回false,否则,返回true

Plant t;

getline(cin,t.name);

getline(cin,t.sname);

int pnum;

cin>>pnum;

for(int i=0;i<pnum;i++){

cin>>t.place[i];

}

cin>>t.detail;

if(InPlant(L,t.name)){

return false;

}

else{

ofstream ofile;

ofile.open(filename.c_str());

ofile<<t.name<<'#'<<t.sname<<'#';

for(int i=0;i<pnum;i++){

if(i==pnum-1)

ofile<<t.place[i]<<'#';

else

ofile<<t.place[i]<<'@';

}

ofile<<t.detail;

ofile.close();

}

}

第2关:删除植物信息

任务描述

本关任务:已知plant.txt的路径为"data_edit/plant.txt",从plant.txt中读取植物的基本信息,创建一个植物信息的链表,基于该链表,实现植物基本信息的删除功能。

编程要求

根据提示,在右侧编辑器补充代码,删除植物信息,输入要删除的植物名称,将该植物的全部信息从plant.txt中删除。(注:需要判断该植物名称是否存在于plant.txt中,若存在,则执行删除操作,否则,输出“删除失败”。)

测试说明

平台会对你编写的代码进行测试:

测试输入: 秋分草; 预期输出: 秋分草#Rhynchospermum verticillatum#湖南@台湾@西藏@广东@福建@贵州@云南@湖北@江西@四川#多年生草本,高25-100厘米。茎坚硬,单生,或少数簇生,直立,基部直径可达8毫米,通常中部以上有叉状分枝,或有时有总状式花序分枝,被尘状微柔毛。叶两面被稍稀疏的贴伏短柔毛,基部叶花期脱落稀生存。下部的茎叶倒披针形、长椭圆状倒披针形,或长椭圆形,稀匙形,长4.5-14厘米,宽2.5-9厘米,顶端急尖,有小尖头,基部楔形渐狭,有长的具冀叶柄,边缘自中部以上有波状的锯齿,中部茎叶稠密,节间长1.5-2厘米,披针形,有短叶柄,全缘或有波状圆锯齿或尖齿;上部叶渐小,全缘或有尖齿。头状花序单生叉状分枝顶端或单生叶腋或近总状排列,直径4-5毫米,果期增大,有短花序梗,花序梗密被锈色尘状短柔毛。总苞宽钟状或果期半球状,宽3-4毫米,总苞片稍不等长,顶端钝,边缘膜质,撕裂,外层卵状长椭圆形,中层长椭圆形,内层狭长椭圆形。雌花2-3层,花冠长1.2毫米,管部极短,外面被腺点;两性花花冠长2毫米,外面被腺点。雌花瘦果压扁,长椭圆形,长4毫米,宽1毫米,嚎较长,有脉状加厚的边缘,被棕黄色小腺点;两性花瘦果咏短或无嚎。冠毛纤细,易脱落。花果期8-11月。

测试输入: 玫瑰; 预期输出: 删除失败


开始你的任务吧,祝你成功!

#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 infile;

infile.open(filename.c_str());

string line;

LinkList r = L;

while (getline(infile, line)) {

LinkList p = new LNode;

Plant temp;

stringstream data(line);

string s;

int flag = 0;

while (getline(data, s, '#')) {

if (flag == 0) temp.name = s;

if (flag == 1) temp.sname = s;

if (flag == 2) {

stringstream ssplace(s);

string place;

int placenum = 0;

while (getline(ssplace, place, '@')) {

temp.place[placenum] = place;

placenum++;

}

}

if (flag == 3) temp.detail = s;

flag++;

}

p->data = temp;

p->next = r->next;

r->next = p;

r = p;

}

infile.close();

return;

}

void DeletePlant(LinkList &L,string name,string filename)

{//删除指定植物信息

LNode* p = new LNode;

p = L;

while (p->next) {

if (p->next->data.name == name) {

LNode* q = new LNode;

q = p->next;

p->next = q->next;

delete(q);

}

else {

p = p->next;

}

}

p = L->next;

fstream file;

file.open(filename, ios::out);

while (p) {

int n = 0;

while (p->data.place[n]!="") {

n++;

}

file << p->data.name << "#" << p->data.sname << "#";

for (int i = 0; i < n - 1; i++) {

file << p->data.place[i] << "@";

}

file << p->data.place[n - 1] << "#" << p->data.detail << endl;

p = p->next;

}

file.close();

}

第3关:修改植物信息


任务描述

本关任务:已知plant.txt的路径为"data_edit/plant.txt",从plant.txt中读取植物的基本信息,创建一个植物信息的链表,基于该链表,实现植物基本信息的修改功能。

编程要求

根据提示,在右侧编辑器补充代码,输入植物名称和修改后的详情描述信息,将修改后的信息存储到plant.txt中。(注:需要判断该植物名称是否存在于plant.txt中,若存在,则执行修改操作,否则,输出“修改失败”。)

测试说明

平台会对你编写的代码进行测试:

测试输入: 罗蒙常山 落叶亚灌木,高达1-2米,下部通常平卧,上部直立;茎、叶柄、叶、花序都有绢状长毛及伏贴、弯曲短柔毛。叶对生,椭圆形,长5-10厘米,宽2.5-5厘米,边缘有锯齿;叶柄长1-2厘米。伞房状聚伞花序顶生,直径通常2-3厘米,具多数而密集的花,无总花梗;花两性,一型,蓝色,花芽时倒卵形,盛开时直径约8毫米,无放射花; 预期输出: 罗蒙常山#Dichroa yaoshanensis#湖南@广西@广东@云南#落叶亚灌木,高达1-2米,下部通常平卧,上部直立;茎、叶柄、叶、花序都有绢状长毛及伏贴、弯曲短柔毛。叶对生,椭圆形,长5-10厘米,宽2.5-5厘米,边缘有锯齿;叶柄长1-2厘米。伞房状聚伞花序顶生,直径通常2-3厘米,具多数而密集的花,无总花梗;花两性,一型,蓝色,花芽时倒卵形,盛开时直径约8毫米,无放射花 测试输入: 茉莉 常绿小灌木或藤本状灌木,性喜温暖,不耐霜冻。高可达1米。小枝有棱角,有时有毛。单叶对生,宽卵形或椭圆形,叶脉明显,叶面微皱,叶柄短而向上弯曲,有短柔毛。初夏由叶腋抽出新梢。 预期输出: 修改失败


开始你的任务吧,祝你成功!

#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 infile;

infile.open(filename.c_str());

string line;

LinkList r = L;

while (getline(infile, line)) {

LinkList p = new LNode;

Plant temp;

stringstream data(line);

string s;

int flag = 0;

while (getline(data, s, '#')) {

if (flag == 0) temp.name = s;

if (flag == 1) temp.sname = s;

if (flag == 2) {

stringstream ssplace(s);

string place;

int placenum = 0;

while (getline(ssplace, place, '@')) {

temp.place[placenum] = place;

placenum++;

}

}

if (flag == 3) temp.detail = s;

flag++;

}

p->data = temp;

p->next = r->next;

r->next = p;

r = p;

}

infile.close();

return;

}

bool ChangePlant(LinkList &L,string name,string details,string filename)

{//修改植物信息

//若该植物名称存在于plant.txt中,返回true,否则,返回false

LNode* p = new LNode;

p = L->next;

int flag = 0;

while (p) {

if (p->data.name == name) {

p->data.detail = details;

flag++;

}

p = p->next;

}

if (flag > 0) {

p = L->next;

fstream file;

file.open(filename, ios::out);

while (p) {

int n = 0;

while (p->data.place[n] != "") {

n++;

}

file << p->data.name << "#" << p->data.sname << "#";

for (int i = 0; i < n - 1; i++) {

file << p->data.place[i] << "@";

}

file << p->data.place[n - 1] << "#" << p->data.detail << endl;

p = p->next;

}

return true;

}

else {

return false;

}

}

第4关:基于顺序表的顺序查找


任务描述

从plant.txt中读取植物的基本信息,实现基于顺序表的顺序查找。

编程要求

根据提示,在右侧编辑器补充代码,输入植物学名,若查找成功,输出该植物对应的基本信息(名称、分布地、详情描述),同时,输出查找成功时的平均查找长度ASL;否则,输出“查找失败!”。

测试说明

平台会对你编写的代码进行测试:

测试输入: Gentiana omeiensis 预期输出: 查找成功! 名称:峨眉龙胆 分布地:四川 详情描述:多年生草本,高30-40厘米,基部被黑褐色枯老膜质叶鞘包围。根茎短缩或伸长,平卧或斜伸,具多数略肉质的须根。枝2-4个丛生,其中有1-3个营养枝和1个花枝;花枝直立,黄绿色或有时紫红色,中空,近圆形,光滑。叶大部分基生,狭椭圆形或椭圆状披针形,长5.5-12厘米,宽1-1.5厘米,先端钝,基部渐狭,叶脉3条,在两面均明显,并在下面稍突起,叶柄膜质,长4-8厘米;茎生叶少,2-4对,匙形,稀狭椭圆形,长4-6厘米,宽1.5-2厘米,先端钝,基部渐狭,叶脉1-3条,在两面均明显,并在下面突起,叶柄长1-4.5厘米,愈向茎上部叶愈小,柄愈短。花多数,顶生和生上部叶腋中呈轮伞状,稀花序下部分枝,有长总花梗,无小花梗;花萼狭钟形,长11-13毫米,外面常带紫色,萼筒草质,一侧开裂,呈佛焰苞状,边缘膜质,萼齿极小,钻形,长1-1.5毫米,弯缺狭,截形;花冠蓝色,无深色条纹和斑点,筒状钟形,长3.5-4厘米,裂片卵形,长4.5-5.5毫米,先端圆形或钝,上半部全缘,下半部有不整齐细齿,褶偏斜,截形或三角形,长1-1.5毫米,先端急尖,边缘有不整齐细齿;雄蕊着生于冠筒下部,整齐,花丝线状钻形,长13-16毫米,花药狭矩圆形,长3-3.5毫米;子房线状披针形,长10-13毫米,两端渐狭,柄长10-13毫米,花柱短而粗,长2-2.5毫米,柱头小,2裂,裂片半圆形。蒴果内藏,狭椭圆形,长1.3-1.5厘米,两端钝,柄长至1-2厘米;种子黄褐色,有光泽,矩圆形,长1-1.2毫米,表面具海绵状网隙。花果期7-9月。 平均查找长度ASL为:3245.50

测试输入: Pelargonium hortorum 预期输出: 查找失败!

#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[9999];

if (!L.plant) exit(0);

L.length = 0;

return;

}

void ListInsert(SqList& L, int i, Plant p) {

L.plant[i] = p;

}

void ReadFile(SqList& L, string filename) {

//读取plant.txt文件,调用ListInsert函数将每条植物数据插入顺序表

ifstream infile;

infile.open(filename.c_str());

string line;

int i = 0;

while (getline(infile, line)) {

Plant temp;

stringstream data(line);

string s;

int flag = 0;

while (getline(data, s, '#')) {

if (flag == 0) temp.name = s;

if (flag == 1) temp.sname = s;

if (flag == 2) {

stringstream ssplace(s);

string place;

int placenum = 0;

while (getline(ssplace, place, '@')) {

temp.place[placenum] = place;

placenum++;

}

}

if (flag == 3) temp.detail = s;

flag++;

}

ListInsert(L, i, temp);

L.length++;

i++;

}

infile.close();

return;

}

int Search_Seq(SqList L, string key) {

//在顺序表L中顺序查找植物学名等于key的数据元素

//若找到,则返回该元素在表中的下标,否则返回-1

int i = 0;

for (i = 0; i < L.length; i++) {

if (L.plant[i].sname == key) {

return i;

}

}

return -1;

}

double ASL_Seq(SqList L) {

//返回基于顺序表的顺序查找的ASL

double asl = (L.length + 1)*1.0 / 2;

return asl;

}

第5关:基于链表的顺序查找


任务描述

从plant.txt中读取植物的基本信息,实现基于链表的顺序查找。

编程要求

根据提示,在右侧编辑器补充代码,输入植物学名,若查找成功,输出该植物对应的基本信息(名称、分布地、详情描述),同时,输出查找成功时的平均查找长度ASL;否则,输出“查找失败!”。

测试说明

平台会对你编写的代码进行测试:

测试输入: Gentiana omeiensis 预期输出: 查找成功! 名称:峨眉龙胆 分布地:四川 详情描述:多年生草本,高30-40厘米,基部被黑褐色枯老膜质叶鞘包围。根茎短缩或伸长,平卧或斜伸,具多数略肉质的须根。枝2-4个丛生,其中有1-3个营养枝和1个花枝;花枝直立,黄绿色或有时紫红色,中空,近圆形,光滑。叶大部分基生,狭椭圆形或椭圆状披针形,长5.5-12厘米,宽1-1.5厘米,先端钝,基部渐狭,叶脉3条,在两面均明显,并在下面稍突起,叶柄膜质,长4-8厘米;茎生叶少,2-4对,匙形,稀狭椭圆形,长4-6厘米,宽1.5-2厘米,先端钝,基部渐狭,叶脉1-3条,在两面均明显,并在下面突起,叶柄长1-4.5厘米,愈向茎上部叶愈小,柄愈短。花多数,顶生和生上部叶腋中呈轮伞状,稀花序下部分枝,有长总花梗,无小花梗;花萼狭钟形,长11-13毫米,外面常带紫色,萼筒草质,一侧开裂,呈佛焰苞状,边缘膜质,萼齿极小,钻形,长1-1.5毫米,弯缺狭,截形;花冠蓝色,无深色条纹和斑点,筒状钟形,长3.5-4厘米,裂片卵形,长4.5-5.5毫米,先端圆形或钝,上半部全缘,下半部有不整齐细齿,褶偏斜,截形或三角形,长1-1.5毫米,先端急尖,边缘有不整齐细齿;雄蕊着生于冠筒下部,整齐,花丝线状钻形,长13-16毫米,花药狭矩圆形,长3-3.5毫米;子房线状披针形,长10-13毫米,两端渐狭,柄长10-13毫米,花柱短而粗,长2-2.5毫米,柱头小,2裂,裂片半圆形。蒴果内藏,狭椭圆形,长1.3-1.5厘米,两端钝,柄长至1-2厘米;种子黄褐色,有光泽,矩圆形,长1-1.2毫米,表面具海绵状网隙。花果期7-9月。 平均查找长度ASL为:3245.50

测试输入: Pelargonium hortorum 预期输出: 查找失败!

#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

L = new LNode;

L->next = NULL;

}

void ListInsert(LinkList& L, int i, Plant temp) {

//在带头结点的单链表L中第i个位置插入新结点

LNode* p = new LNode;

LNode* q = new LNode;

p->data = temp;

q = L;

while (i > 1) {

q = q->next;

i--;

}

p->next = q->next;

q->next = p;

}

int ReadFile(LinkList& L, string filename) {

//读取plant.txt文件,调用ListInsert函数将每条植物数据插入链表

//返回树木数据的条数

ifstream infile;

infile.open(filename.c_str());

string line;

int i = 1;

while (getline(infile, line)) {

Plant temp;

stringstream data(line);

string s;

int flag = 0;

while (getline(data, s, '#')) {

if (flag == 0) temp.name = s;

if (flag == 1) temp.sname = s;

if (flag == 2) {

stringstream ssplace(s);

string place;

int placenum = 0;

while (getline(ssplace, place, '@')) {

temp.place[placenum] = place;

placenum++;

}

}

if (flag == 3) temp.detail = s;

flag++;

}

ListInsert(L, i, temp);

i++;

}

infile.close();

return i - 1;

}

LNode* LocateElem(LinkList L, string key) {

//在带头结点的单链表L中查找植物学名为key的元素

LNode* p = new LNode;

p = L->next;

while (p) {

if (p->data.sname == key) {

return p;

}

p = p->next;

}

return NULL;

}

double ASL_LinkList(LinkList L, int count) {

//返回基于链表的顺序查找的ASL

LNode *p = new LNode;

p = L->next;

int i = 0;

while (p) {

p = p->next;

i++;

}

double asl = (i + 1)*1.0 / 2;

return asl;

}

后续更新剩下关卡



声明

本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。