前言:
- 程序运行环境: DevC++
- 文件组成说明:头文件main.h:包含结构体定义,函数声明、源文件Huffman.cpp:总代码,数据文件Optional-course.txt选修课课程信息,Require-course.txt必修课课程信息、说明文件readme.txt,图片文件等。
一、基于哈夫曼编码的文件压缩解压
要实现的功能包括:构建哈夫曼树,生成字符的哈夫曼编码,压缩文件,解压文件。压缩文件功能为:系统读取输入文件,通过哈夫曼编码将其压缩,并输出压缩后的文件。解压文件功能为:系统读取已压缩的文件,使用对应字符的哈夫曼译码将其解压为原始文件,并输出解压后的文件。
//定义哈夫曼树数据结构
struct HuffmanNode
{
unsigned char data; //定义一个字符
long frequency; //字符出现频率
long parent,leftch,rightch; //创建哈夫曼树
char bits[256]; //哈夫曼结点
}header[512],tmp;
//读取ifp文件内容
while(!feof(ifp))
{
fread(&c,1,1,ifp); //按位读取文件
header[c].frequency++; //记录文件的字符总数
flength++;
}
flength = -1;
header[c].frequency = -1; //读取文件结束
//构造哈弗曼树,初始结点的设置
for(i=0;i<512;i++)
{
if(header[i].frequency != 0)
header[i].data = (unsigned char)i;
else
header[i].data = 0;
header[i].parent = -1;
header[i].leftch = header[i].rightch = -1;
}
//按结点出现的次数排序
for(i=0;i<256;i++)
{
for(j=i+1;j<256;j++)
{
if(header[i].frequency < header[j].frequency)
{
tmp=header[i];
header[i] = header[j];
header[j] = tmp;
}
}
}
//统计不同字符的数量
for(i=0;i<256;i++)
if(header[i].frequency==0)
break;
n=i;
m=2*n-1;
for(i=n;i<m;i++)
{
min1=999999999;
for(j=0;j<i;j++)
{
if(header[j].parent!=-1)
continue;
if(min1>header[j].frequency)
{
pt1=j;
min1=header[j].frequency;
continue;
}
}
header[i].frequency=header[pt1].frequency;
header[pt1].parent=i;
header[i].leftch=pt1;
min1=999999999;
for(j=0;j<i;j++)
{
if(header[j].parent!=-1)
continue;
if(min1>header[j].frequency)
{
pt1=j;
min1=header[j].frequency;
continue;
}
}
header[i].frequency+=header[pt1].frequency;
header[i].rightch=pt1;
header[pt1].parent=i;
}
//构造哈夫曼树,设置字符编码
for(i=0;i<n;i++)
{
f = i;
header[i].bits[0] = 0;
while(header[f].parent != -1)
{
j = f;
f = header[f].parent;
if(header[f].leftch==j)
{
j = strlen(header[i].bits);
memmove(header[i].bits+1,header[i].bits,j+1);
header[i].bits[0]='0';
}
else
{
j=strlen(header[i].bits);
memmove(header[i].bits+1,header[i].bits,j+1);
header[i].bits[0]='1';
}
}
}
二、拓扑排序实现学生选课排课
功能包括:课程信息管理、选课管理、输出已选课程列表、课程排课顺序。要实现的功能包括:从指定文件读取课程信息(包括课程名称、课程编号、课程学分以及所需选修课程等信息)、将课程信息用带入度域的邻接表存储下来;从键盘读取拟添加的选修课信息、删除已选的选修课、输出已选修课程列表、统计选修课总学分、将已选课程列表输出到屏幕上、统计不同类型课程的学分数值;使用拓扑排序算法对已选课程进行排序,生成课程的排课顺序并输出。
// 定义课程结构体
typedef struct Course {
char code[MAX_NAME];
char name[MAX_NAME];
float credit;
int numPrerequisites;
struct Course* prerequisites[MAX_COURSES];
} Course;
// 读取课程信息
void readCourseInfo(char* filename, Course* courses, int* numCourses)
{
FILE* file = fopen(filename, "r");
if (file == NULL) {
printf("无法打开文件 %s\n", filename);
exit(1);
}
char line[100];
while (fgets(line, sizeof(line), file)) {
sscanf(line, "%s %s %f", courses[*numCourses].code, courses[*numCourses].name, &courses[*numCourses].credit);
// 解析先修课程
char prerequisites[100];
sscanf(line, "%*s %*s %*f %[^\n]", prerequisites);
char* prereq = strtok(prerequisites, " ,");
while (prereq != NULL) {
for (int i = 0; i < *numCourses; i++) {
if (strcmp(prereq, courses[i].code) == 0) {
courses[*numCourses].prerequisites[courses[*numCourses].numPrerequisites] = &courses[i];
courses[*numCourses].numPrerequisites++;
}
}
prereq = strtok(NULL, " ,");
}
// 添加对选修课学分的判断
if (courses[*numCourses].credit >= 20) {
electiveCourses[numElectiveCourses++] = courses[*numCourses];
}
(*numCourses)++;
}
fclose(file);
}
三、最终效果
写在最后:
欢迎大家一起交流讨论,需要源码可以私我或者给我留评论!