数据结构课程设计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;
}
后续更新剩下关卡
声明
本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。