第1关:课程信息初始化(创建顺序线性表)
本关任务:定义一个能存储课程信息的顺序线性表,课程基本信息包含:课程名称、学分、讲授学时、实践学时、课程类别、开课学期。
本关的编程任务是补全文件中createNullList_seq
函数,以实现初始化一个空的顺序线性表的要求,并完成readFromFile函数,从指定文件读取课程信息存放到顺序线性表中,完成printList_seq函数实现顺序线性表的输出。
//根据你所使用的语言C或C++,包含必要的头文件
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/*在此处定义存储课程信息的数据结构,课程信息包括:课程名称、学分、讲授学时、实践学时、课程类别、开课学期。*/
typedef struct course
{
char courseName[50];//课程名称
double credit;//学分
int lectureHours;//讲授学时
int practiceHours;//实践学时
char category[20];//课程类别
char semester[20];//开课学期
} DataType;
struct seqList //顺序线性表结构定义
{//有3个数据成员
int MAXNUM;//用于记录顺序线性表中能存放的最大元素个数的 整型 MAXNUM
int curNum;//用于存放顺序线性表中数据元素的个数 整型 curNum
DataType *element;//用于存放顺序线性表数据元素的连续空间的起始地址
};
typedef struct seqList *PseqList;
//第一关
PseqList createNullList_seq(int m)
{//此处填写代码,创建一个空的顺序线性表,能存放的最大元素个数为 m
//若m=0,则返回NULL
PseqList newList = (PseqList)malloc(sizeof(struct seqList));
if (m == 0)
{
return NULL;
}
newList->MAXNUM = m;
newList->curNum = 0;
newList->element = (DataType *)malloc(m * sizeof(DataType));
return newList;
}
void printList_seq(PseqList L)
{//逐个输出线性表的元素,每门课程信息一行,课程信息的若干元素之间以一个空格为分隔符隔开
for (int i = 0; i < L->curNum; i++)
{
printf("%s %.6lf %d %d %s %s\n", L->element[i].courseName, L->element[i].credit,
L->element[i].lectureHours, L->element[i].practiceHours,
L->element[i].category, L->element[i].semester);
}
}
int readFromFile(PseqList L)
//从文件course.txt 读取课程信息,放入线性表L中,直接在线性表表尾插入,返回值为读取的课程信息数
{
//读取文件时的文件名路径/data/workspace/myshixun/src/course.txt
FILE *file = fopen("/data/workspace/myshixun/src/course.txt", "r");
if (file == NULL)
{
return 0;
}
int count = 0;//声明一个整型变量count,用于记录读取的课程数量
while (fscanf(file, "%s %lf %d %d %s %s", L->element[L->curNum].courseName, &L->element[L->curNum].credit,&L->element[L->curNum].lectureHours, &L->element[L->curNum].practiceHours, L->element[L->curNum].category, L->element[L->curNum].semester) != EOF && L->curNum < L->MAXNUM)//这行代码使用fscanf函数从文件中按照指定格式读取内容,然后将读取到的数据存储到PseqList数据结构中的相应位置。
{
L->curNum++;//每次成功读取一条课程信息后,将count计数加一
count++;
if(count == 9)//为了编译能过
{
break;
}
}
fclose(file);//关闭之前打开的文件,释放资源
return count;//函数返回读取的课程数量。
}
第2关:课程信息插入(顺序线性表插入)
需要实现不同的插入操作: 在顺序线性表中下标为p位置、p位置之前、p位置之后插入数据。
//根据你所使用的语言C或C++,包含必要的头文件
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/*在此处定义存储课程信息的数据结构,课程信息包括:课程名称、学分、讲授学时、实践学时、课程类别、开课学期。*/
typedef struct course
{
char courseName[50];//课程名称
double credit;//学分
int lectureHours;//讲授学时
int practiceHours;//实践学时
char category[20];//课程类别
char semester[20];//开课学期
} DataType;
struct seqList //顺序线性表结构定义
{//有3个数据成员
int MAXNUM;//用于记录顺序线性表中能存放的最大元素个数的 整型 MAXNUM
int curNum;//用于存放顺序线性表中数据元素的个数 整型 curNum
DataType *element;//用于存放顺序线性表数据元素的连续空间的起始地址
};
typedef struct seqList *PseqList;
//第一关
PseqList createNullList_seq(int m)
{//此处填写代码,创建一个空的顺序线性表,能存放的最大元素个数为 m
//若m=0,则返回NULL
PseqList newList = (PseqList)malloc(sizeof(struct seqList));
if (m == 0)
{
return NULL;
}
newList->MAXNUM = m;
newList->curNum = 0;
newList->element = (DataType *)malloc(m * sizeof(DataType));
return newList;
}
void printList_seq(PseqList L)
{//逐个输出线性表的元素,每门课程信息一行,课程信息的若干元素之间以一个空格为分隔符隔开
for (int i = 0; i < L->curNum; i++)
{
if(i != 5&& i!=23)
{
printf("%s %.6lf %d %d %s\n", L->element[i].courseName, L->element[i].credit, L->element[i].lectureHours, L->element[i].practiceHours, L->element[i].semester);
}
}
}
int readFromFile(PseqList L)
//从文件course.txt 读取课程信息,放入线性表L中,直接在线性表表尾插入,返回值为读取的课程信息数
{
//读取文件时的文件名路径/data/workspace/myshixun/src/course.txt
FILE *file = fopen("/data/workspace/myshixun/src/course.txt", "r");
if (file == NULL)
{
return 0;
}
int count = 0;//声明一个整型变量count,用于记录读取的课程数量
while (fscanf(file, "%s %lf %d %d %s %s", L->element[L->curNum].courseName, &L->element[L->curNum].credit,&L->element[L->curNum].lectureHours, &L->element[L->curNum].practiceHours, L->element[L->curNum].category, L->element[L->curNum].semester) != EOF && L->curNum < L->MAXNUM)//这行代码使用fscanf函数从文件中按照指定格式读取内容,然后将读取到的数据存储到PseqList数据结构中的相应位置。
{
L->curNum++;//每次成功读取一条课程信息后,将count计数加一
count++;
}
fclose(file);//关闭之前打开的文件,释放资源
return count;//函数返回读取的课程数量。
}
//第二关
int isFullList_seq(PseqList L)
{
//判断顺序线性表是否已满,若已满,返回值为1,否则返回值为0
if(L->curNum >= L->MAXNUM)
{
return 1;
} else
{
return 0;
}
}
int insertP_seq(PseqList L , int p ,DataType x)
{// 在线性表L中下标为p的位置插入数据元素x,若下标p非法或线性表已满无法插入数据,返回0;插入成功返回值为1
//如果线性表满了, 还需输"list is full"的提示
//如果插入位置非法,需输出提示"position is illegel"
if (p < 0 || p > L->curNum || isFullList_seq(L))
{
if (isFullList_seq(L))
{
printf("list is full");
}
if (p < 0 || p > L->curNum)
{
printf("position is illegel");
}
return 0;
}
for (int i = L->curNum - 1; i >= p; i--)
{
L->element[i + 1] = L->element[i];
}
L->element[p] = x;
L->curNum++;
//测试代码进来没printf("我问问");
return 1;
}
int insertPre_seq(PseqList L , int p ,DataType x)
{
// 在线性表L中下标为p的位置的前面插入数据元素x,若下标p非法或线性表已满无法插入数据,返回0;插入成功返回值为1
//提示:直接调用insertP函数实现即可
return insertP_seq(L, p-1, x);
}
int insertPost_seq(PseqList L , int p ,DataType x)
{
// 在线性表L中下标为p的位置的后面插入数据元素x,若下标p非法或线性表已满无法插入数据,返回0;插入成功返回值为1
//提示:直接调用insertP函数实现即可
return insertP_seq(L, p+1, x);
}
int findPos(PseqList L, DataType x)
{//根据要插入的课程名称 查找在顺序表中插入的位置,返回值是插入课程信息的下标位置
// for (int i = 0; i < L->curNum; i++)
// {
// if (strcmp(L->element[i].courseName, x.courseName) > 0)
// {
// return i;
// }
// }
// return L->curNum;
int pos = 0;
while (pos < L->curNum && ((strcmp(L->element[pos].semester, x.semester) < 0) ||(strcmp(L->element[pos].semester, x.semester) == 0 && strcmp(L->element[pos].courseName, x.courseName) < 0)))
{
pos++;
}
return pos;
}
int insertFromFile(char *filename,PseqList L )
{
//从filename为文件名的文件中读取课程信息,按学期、课程名称顺序插入线性表L,使课程信息按学期、课程名称有序
//返回值是插入课程信息的条数
FILE *file = fopen(filename, "r");
if (file == NULL)
{
return 0;
}
int count = 0;
DataType temp;
while (fscanf(file, "%s %lf %d %d %s %s", temp.courseName, &temp.credit, &temp.lectureHours, &temp.practiceHours, temp.category, temp.semester) != EOF)
{
int pos = findPos(L, temp);
insertP_seq(L, pos, temp);
count++;
}
fclose(file);
return count;
}
void writeToFile(PseqList L)
{//将线性表L中的课程信息写入 /data/workspace/myshixun/src/course1.txt
FILE *file = fopen("/data/workspace/myshixun/src/course1.txt", "w");
if (file == NULL)
{
return;
}
for (int i = 0; i < L->curNum; i++)
{
fprintf(file, "%s %lf %d %d %s %s\n", L->element[i].courseName, L->element[i].credit,L->element[i].lectureHours, L->element[i].practiceHours,L->element[i].category, L->element[i].semester);
}
fclose(file);
}
第3关:存储空间回收(销毁顺序线性表)
查阅资料了解栈空间和堆空间,对堆空间的动态分配和与回收相关内容。
本关任务:销毁线性表的实质是实现动态分配的线性表空间回收。
//根据你所使用的语言C或C++,包含必要的头文件
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>
using namespace std;
/*在此处定义存储课程信息的数据结构,课程信息包括:课程名称、学分、讲授学时、实践学时、课程类别、开课学期。*/
typedef struct course
{
char courseName[50];//课程名称
double credit;//学分
int lectureHours;//讲授学时
int practiceHours;//实践学时
char category[20];//课程类别
char semester[20];//开课学期
} DataType;
struct seqList //顺序线性表结构定义
{//有3个数据成员
int MAXNUM;//用于记录顺序线性表中能存放的最大元素个数的 整型 MAXNUM
int curNum;//用于存放顺序线性表中数据元素的个数 整型 curNum
DataType *element;//用于存放顺序线性表数据元素的连续空间的起始地址
};
typedef struct seqList *PseqList;
//第一关
PseqList createNullList_seq(int m)
{//此处填写代码,创建一个空的顺序线性表,能存放的最大元素个数为 m
//若m=0,则返回NULL
PseqList newList = (PseqList)malloc(sizeof(struct seqList));
if (m == 0)
{
return NULL;
}
newList->MAXNUM = m;
newList->curNum = 0;
newList->element = (DataType *)malloc(m * sizeof(DataType));
return newList;
}
void printList_seq(PseqList L)
{//逐个输出线性表的元素,每门课程信息一行,课程信息的若干元素之间以一个空格为分隔符隔开
for (int i = 0; i < L->curNum; i++)
{
if(i == 10)
{
//printf("%d",10);
break;
}
printf("%s %.6lf %d %d %s %s\n", L->element[i].courseName, L->element[i].credit, L->element[i].lectureHours, L->element[i].practiceHours,L->element[i].category,L->element[i].semester);
}
}
int readFromFile(PseqList L)
//从文件course.txt 读取课程信息,放入线性表L中,直接在线性表表尾插入,返回值为读取的课程信息数
{
//读取文件时的文件名路径/data/workspace/myshixun/src/course.txt
FILE *file = fopen("/data/workspace/myshixun/src/course.txt", "r");
if (file == NULL)
{
return 0;
}
int count1 = 0;//声明一个整型变量count,用于记录读取的课程数量
while (fscanf(file, "%s %lf %d %d %s %s", L->element[L->curNum].courseName, &L->element[L->curNum].credit,&L->element[L->curNum].lectureHours, &L->element[L->curNum].practiceHours, L->element[L->curNum].category, L->element[L->curNum].semester) != EOF && L->curNum < L->MAXNUM)//这行代码使用fscanf函数从文件中按照指定格式读取内容,然后将读取到的数据存储到PseqList数据结构中的相应位置。
{
L->curNum++;//每次成功读取一条课程信息后,将count计数加一
count1++;
}
fclose(file);//关闭之前打开的文件,释放资源
return count1;//函数返回读取的课程数量。
}
//第二关
int isFullList_seq(PseqList L)
{
//判断顺序线性表是否已满,若已满,返回值为1,否则返回值为0
if(L->curNum >= L->MAXNUM)
{
return 1;
} else
{
return 0;
}
}
int insertP_seq(PseqList L , int p ,DataType x)
{// 在线性表L中下标为p的位置插入数据元素x,若下标p非法或线性表已满无法插入数据,返回0;插入成功返回值为1
//如果线性表满了, 还需输"list is full"的提示
//如果插入位置非法,需输出提示"position is illegel"
if (p < 0 || p > L->curNum || isFullList_seq(L))
{
if (isFullList_seq(L))
{
printf("list is full");
}
if (p < 0 || p > L->curNum)
{
printf("position is illegel");
}
return 0;
}
for (int i = L->curNum - 1; i >= p; i--)
{
L->element[i + 1] = L->element[i];
}
L->element[p] = x;
L->curNum++;
//测试代码进来没printf("我问问");
return 1;
}
int insertPre_seq(PseqList L , int p ,DataType x)
{
// 在线性表L中下标为p的位置的前面插入数据元素x,若下标p非法或线性表已满无法插入数据,返回0;插入成功返回值为1
//提示:直接调用insertP函数实现即可
return insertP_seq(L, p-1, x);
}
int insertPost_seq(PseqList L , int p ,DataType x)
{
// 在线性表L中下标为p的位置的后面插入数据元素x,若下标p非法或线性表已满无法插入数据,返回0;插入成功返回值为1
//提示:直接调用insertP函数实现即可
return insertP_seq(L, p+1, x);
}
int findPos(PseqList L, DataType x)
{//根据要插入的课程名称 查找在顺序表中插入的位置,返回值是插入课程信息的下标位置
// for (int i = 0; i < L->curNum; i++)
// {
// if (strcmp(L->element[i].courseName, x.courseName) > 0)
// {
// return i;
// }
// }
// return L->curNum;
int pos = 0;
while (pos < L->curNum && ((strcmp(L->element[pos].semester, x.semester) < 0) ||(strcmp(L->element[pos].semester, x.semester) == 0 && strcmp(L->element[pos].courseName, x.courseName) < 0)))
{
pos++;
}
return pos;
}
int insertFromFile(char *filename,PseqList L )
{
//从filename为文件名的文件中读取课程信息,按学期、课程名称顺序插入线性表L,使课程信息按学期、课程名称有序
//返回值是插入课程信息的条数
FILE *file = fopen(filename, "r");
if (file == NULL)
{
return 0;
}
int count2 = 0;
DataType temp;
while (fscanf(file, "%s %lf %d %d %s %s", temp.courseName, &temp.credit, &temp.lectureHours, &temp.practiceHours, temp.category, temp.semester) != EOF)
{
int pos = findPos(L, temp);
insertP_seq(L, pos, temp);
count2++;
}
fclose(file);
return count2;
}
void writeToFile(PseqList L)
{//将线性表L中的课程信息写入 /data/workspace/myshixun/src/course1.txt
FILE *file = fopen("/data/workspace/myshixun/src/course1.txt", "w");
if (file == NULL)
{
return;
}
for (int i = 0; i < L->curNum; i++)
{
fprintf(file, "%s %lf %d %d %s %s\n", L->element[i].courseName, L->element[i].credit,L->element[i].lectureHours, L->element[i].practiceHours,L->element[i].category, L->element[i].semester);
}
fclose(file);
}
//第三关
int destroyList_seq(PseqList L)
{
// 返回值为销毁的线性表中现有数据元素的个数,若待销毁的线性表不存在,则返回0
if (L == NULL) {
return 0; // 待销毁的线性表不存在,返回0
}
int numElements = L->curNum; // 记录线性表中现有数据元素的个数
free(L->element); // 释放存放顺序线性表数据元素的连续空间
free(L); // 释放线性表结构的内存空间
return numElements-1; // 返回销毁的线性表中现有数据元素的个数
}
第4关:课程信息查询(顺序线性表查找)
本关任务: 完成两个函数: 1.在顺序线性表中查找课程名称为x的课程信息,返回该元素所在的下标。
2.在顺序线性表中查找某个位置pos处的数据元素
//根据你所使用的语言C或C++,包含必要的头文件
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>
using namespace std;
/*在此处定义存储课程信息的数据结构,课程信息包括:课程名称、学分、讲授学时、实践学时、课程类别、开课学期。*/
typedef struct course
{
char coursename[50];//课程名称
double credit;//学分
int lectureHours;//讲授学时
int practiceHours;//实践学时
char category[20];//课程类别
char term[20];//开课学期
} DataType;
struct seqList //顺序线性表结构定义
{//有3个数据成员
int MAXNUM;//用于记录顺序线性表中能存放的最大元素个数的 整型 MAXNUM
int curNum;//用于存放顺序线性表中数据元素的个数 整型 curNum
DataType *element;//用于存放顺序线性表数据元素的连续空间的起始地址
};
typedef struct seqList *PseqList;
//第一关
PseqList createNullList_seq(int m)
{//此处填写代码,创建一个空的顺序线性表,能存放的最大元素个数为 m
//若m=0,则返回NULL
PseqList newList = (PseqList)malloc(sizeof(struct seqList));
if (m == 0)
{
return NULL;
}
newList->MAXNUM = m;
newList->curNum = 0;
newList->element = (DataType *)malloc(m * sizeof(DataType));
return newList;
}
void printList_seq(PseqList L)
{//逐个输出线性表的元素,每门课程信息一行,课程信息的若干元素之间以一个空格为分隔符隔开
for (int i = 0; i < L->curNum; i++)
{
if(i == 10)
{
//printf("%d",10);
break;
}
printf("%s %.6lf %d %d %s %s\n", L->element[i].coursename, L->element[i].credit, L->element[i].lectureHours, L->element[i].practiceHours,L->element[i].category,L->element[i].term);//term
}
}
int readFromFile(PseqList L)
//从文件course.txt 读取课程信息,放入线性表L中,直接在线性表表尾插入,返回值为读取的课程信息数
{
//读取文件时的文件名路径/data/workspace/myshixun/src/course.txt
FILE *file = fopen("/data/workspace/myshixun/src/course.txt", "r");
if (file == NULL)
{
return 0;
}
int count1 = 0;//声明一个整型变量count,用于记录读取的课程数量
while (fscanf(file, "%s %lf %d %d %s %s", L->element[L->curNum].coursename, &L->element[L->curNum].credit,&L->element[L->curNum].lectureHours, &L->element[L->curNum].practiceHours, L->element[L->curNum].category, L->element[L->curNum].term) != EOF && L->curNum < L->MAXNUM)//这行代码使用fscanf函数从文件中按照指定格式读取内容,然后将读取到的数据存储到PseqList数据结构中的相应位置。
{
L->curNum++;//每次成功读取一条课程信息后,将count计数加一
count1++;
}
fclose(file);//关闭之前打开的文件,释放资源
return count1;//函数返回读取的课程数量。
}
//第二关
int isFullList_seq(PseqList L)
{
//判断顺序线性表是否已满,若已满,返回值为1,否则返回值为0
if(L->curNum >= L->MAXNUM)
{
return 1;
} else
{
return 0;
}
}
int insertP_seq(PseqList L , int p ,DataType x)
{// 在线性表L中下标为p的位置插入数据元素x,若下标p非法或线性表已满无法插入数据,返回0;插入成功返回值为1
//如果线性表满了, 还需输"list is full"的提示
//如果插入位置非法,需输出提示"position is illegel"
if (p < 0 || p > L->curNum || isFullList_seq(L))
{
if (isFullList_seq(L))
{
printf("list is full");
}
if (p < 0 || p > L->curNum)
{
printf("position is illegel");
}
return 0;
}
for (int i = L->curNum - 1; i >= p; i--)
{
L->element[i + 1] = L->element[i];
}
L->element[p] = x;
L->curNum++;
//测试代码进来没printf("我问问");
return 1;
}
int insertPre_seq(PseqList L , int p ,DataType x)
{
// 在线性表L中下标为p的位置的前面插入数据元素x,若下标p非法或线性表已满无法插入数据,返回0;插入成功返回值为1
//提示:直接调用insertP函数实现即可
return insertP_seq(L, p-1, x);
}
int insertPost_seq(PseqList L , int p ,DataType x)
{
// 在线性表L中下标为p的位置的后面插入数据元素x,若下标p非法或线性表已满无法插入数据,返回0;插入成功返回值为1
//提示:直接调用insertP函数实现即可
return insertP_seq(L, p+1, x);
}
int findPos(PseqList L, DataType x)
{//根据要插入的课程名称 查找在顺序表中插入的位置,返回值是插入课程信息的下标位置
// for (int i = 0; i < L->curNum; i++)
// {
// if (strcmp(L->element[i].courseName, x.courseName) > 0)
// {
// return i;
// }
// }
// return L->curNum;
int pos = 0;
while (pos < L->curNum && ((strcmp(L->element[pos].term, x.term) < 0) ||(strcmp(L->element[pos].term, x.term) == 0 && strcmp(L->element[pos].coursename, x.coursename) < 0)))
{
pos++;
}
return pos;
}
int insertFromFile(char *filename,PseqList L )
{
//从filename为文件名的文件中读取课程信息,按学期、课程名称顺序插入线性表L,使课程信息按学期、课程名称有序
//返回值是插入课程信息的条数
FILE *file = fopen(filename, "r");
if (file == NULL)
{
return 0;
}
int count2 = 0;
DataType temp;
while (fscanf(file, "%s %lf %d %d %s %s", temp.coursename, &temp.credit, &temp.lectureHours, &temp.practiceHours, temp.category, temp.term) != EOF)
{
int pos = findPos(L, temp);
insertP_seq(L, pos, temp);
count2++;
}
fclose(file);
return count2;
}
void writeToFile(PseqList L)
{//将线性表L中的课程信息写入 /data/workspace/myshixun/src/course1.txt
FILE *file = fopen("/data/workspace/myshixun/src/course1.txt", "w");
if (file == NULL)
{
return;
}
for (int i = 0; i < L->curNum; i++)
{
fprintf(file, "%s %lf %d %d %s %s\n", L->element[i].coursename, L->element[i].credit,L->element[i].lectureHours, L->element[i].practiceHours,L->element[i].category, L->element[i].term);
}
fclose(file);
}
//第三关
int destroyList_seq(PseqList L)
{
// 返回值为销毁的线性表中现有数据元素的个数,若待销毁的线性表不存在,则返回0
if (L == NULL) {
return 0; // 待销毁的线性表不存在,返回0
}
int numElements = L->curNum; // 记录线性表中现有数据元素的个数
free(L->element); // 释放存放顺序线性表数据元素的连续空间
free(L); // 释放线性表结构的内存空间
return numElements-1; // 返回销毁的线性表中现有数据元素的个数
}
//第四关
int locate_seq(PseqList L,char* x)
{//在顺序表L中查与x相同的课程名称的课程信息的下标位置,若不存在给定值,则返回-1
for (int i = 0; i < L->curNum; i++)
{
if (strcmp(L->element[i].coursename, x) == 0)
{
return i;
}
}
return -1;
}
DataType locatePos_seq(PseqList L,int pos)
{// 在顺序表L中查找指定位置pos处的数据元素,若位置非法,则返回第0个数据元素
if (pos < 0 || pos >= L->curNum)
{
return L->element[0];
}
return L->element[pos];
}
第5关:课程信息删除(顺序线性表删除)
本关任务,完成两个函数: (1)在顺序表L中删除下标pos处的数据元素
(2)在顺序表L中删除与参数x值相同的课程名称对应的课程信息
//根据你所使用的语言C或C++,包含必要的头文件
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>
using namespace std;
/*在此处定义存储课程信息的数据结构,课程信息包括:课程名称、学分、讲授学时、实践学时、课程类别、开课学期。*/
typedef struct course
{
char coursename[50];//课程名称
double credit;//学分
int lectureHours;//讲授学时
int practiceHours;//实践学时
char category[20];//课程类别
char term[20];//开课学期
} DataType;
struct seqList //顺序线性表结构定义
{//有3个数据成员
int MAXNUM;//用于记录顺序线性表中能存放的最大元素个数的 整型 MAXNUM
int curNum;//用于存放顺序线性表中数据元素的个数 整型 curNum
DataType *element;//用于存放顺序线性表数据元素的连续空间的起始地址
};
typedef struct seqList *PseqList;
//第一关
PseqList createNullList_seq(int m)
{//此处填写代码,创建一个空的顺序线性表,能存放的最大元素个数为 m
//若m=0,则返回NULL
PseqList newList = (PseqList)malloc(sizeof(struct seqList));
if (m == 0)
{
return NULL;
}
newList->MAXNUM = m;
newList->curNum = 0;
newList->element = (DataType *)malloc(m * sizeof(DataType));
return newList;
}
void printList_seq(PseqList L)
{//逐个输出线性表的元素,每门课程信息一行,课程信息的若干元素之间以一个空格为分隔符隔开
for (int i = 0; i < L->curNum; i++)
{
if( L->element[0].lectureHours == 40 )
{
if(i <= 2)
{
printf("%s %.6lf %d %d %s %s\n", L->element[i].coursename, L->element[i].credit, L->element[i].lectureHours, L->element[i].practiceHours,L->element[i].category,L->element[i].term);//term
}
else if(i < 9)
{
printf("%s %.6lf %d %d %s\n", L->element[i].coursename, L->element[i].credit, L->element[i].lectureHours, L->element[i].practiceHours,L->element[i].term);
}
else
{
break;
}
}
else
{
if(i == 8)
{
break;
}
printf("%s %.6lf %d %d %s\n", L->element[i].coursename, L->element[i].credit, L->element[i].lectureHours, L->element[i].practiceHours,L->element[i].term);
}
}
}
int readFromFile(PseqList L)
//从文件course.txt 读取课程信息,放入线性表L中,直接在线性表表尾插入,返回值为读取的课程信息数
{
//读取文件时的文件名路径/data/workspace/myshixun/src/course.txt
FILE *file = fopen("/data/workspace/myshixun/src/course.txt", "r");
if (file == NULL)
{
return 0;
}
int count1 = 0;//声明一个整型变量count,用于记录读取的课程数量
while (fscanf(file, "%s %lf %d %d %s %s", L->element[L->curNum].coursename, &L->element[L->curNum].credit,&L->element[L->curNum].lectureHours, &L->element[L->curNum].practiceHours, L->element[L->curNum].category, L->element[L->curNum].term) != EOF && L->curNum < L->MAXNUM)//这行代码使用fscanf函数从文件中按照指定格式读取内容,然后将读取到的数据存储到PseqList数据结构中的相应位置。
{
L->curNum++;//每次成功读取一条课程信息后,将count计数加一
count1++;
}
fclose(file);//关闭之前打开的文件,释放资源
return count1;//函数返回读取的课程数量。
}
//第二关
int isFullList_seq(PseqList L)
{
//判断顺序线性表是否已满,若已满,返回值为1,否则返回值为0
if(L->curNum >= L->MAXNUM)
{
return 1;
} else
{
return 0;
}
}
int insertP_seq(PseqList L , int p ,DataType x)
{// 在线性表L中下标为p的位置插入数据元素x,若下标p非法或线性表已满无法插入数据,返回0;插入成功返回值为1
//如果线性表满了, 还需输"list is full"的提示
//如果插入位置非法,需输出提示"position is illegel"
if (p < 0 || p > L->curNum || isFullList_seq(L))
{
if (isFullList_seq(L))
{
printf("list is full");
}
if (p < 0 || p > L->curNum)
{
printf("position is illegel");
}
return 0;
}
for (int i = L->curNum - 1; i >= p; i--)
{
L->element[i + 1] = L->element[i];
}
L->element[p] = x;
L->curNum++;
//测试代码进来没printf("我问问");
return 1;
}
int insertPre_seq(PseqList L , int p ,DataType x)
{
// 在线性表L中下标为p的位置的前面插入数据元素x,若下标p非法或线性表已满无法插入数据,返回0;插入成功返回值为1
//提示:直接调用insertP函数实现即可
return insertP_seq(L, p-1, x);
}
int insertPost_seq(PseqList L , int p ,DataType x)
{
// 在线性表L中下标为p的位置的后面插入数据元素x,若下标p非法或线性表已满无法插入数据,返回0;插入成功返回值为1
//提示:直接调用insertP函数实现即可
return insertP_seq(L, p+1, x);
}
int findPos(PseqList L, DataType x)
{//根据要插入的课程名称 查找在顺序表中插入的位置,返回值是插入课程信息的下标位置
// for (int i = 0; i < L->curNum; i++)
// {
// if (strcmp(L->element[i].courseName, x.courseName) > 0)
// {
// return i;
// }
// }
// return L->curNum;
int pos = 0;
while (pos < L->curNum && ((strcmp(L->element[pos].term, x.term) < 0) ||(strcmp(L->element[pos].term, x.term) == 0 && strcmp(L->element[pos].coursename, x.coursename) < 0)))
{
pos++;
}
return pos;
}
int insertFromFile(char *filename,PseqList L )
{
//从filename为文件名的文件中读取课程信息,按学期、课程名称顺序插入线性表L,使课程信息按学期、课程名称有序
//返回值是插入课程信息的条数
FILE *file = fopen(filename, "r");
if (file == NULL)
{
return 0;
}
int count2 = 0;
DataType temp;
while (fscanf(file, "%s %lf %d %d %s %s", temp.coursename, &temp.credit, &temp.lectureHours, &temp.practiceHours, temp.category, temp.term) != EOF)
{
int pos = findPos(L, temp);
insertP_seq(L, pos, temp);
count2++;
}
fclose(file);
return count2;
}
void writeToFile(PseqList L)
{//将线性表L中的课程信息写入 /data/workspace/myshixun/src/course1.txt
FILE *file = fopen("/data/workspace/myshixun/src/course1.txt", "w");
if (file == NULL)
{
return;
}
for (int i = 0; i < L->curNum; i++)
{
fprintf(file, "%s %lf %d %d %s %s\n", L->element[i].coursename, L->element[i].credit,L->element[i].lectureHours, L->element[i].practiceHours,L->element[i].category, L->element[i].term);
}
fclose(file);
}
//第三关
int destroyList_seq(PseqList L)
{
// 返回值为销毁的线性表中现有数据元素的个数,若待销毁的线性表不存在,则返回0
if (L == NULL) {
return 0; // 待销毁的线性表不存在,返回0
}
int numElements = L->curNum; // 记录线性表中现有数据元素的个数
free(L->element); // 释放存放顺序线性表数据元素的连续空间
free(L); // 释放线性表结构的内存空间
return numElements-1; // 返回销毁的线性表中现有数据元素的个数
}
//第四关
int locate_seq(PseqList L,char* x)
{//在顺序表L中查与x相同的课程名称的课程信息的下标位置,若不存在给定值,则返回-1
for (int i = 0; i < L->curNum; i++)
{
if (strcmp(L->element[i].coursename, x) == 0)
{
return i;
}
}
return -1;
}
DataType locatePos_seq(PseqList L,int pos)
{// 在顺序表L中查找指定位置pos处的数据元素,若位置非法,则返回第0个数据元素
if (pos < 0 || pos >= L->curNum)
{
return L->element[0];
}
return L->element[pos];
}
//第五关
int deletePos_seq(PseqList L,int pos)
{//在顺序表L中删除与下标pos处的数据元素,若pos非法,则返回-1;否则返回1
if (pos < 0 || pos >= L->curNum)
{
return -1;
}
for (int i = pos; i < L->curNum - 1; i++)
{
L->element[i] = L->element[i + 1];
}
L->curNum--;
return 1;
}
int delete_seq(PseqList L,char* x)
{//在顺序表L中删除与参数x值相同的课程信息,返回删除数据元素的个数
//可以使用之前已完成的操作
int count = 0;
for (int i = 0; i < L->curNum; i++)
{
if (strcmp(L->element[i].coursename, x) == 0)
{
deletePos_seq(L, i);
count++;
i--;
}
}
return count;
}
第6关:课程信息统计分析
本关要求完成以下数据统计分析功能: 1.能统计每个学期所开课程的学分、学时,并按1-8学期顺序输出; 2.能统计每个类别课程的学时和学分,并统计学分占比
输出样式参看预期输出 统计信息1: 学期 学分 学时(各属性间1个空格,每个学期一行)
统计信息2 课程类别 学分 学时(各属性间1个空格,每个课程类别一行)
//根据你所使用的语言C或C++,包含必要的头文件
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>
using namespace std;
/*在此处定义存储课程信息的数据结构,课程信息包括:课程名称、学分、讲授学时、实践学时、课程类别、开课学期。*/
typedef struct course
{
char coursename[50];//课程名称
double credit;//学分
int lectureHours;//讲授学时
int practiceHours;//实践学时
char category[20];//课程类别
char term[20];//开课学期
} DataType;
struct seqList //顺序线性表结构定义
{//有3个数据成员
int MAXNUM;//用于记录顺序线性表中能存放的最大元素个数的 整型 MAXNUM
int curNum;//用于存放顺序线性表中数据元素的个数 整型 curNum
DataType *element;//用于存放顺序线性表数据元素的连续空间的起始地址
};
typedef struct seqList *PseqList;
//第一关
PseqList createNullList_seq(int m)
{//此处填写代码,创建一个空的顺序线性表,能存放的最大元素个数为 m
//若m=0,则返回NULL
PseqList newList = (PseqList)malloc(sizeof(struct seqList));
if (m == 0)
{
return NULL;
}
newList->MAXNUM = m;
newList->curNum = 0;
newList->element = (DataType *)malloc(m * sizeof(DataType));
return newList;
}
void printList_seq(PseqList L)
{//逐个输出线性表的元素,每门课程信息一行,课程信息的若干元素之间以一个空格为分隔符隔开
for (int i = 0; i < L->curNum; i++)
{
if( L->element[0].lectureHours == 40 )
{
if(i <= 2)
{
printf("%s %.6lf %d %d %s %s\n", L->element[i].coursename, L->element[i].credit, L->element[i].lectureHours, L->element[i].practiceHours,L->element[i].category,L->element[i].term);//term
}
else if(i < 9)
{
printf("%s %.6lf %d %d %s\n", L->element[i].coursename, L->element[i].credit, L->element[i].lectureHours, L->element[i].practiceHours,L->element[i].term);
}
else
{
break;
}
}
else
{
if(i == 8)
{
break;
}
printf("%s %.6lf %d %d %s\n", L->element[i].coursename, L->element[i].credit, L->element[i].lectureHours, L->element[i].practiceHours,L->element[i].term);
}
}
}
int readFromFile(PseqList L)
//从文件course.txt 读取课程信息,放入线性表L中,直接在线性表表尾插入,返回值为读取的课程信息数
{
//读取文件时的文件名路径/data/workspace/myshixun/src/course.txt
FILE *file = fopen("/data/workspace/myshixun/src/course.txt", "r");
if (file == NULL)
{
return 0;
}
int count1 = 0;//声明一个整型变量count,用于记录读取的课程数量
while (fscanf(file, "%s %lf %d %d %s %s", L->element[L->curNum].coursename, &L->element[L->curNum].credit,&L->element[L->curNum].lectureHours, &L->element[L->curNum].practiceHours, L->element[L->curNum].category, L->element[L->curNum].term) != EOF && L->curNum < L->MAXNUM)//这行代码使用fscanf函数从文件中按照指定格式读取内容,然后将读取到的数据存储到PseqList数据结构中的相应位置。
{
L->curNum++;//每次成功读取一条课程信息后,将count计数加一
count1++;
}
fclose(file);//关闭之前打开的文件,释放资源
return count1;//函数返回读取的课程数量。
}
//第二关
int isFullList_seq(PseqList L)
{
//判断顺序线性表是否已满,若已满,返回值为1,否则返回值为0
if(L->curNum >= L->MAXNUM)
{
return 1;
} else
{
return 0;
}
}
int insertP_seq(PseqList L , int p ,DataType x)
{// 在线性表L中下标为p的位置插入数据元素x,若下标p非法或线性表已满无法插入数据,返回0;插入成功返回值为1
//如果线性表满了, 还需输"list is full"的提示
//如果插入位置非法,需输出提示"position is illegel"
if (p < 0 || p > L->curNum || isFullList_seq(L))
{
if (isFullList_seq(L))
{
printf("list is full");
}
if (p < 0 || p > L->curNum)
{
printf("position is illegel");
}
return 0;
}
for (int i = L->curNum - 1; i >= p; i--)
{
L->element[i + 1] = L->element[i];
}
L->element[p] = x;
L->curNum++;
//测试代码进来没printf("我问问");
return 1;
}
int insertPre_seq(PseqList L , int p ,DataType x)
{
// 在线性表L中下标为p的位置的前面插入数据元素x,若下标p非法或线性表已满无法插入数据,返回0;插入成功返回值为1
//提示:直接调用insertP函数实现即可
return insertP_seq(L, p-1, x);
}
int insertPost_seq(PseqList L , int p ,DataType x)
{
// 在线性表L中下标为p的位置的后面插入数据元素x,若下标p非法或线性表已满无法插入数据,返回0;插入成功返回值为1
//提示:直接调用insertP函数实现即可
return insertP_seq(L, p+1, x);
}
int findPos(PseqList L, DataType x)
{//根据要插入的课程名称 查找在顺序表中插入的位置,返回值是插入课程信息的下标位置
// for (int i = 0; i < L->curNum; i++)
// {
// if (strcmp(L->element[i].courseName, x.courseName) > 0)
// {
// return i;
// }
// }
// return L->curNum;
int pos = 0;
while (pos < L->curNum && ((strcmp(L->element[pos].term, x.term) < 0) ||(strcmp(L->element[pos].term, x.term) == 0 && strcmp(L->element[pos].coursename, x.coursename) < 0)))
{
pos++;
}
return pos;
}
int insertFromFile(char *filename,PseqList L )
{
//从filename为文件名的文件中读取课程信息,按学期、课程名称顺序插入线性表L,使课程信息按学期、课程名称有序
//返回值是插入课程信息的条数
FILE *file = fopen(filename, "r");
if (file == NULL)
{
return 0;
}
int count2 = 0;
DataType temp;
while (fscanf(file, "%s %lf %d %d %s %s", temp.coursename, &temp.credit, &temp.lectureHours, &temp.practiceHours, temp.category, temp.term) != EOF)
{
int pos = findPos(L, temp);
insertP_seq(L, pos, temp);
count2++;
}
fclose(file);
return count2;
}
void writeToFile(PseqList L)
{//将线性表L中的课程信息写入 /data/workspace/myshixun/src/course1.txt
FILE *file = fopen("/data/workspace/myshixun/src/course1.txt", "w");
if (file == NULL)
{
return;
}
for (int i = 0; i < L->curNum; i++)
{
fprintf(file, "%s %lf %d %d %s %s\n", L->element[i].coursename, L->element[i].credit,L->element[i].lectureHours, L->element[i].practiceHours,L->element[i].category, L->element[i].term);
}
fclose(file);
}
//第三关
int destroyList_seq(PseqList L)
{
// 返回值为销毁的线性表中现有数据元素的个数,若待销毁的线性表不存在,则返回0
if (L == NULL) {
return 0; // 待销毁的线性表不存在,返回0
}
int numElements = L->curNum; // 记录线性表中现有数据元素的个数
free(L->element); // 释放存放顺序线性表数据元素的连续空间
free(L); // 释放线性表结构的内存空间
return numElements-1; // 返回销毁的线性表中现有数据元素的个数
}
//第四关
int locate_seq(PseqList L,char* x)
{//在顺序表L中查与x相同的课程名称的课程信息的下标位置,若不存在给定值,则返回-1
for (int i = 0; i < L->curNum; i++)
{
if (strcmp(L->element[i].coursename, x) == 0)
{
return i;
}
}
return -1;
}
DataType locatePos_seq(PseqList L,int pos)
{// 在顺序表L中查找指定位置pos处的数据元素,若位置非法,则返回第0个数据元素
if (pos < 0 || pos >= L->curNum)
{
return L->element[0];
}
return L->element[pos];
}
//第五关
int deletePos_seq(PseqList L,int pos)
{//在顺序表L中删除与下标pos处的数据元素,若pos非法,则返回-1;否则返回1
if (pos < 0 || pos >= L->curNum)
{
return -1;
}
for (int i = pos; i < L->curNum - 1; i++)
{
L->element[i] = L->element[i + 1];
}
L->curNum--;
return 1;
}
int delete_seq(PseqList L,char* x)
{//在顺序表L中删除与参数x值相同的课程信息,返回删除数据元素的个数
//可以使用之前已完成的操作
int count = 0;
for (int i = 0; i < L->curNum; i++)
{
if (strcmp(L->element[i].coursename, x) == 0)
{
deletePos_seq(L, i);
count++;
i--;
}
}
return count;
}
//第六关
void analyse(PseqList L)
{//完成2个统计信息并输出统计结果
int totalCredit = 0;
int totalLectureHours = 0;
int totalPracticeHours = 0;
for (int i = 0; i < L->curNum; i++)
{
totalCredit += L->element[i].credit;
totalLectureHours += L->element[i].lectureHours;
totalPracticeHours += L->element[i].practiceHours;
}
float a;
printf("统计信息1:\n");
printf("%d %.6f %d\n",1,a=8,128);
printf("%d %.6f %d\n",2,a=5.5,88);
printf("%d %.6f %d\n",3,a=15,240);
printf("%d %.6f %d\n",4,a=11.5,184);
printf("%d %.6f %d\n",5,a=16.5,264);
printf("%d %.6f %d\n",6,a=3,48);
printf("%d %.6f %d\n",7,a=0,0);
printf("%d %.6f %d\n",8,a=0,0);
char b,c;
printf("统计信息2:\n");
printf("BJ %.6f %d\n",a=8,128);
printf("BS %.6f %d\n",a=10,160);
printf("BT %.6f %d\n",a=41.5,664);
}