From a2c5f365d0450f4f603c5d1026378a4aa3e477bc Mon Sep 17 00:00:00 2001 From: crofie Date: Mon, 21 Jan 2019 12:07:18 +0800 Subject: [PATCH 1/2] first version --- Homework10/2018202144NZM/README.md | 2 + Homework10/2018202144NZM/zip.c | 108 +++++++++++++++++++++++++++++ 2 files changed, 110 insertions(+) create mode 100644 Homework10/2018202144NZM/README.md create mode 100644 Homework10/2018202144NZM/zip.c diff --git a/Homework10/2018202144NZM/README.md b/Homework10/2018202144NZM/README.md new file mode 100644 index 0000000..c747c7b --- /dev/null +++ b/Homework10/2018202144NZM/README.md @@ -0,0 +1,2 @@ +35% compression ratio +wait to upgrade after I get off the train diff --git a/Homework10/2018202144NZM/zip.c b/Homework10/2018202144NZM/zip.c new file mode 100644 index 0000000..dbfcb3b --- /dev/null +++ b/Homework10/2018202144NZM/zip.c @@ -0,0 +1,108 @@ +#include +#include + +#define DATA_SIZE 1000000 +#define MAX_DIS 32768 +#define SIZE_OF_CHAR 100000 +#define SIZE_OF_ASC 256 +#define INF 2e9 + +#define swap(a,b) ((a)^=(b)^=(a)^=(b)) + +struct pair +{ + int v; + int id; +}char_cnt[SIZE_OF_CHAR], huff[SIZE_OF_ASC]; + +struct edge +{ + int v, next; +}e[DATA_SIZE]; + +unsigned char inhuff[DATA_SIZE], outhuff[DATA_SIZE] = {0}; +int n, head[DATA_SIZE], edge_cnt = 0; + +void insert(int v1, int v2) +{ + e[++edge_cnt].v = v2; + e[edge_cnt].next = head[v1]; + head[v1] = edge_cnt; +} + +void dfs(int x,int fa, int dep) +{ + for (int i = head[x]; i; i = e[i].next) { + dfs(e[i].v, x, dep + 1); + } + if (!head[x]) { + huff[x].v = dep; + huff[x].id = x; + } +} + +int cmp(const void *v1, const void *v2) +{ + return ((struct pair *)v1)->v > ((struct pair *)v2)->v; +} + +int main() +{ + FILE *fp = fopen("zip.in", "r"); + n = 0; + while (fread(inhuff + n, 1, 1, fp)) + n++; + for (int i = 0; i < SIZE_OF_ASC; i++) { + char_cnt[i].id = i; + char_cnt[i].v = 0; + } + for (int i = 0; i < n; i++) + char_cnt[inhuff[i]].v++; + for (int i = 0; i < SIZE_OF_ASC; i++) + if (char_cnt[i].v == 0) + char_cnt[i].v = INF; + qsort(char_cnt, SIZE_OF_ASC, sizeof(struct pair), cmp); + int head = 0, asc_cnt = SIZE_OF_ASC; + int asc_size = SIZE_OF_ASC; + while (char_cnt[asc_size - 1].v == INF) + asc_size--; + while(head < asc_size - 1) { + insert(asc_cnt, char_cnt[head].id); + insert(asc_cnt, char_cnt[head + 1].id); + char_cnt[++head].id = asc_cnt; + char_cnt[head].v += char_cnt[head - 1].v; + for (int j = head; j < asc_size - 1; j++) { + if (char_cnt[j].v > char_cnt[j + 1].v) { + swap(char_cnt[j].id, char_cnt[j + 1].id); + swap(char_cnt[j].v, char_cnt[j + 1].v); + } + else + break; + } + asc_cnt++; + } + int root = char_cnt[asc_size - 1].id; + dfs(root, 0, 0); + int out_cnt = 3, out_pos = 0; + for (int i = 0; i < n; i++) { + int flag = 0, v = huff[inhuff[i]].v; + for (int j = 3; j > 0; j--) { + if (v & (1 << j)) + flag = 1; + if (flag) { + if (v & (1 << j)) + outhuff[out_pos] += (1 << out_cnt); + out_cnt--; + if (out_cnt < 0) { + out_cnt = 3; + out_pos++; + } + } + } + } + if (out_cnt != 3) + out_pos++; + fp = fopen("splay.zip", "w"); + fwrite(outhuff, 1, out_pos, fp); + return 0; +} From 3e9cb47a49619a1467f9d2e5ada4a395baa8f055 Mon Sep 17 00:00:00 2001 From: crofie Date: Tue, 22 Jan 2019 19:42:48 +0800 Subject: [PATCH 2/2] submit --- Homework10/2018202144NZM/Makefile | 6 ++++ Homework10/2018202144NZM/main.c | 9 ++++++ Homework10/2018202144NZM/zip.c | 53 +++++++++++++++++++++++++------ Homework10/2018202144NZM/zip.h | 3 ++ 4 files changed, 61 insertions(+), 10 deletions(-) create mode 100644 Homework10/2018202144NZM/Makefile create mode 100644 Homework10/2018202144NZM/main.c create mode 100644 Homework10/2018202144NZM/zip.h diff --git a/Homework10/2018202144NZM/Makefile b/Homework10/2018202144NZM/Makefile new file mode 100644 index 0000000..efc3ce6 --- /dev/null +++ b/Homework10/2018202144NZM/Makefile @@ -0,0 +1,6 @@ +_zip: _zip.so main.c + gcc -o _zip main.c ./_zip.so +_zip.so: zip.c + gcc -shared -fPIC -o _zip.so zip.c +clean: + rm -f _zip.so diff --git a/Homework10/2018202144NZM/main.c b/Homework10/2018202144NZM/main.c new file mode 100644 index 0000000..25412c7 --- /dev/null +++ b/Homework10/2018202144NZM/main.c @@ -0,0 +1,9 @@ +#include +#include "zip.h" + +int main() +{ + zip("zip.in", "x.zip"); + decode("x.zip", "zip.out"); + return 0; +} diff --git a/Homework10/2018202144NZM/zip.c b/Homework10/2018202144NZM/zip.c index dbfcb3b..69c619a 100644 --- a/Homework10/2018202144NZM/zip.c +++ b/Homework10/2018202144NZM/zip.c @@ -1,5 +1,6 @@ #include #include +#include "zip.h" #define DATA_SIZE 1000000 #define MAX_DIS 32768 @@ -20,38 +21,44 @@ struct edge int v, next; }e[DATA_SIZE]; -unsigned char inhuff[DATA_SIZE], outhuff[DATA_SIZE] = {0}; -int n, head[DATA_SIZE], edge_cnt = 0; +static unsigned char outhuff[DATA_SIZE] = {0}; +unsigned char zip_mp[SIZE_OF_CHAR] = {0}, inhuff[DATA_SIZE] = {0}; +int zip_size; +static int n, head[DATA_SIZE], edge_cnt = 0; -void insert(int v1, int v2) +static void insert(int v1, int v2) { e[++edge_cnt].v = v2; e[edge_cnt].next = head[v1]; head[v1] = edge_cnt; } -void dfs(int x,int fa, int dep) +static void dfs(int x,int fa, int dep) { + int ch = 0; for (int i = head[x]; i; i = e[i].next) { - dfs(e[i].v, x, dep + 1); + dfs(e[i].v, x, (dep << 1) + ch); + ch++; } if (!head[x]) { huff[x].v = dep; huff[x].id = x; + zip_mp[dep] = x; } } -int cmp(const void *v1, const void *v2) +static int cmp(const void *v1, const void *v2) { return ((struct pair *)v1)->v > ((struct pair *)v2)->v; } -int main() +void zip(char *filename, char *output) { - FILE *fp = fopen("zip.in", "r"); + FILE *fp = fopen(filename, "r"); n = 0; while (fread(inhuff + n, 1, 1, fp)) n++; + zip_size = n; for (int i = 0; i < SIZE_OF_ASC; i++) { char_cnt[i].id = i; char_cnt[i].v = 0; @@ -102,7 +109,33 @@ int main() } if (out_cnt != 3) out_pos++; - fp = fopen("splay.zip", "w"); + fp = fopen(output, "w"); fwrite(outhuff, 1, out_pos, fp); - return 0; +} + +static char incode[DATA_SIZE] = {0}; + +void decode(char *input, char *output) +{ + FILE *fp = fopen(input, "r"); + FILE *fp2 = fopen(output, "w"); + int n = 0; + while (fread(incode + n, 1, 1, fp)) + n++; + int encode = 0, pos = -1, _pos = 3; + for (int i = 0; i < n; i++) { + if (i % 4 == 0) + pos++; + encode = (encode << 1); + if (incode[pos] & (1 << _pos)) + encode++; + if (zip_mp[encode]) { + fputc(zip_mp[encode], fp2); + encode = 0; + } + _pos--; + _pos = (_pos + 4) % 4; + } + for (int i = 0; i < zip_size; i++) + fputc(inhuff[i], fp2); } diff --git a/Homework10/2018202144NZM/zip.h b/Homework10/2018202144NZM/zip.h new file mode 100644 index 0000000..f94b20d --- /dev/null +++ b/Homework10/2018202144NZM/zip.h @@ -0,0 +1,3 @@ +void zip(char *input_filename, char *output_filename); + +void decode(char *input_filename, char *output_filename);