概述
一元多项式计算器
实验二:哈夫曼编码
实验三:图及其应用
github地址
代码仅供参考
一元多项式计算器
注意:c报错的,删掉typedef enum Bool {false, true} bool;换成c++运行。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#define MAX_SIZE 100
#define max(x, y) x > y ? x : y
typedef enum Bool {false, true} bool;
typedef struct {
int coef; //系数
int expn; //幂次
} ElemType;
// 线性表
typedef struct vector{
int size; // 开辟的空间大小
int length; // 有效数据长度
int *data;
}Vector;
// 单链表
typedef struct node {
ElemType data;
struct node *next;
}Node, *Link;
int pows[MAX_SIZE * 2 + 10];
void inputMessage() {
printf("因变量为x,不需要输入。输入多项式请按要求每一行输入两个数字,");
printf("分别代表x的系数与幂次,幂次由高到低。n两数请用空格隔开,以文件结束符终止输入n");
}
// 创建一个空的线性表
Vector getEmptyArray() {
Vector arr;
arr.size = MAX_SIZE * 2 + 10;
arr.data = (int*)malloc(sizeof(int) * arr.size);
for (int i = 0; i < arr.size; ++ i) arr.data[i] = 0;
arr.length = 0;
return arr;
}
// 线性表,输入多项式
Vector inputPolynomialArray() {
int coef, expn;
Vector arr = getEmptyArray();
while(~scanf("%d%d", &coef, &expn)) {
arr.length = max(arr.length, expn);
arr.data[expn] = coef;
}
++ arr.length;
return arr;
}
// 多项式相乘
Vector mulPolynomial(Vector A, Vector B) {
Vector arr = getEmptyArray();
int coef, expn;
for (int i = 0; i < A.length; ++ i) {
for (int j = 0; j < B.length; ++ j) {
coef = A.data[i] * B.data[j];
expn = i * j;
arr.data[expn] += coef;
arr.length = max(arr.length, expn);
}
}
++ arr.length;
return arr;
}
// 线性表,输出多项式
void printPolynomialArray(Vector arr) {
bool f = true;
printf("升幂:");
for (int i = 0; i < arr.length; ++ i) {
if(arr.data[i] == 0) continue;
if(!f) printf(" %c ", arr.data[i] > 0 ? '+' : '-');
else if(arr.data[i] < 0) printf("-");
f = false;
printf("%dx^%d", abs(arr.data[i]), i);
}
printf("n降幂:");
f = true;
for (int i = arr.length - 1; i >= 0; -- i) {
if(arr.data[i] == 0) continue;
if(!f) printf(" %c ", arr.data[i] > 0 ? '+' : '-');
f = false;
printf("%dx^%d", abs(arr.data[i]), i);
}
puts("");
}
//单链表尾插法函数,减少代码量
Link rearInsert(Link p, int coef, int expn) {
Link tmp = tmp = (Link)malloc(sizeof(Node));
tmp->next = NULL;
tmp->data.coef = coef;
tmp->data.expn = expn;
p->next = tmp;
p = tmp;
return p;
}
//单链表,输入一个多项式
Link inputPolynomialList() {
Link head = (Link)malloc(sizeof(Node));
head->next = NULL;
int coef, expn;
Link tmp, p;
p = head;
while(~scanf("%d%d", &coef, &expn))
p = rearInsert(p, coef, expn);
return head;
}
//单链表,输出多项式
void printPolynomialList(Link head) {
Vector arr = getEmptyArray();
Link p = head;
while(p->next != NULL) {
int coef = p->next->data.coef;
int expn = p->next->data.expn;
arr.data[expn] += coef;
arr.length = max(arr.length, expn);
p = p->next;
}
++ arr.length;
printPolynomialArray(arr);
}
//多项式相加减
Link addOrSubPolynomial(Link A, Link B, bool add) {
Link head = (Link)malloc(sizeof(Node));
Link p, tmp;
int coefA, coefB, coef;
int expnA, expnB, expn;
p = head;
// 链表加减,先计算出幂次高的值
while(A->next && B->next) {
coefA = A->next->data.coef;
coefB = B->next->data.coef;
expnA = A->next->data.expn;
expnB = B->next->data.expn;
if(expnA == expnB) {
if(add) coef = coefA + coefB;
else coef = coefA - coefB;
expn = expnA;
A = A->next;
B = B->next;
if(coef == 0) continue;
} else if(expnA > expnB) {
coef = coefA;
expn = expnA;
A = A->next;
} else {
if(add) coef = coefB;
else coef = -coefB;
expn = expnB;
B = B->next;
}
p = rearInsert(p, coef, expn);
}
while(A->next) {
p = rearInsert(p, A->next->data.coef, A->next->data.expn);
A = A->next;
}
while(B->next) {
if(add) p = rearInsert(p, B->next->data.coef, B->next->data.expn);
else p = rearInsert(p, -B->next->data.coef, B->next->data.expn);
B = B->next;
}
return head;
}
int main() {
printf("1:多项式+,-n");
printf("2:多项式*n");
printf("0:退出n");
int choose;
while(~scanf("%d", &choose)) {
if(choose == 0) break;
inputMessage();
if(choose == 1) {
printf("请输入多项式A:n");
Link A = inputPolynomialList();
printf("请输入多项式B:n");
Link B = inputPolynomialList();
int op;
printf("0:-n1:+n");
scanf("%d", &op);
Link C = addOrSubPolynomial(A, B, op);
printPolynomialList(C);
} else {
printf("请输入多项式A:n");
Vector A = inputPolynomialArray();
printf("请输入多项式B:n");
Vector B = inputPolynomialArray();
Vector C = mulPolynomial(A, B);
printPolynomialArray(C);
}
puts("---------");
printf("1:多项式+,-n");
printf("2:多项式*n");
printf("0:退出n");
}
return 0;
}
实验二:哈夫曼编码
注意:C++运行代码
补充
之前写的没仔细看实验要求,本来想着也没多难,然后就直接写了。哪知道他还要求中文字符。(;´д`)ゞ。这一天天的,教的东西没啥,要求蛮多。
除此之外,一些细节也已更改。就是输出文件路径那些,之前漏掉了。
为减少篇幅,最新的代码放这里:
https://paste.ubuntu.com/p/cMDX6fWQsn/
然后说下支持中文字符的改动
加上头文件#include <map>
,work函数中原有的int* mp
改成map<char, int> mp
。然后更改原有函数void getLeafsArray
。
void getLeafsArray(List &leafs, map<char, int> &mp, char* s) {
map<char, int> nums; // 保存每个字符出现的次数
for (int i = 0; i < strlen(s); ++ i)
++ nums[s[i]];
leafs.len = nums.size() + 1; // 0不用故+1
leafs.codes = (char*) malloc(sizeof(char) * leafs.len);
leafs.weights = (int*) malloc(sizeof(int) * leafs.len);
int len = 0;
for (map<char, int>::iterator it = nums.begin(); it != nums.end(); it ++) {
leafs.codes[++ len] = it->first;
leafs.weights[len] = it->second;
mp[it->first] = len; // 字符映射,方便查找
}
}
然后就是编码部分。直接新建记事本用的应该是utf8的编码,然而咱们的控制台大部分都是gbk编码的。
所以如果你的控制台上出现乱码。像这样。
不要慌。记事本里的还是完好的。
若是想消除控制台上的乱码,可以用记事本新建,保存的时候将编码保存成ANSI。
ANSI编码会根据电脑系统的不同为你选择合适的编码。简体中文环境下就是gbk。详见百度百科
输入和输出
- 输入:硬盘上原始文件的文件路径
- 输出:
- 生成一个加密文件,并在控制台输出其路径。
- 生成一个解码文件,并在控制台输出其路径。
- 在控制台输出原始文件与解码文件的对比结果。
编写环境
C/C++
实验分析
分析个锤子,就两部分。会就是会,不会就百度。
- 文件操作
- 哈夫曼编码
文件操作咱们就用C语言吧,起码还会一点点,C++就要从零开始了
文件操作
编写两个函数,一个用来读取文本内容,一个写入文本内容。
- 文本路径Path,及字符串。typedef char* Path。
- 读取文本内容,char* readAllTxt(Path txtPath)
- 写入文本内容,void writeTxt(char* str, Path txtPath)。
code
char* readAllTxt(Path txtPath) {
FILE* fp = fopen(txtPath, "rb"); // rb打开用于读取的二进制文件,不要写r。不然会错
fseek(fp, 0, SEEK_END); // 将fp的输入流移动到文本末端
int flen = ftell(fp); // 计算文本长度
char* str = (char*)malloc(sizeof(char) * (flen + 1)); // 创建一个长度为flen+1的字符数组。结束符'