diff --git a/CLion/ExerciseBook/05.17/05.17.c b/CLion/ExerciseBook/05.17/05.17.c new file mode 100644 index 0000000..88f75ca --- /dev/null +++ b/CLion/ExerciseBook/05.17/05.17.c @@ -0,0 +1,137 @@ +#include +#include // 提供 system、rand、srand 原型 +#include // 提供 time 原型 +#include "SqList.h" //**▲02 线性表**// + +// 递归求最大值 +int Algo_5_17_1(SqList L, int len); + +// 递归求最小值 +int Algo_5_17_2(SqList L, int len); + +// 递归求和 +int Algo_5_17_3(SqList L, int len); + +// 递归求积 +double Algo_5_17_4(SqList L, int len); + +// 递归求平均数 +double Algo_5_17_5(SqList L, int len); + + +int main(int argc, char* argv[]) { + SqList L; + int i; + + InitList(&L); + + srand((unsigned) time(NULL)); // 用系统时间做随机数种子 + + for(i = 1; i <= 10; i++) { + ListInsert(&L, i, rand() % 100); + } + + printf("顺序表中的数字序列为:"); + for(i = 0; i < L.length; i++) { + printf("%d ", L.elem[i]); + } + printf("\n"); + + printf("顺序表中的最大值为: %d \n", Algo_5_17_1(L, L.length)); + printf("顺序表中的最小值为: %d \n", Algo_5_17_2(L, L.length)); + printf("顺序表中的和为: %d \n", Algo_5_17_3(L, L.length)); + printf("顺序表中的积为: %.2f \n", Algo_5_17_4(L, L.length)); + printf("顺序表中的平均值为: %.2f \n", Algo_5_17_5(L, L.length)); + + return 0; +} + + +// 递归求最大值 +int Algo_5_17_1(SqList L, int len) { + int value, max; + + // 获取当前位置的值 + GetElem(L, len, &value); + + if(len == 1) { + return value; + } + + // 获取先前序列的最大值 + max = Algo_5_17_1(L, --len); + + return max > value ? max : value; +} + +// 递归求最小值 +int Algo_5_17_2(SqList L, int len) { + int value, min; + + // 获取当前位置的值 + GetElem(L, len, &value); + + if(len == 1) { + return value; + } + + // 获取先前序列的最小值 + min = Algo_5_17_2(L, --len); + + return min < value ? min : value; +} + +// 递归求和 +int Algo_5_17_3(SqList L, int len) { + int sum; + + // 获取当前位置的值 + GetElem(L, len, &sum); + + if(len == 1) { + return sum; + } + + // 获取先前序列的和 + sum += Algo_5_17_3(L, --len); + + return sum; +} + +// 递归求积 +double Algo_5_17_4(SqList L, int len) { + int value; + double mul; + + // 获取当前位置的值 + GetElem(L, len, &value); + mul = value; + + if(len == 1) { + return mul; + } + + // 获取先前序列的积 + mul *= Algo_5_17_4(L, --len); + + return mul; +} + +// 递归求平均数 +double Algo_5_17_5(SqList L, int len) { + int value; + double avg; + + // 获取当前位置的值 + GetElem(L, len, &value); + avg = value; + + if(len == 1) { + return avg; + } + + // 获取先前序列的平均数 + avg = (Algo_5_17_5(L, len - 1) * (len - 1) + value) / len; + + return avg; +} diff --git a/CLion/ExerciseBook/05.17/CMakeLists.txt b/CLion/ExerciseBook/05.17/CMakeLists.txt new file mode 100644 index 0000000..b86f006 --- /dev/null +++ b/CLion/ExerciseBook/05.17/CMakeLists.txt @@ -0,0 +1,7 @@ +# 包含公共库 +include_directories(${CMAKE_SOURCE_DIR}/Status) + +# 生成可执行文件 +add_executable(05.17 SqList.h SqList.c 05.17.c) +# 链接公共库 +target_link_libraries(05.17 Scanf_lib) \ No newline at end of file diff --git a/CLion/ExerciseBook/05.17/SqList.c b/CLion/ExerciseBook/05.17/SqList.c new file mode 100644 index 0000000..df834a4 --- /dev/null +++ b/CLion/ExerciseBook/05.17/SqList.c @@ -0,0 +1,337 @@ +/*============================= + * 线性表的顺序存储结构(顺序表) + * + * 包含算法: 2.3、2.4、2.5、2.6 + =============================*/ + +#include "SqList.h" + +/* + * ████████ 算法2.3 ████████ + * + * 初始化 + * + * 初始化成功则返回OK,否则返回ERROR。 + */ +Status InitList(SqList* L) { + // 分配指定容量的内存,如果分配失败,则返回NULL + (*L).elem = (ElemType*) malloc(LIST_INIT_SIZE * sizeof(ElemType)); + if((*L).elem == NULL) { + // 存储内存失败 + exit(OVERFLOW); + } + + (*L).length = 0; // 初始化顺序表长度为0 + (*L).listsize = LIST_INIT_SIZE; // 顺序表初始内存分配量 + + return OK; // 初始化成功 +} + +/* + * 销毁(结构) + * + * 释放顺序表所占内存。 + */ +Status DestroyList(SqList* L) { + // 确保顺序表结构存在 + if(L == NULL || (*L).elem == NULL) { + return ERROR; + } + + // 释放顺序表内存 + free((*L).elem); + + // 释放内存后置空指针 + (*L).elem = NULL; + + // 顺序表长度跟容量都归零 + (*L).length = 0; + (*L).listsize = 0; + + return OK; +} + +/* + * 置空(内容) + * + * 只是清理顺序表中存储的数据,不释放顺序表所占内存。 + */ +Status ClearList(SqList* L) { + // 确保顺序表结构存在 + if(L == NULL || (*L).elem == NULL) { + return ERROR; + } + + (*L).length = 0; + + return OK; +} + +/* + * 判空 + * + * 判断顺序表中是否包含有效数据。 + * + * 返回值: + * TRUE : 顺序表为空 + * FALSE: 顺序表不为空 + */ +Status ListEmpty(SqList L) { + return L.length == 0 ? TRUE : FALSE; +} + +/* + * 计数 + * + * 返回顺序表包含的有效元素的数量。 + */ +int ListLength(SqList L) { + return L.length; +} + +/* + * 取值 + * + * 获取顺序表中第i个元素,将其存储到e中。 + * 如果可以找到,返回OK,否则,返回ERROR。 + * + *【备注】 + * 教材中i的含义是元素位置,从1开始计数,但这不符合编码的通用约定。 + * 通常,i的含义应该指索引,即从0开始计数。 + */ +Status GetElem(SqList L, int i, ElemType* e) { + // 因为i的含义是位置,所以其合法范围是:[1, length] + if(i < 1 || i > L.length) { + return ERROR; //i值不合法 + } + + *e = L.elem[i - 1]; + + return OK; +} + +/* + * ████████ 算法2.6 ████████ + * + * 查找 + * + * 返回顺序表中首个与e满足Compare关系的元素位序。 + * 如果不存在这样的元素,则返回0。 + * + *【备注】 + * 元素e是Compare函数第二个形参 + */ +int LocateElem(SqList L, ElemType e, Status(Compare)(ElemType, ElemType)) { + int i; + ElemType* p; + + // 确保顺序表结构存在 + if(L.elem == NULL) { + return ERROR; + } + + /* + * i的初值为第1个元素的位序 + * + * 其实,更自然的写法是将i初始化为第1个元素的索引 + * 但由于教材中是按位序计数的,所以这里仍写作位序 + */ + i = 1; + + // p的初值为第1个元素的存储位置 + p = L.elem; + + // 遍历顺序表 + while(i <= L.length && !Compare(*p++, e)) { + ++i; + } + + if(i <= L.length) { + return i; + } else { + return 0; + } +} + +/* + * 前驱 + * + * 获取元素cur_e的前驱, + * 如果存在,将其存储到pre_e中,返回OK, + * 如果不存在,则返回ERROR。 + */ +Status PriorElem(SqList L, ElemType cur_e, ElemType* pre_e) { + int i; + + // 确保顺序表结构存在,且最少包含两个元素 + if(L.elem == NULL || L.length < 2) { + return ERROR; + } + + // 这里的i初始化为第1个元素的【索引】 + i = 0; + + // 从第1个元素开始,查找cur_e的位置 + while(i < L.length && L.elem[i] != cur_e) { + ++i; + } + + // 如果cur_e是首个元素(没有前驱),或者没找到元素cur_e,返回ERROR + if(i==0 || i >= L.length) { + return ERROR; + } + + // 存储cur_e的前驱 + *pre_e = L.elem[i - 1]; + + return OK; +} + +/* + * 后继 + * + * 获取元素cur_e的后继, + * 如果存在,将其存储到next_e中,返回OK, + * 如果不存在,则返回ERROR。 + */ +Status NextElem(SqList L, ElemType cur_e, ElemType* next_e) { + int i; + + // 确保顺序表结构存在,且最少包含两个元素 + if(L.elem == NULL || L.length < 2) { + return ERROR; + } + + // 这里的i初始化为第1个元素的【索引】 + i = 0; + + // 从第1个元素开始,查找cur_e的位置 + while(i < L.length-1 && L.elem[i] != cur_e) { + ++i; + } + + // 如果cur_e是最后1个元素(没有前驱),或者没找到元素cur_e,返回ERROR + if(i >= L.length-1) { + return ERROR; + } + + // 存储cur_e的前驱 + *next_e = L.elem[i + 1]; + + return OK; +} + +/* + * ████████ 算法2.4 ████████ + * + * 插入 + * + * 向顺序表第i个位置上插入e,插入成功则返回OK,否则返回ERROR。 + * + *【备注】 + * 教材中i的含义是元素位置,从1开始计数 + */ +Status ListInsert(SqList* L, int i, ElemType e) { + ElemType* newbase; + ElemType* p, * q; + + // 确保顺序表结构存在 + if(L == NULL || (*L).elem == NULL) { + return ERROR; + } + + // i值越界 + if(i < 1 || i > (*L).length + 1) { + return ERROR; + } + + // 若存储空间已满,则增加新空间 + if((*L).length >= (*L).listsize) { + // 基于现有空间扩容 + newbase = (ElemType*) realloc((*L).elem, ((*L).listsize + LISTINCREMENT) * sizeof(ElemType)); + if(newbase == NULL) { + // 存储内存失败 + exit(OVERFLOW); + } + + // 新基址 + (*L).elem = newbase; + // 存的存储空间 + (*L).listsize += LISTINCREMENT; + } + + // q为插入位置 + q = &(*L).elem[i - 1]; + + // 1.右移元素,腾出位置 + for(p = &(*L).elem[(*L).length - 1]; p >= q; --p) { + *(p + 1) = *p; + } + + // 2.插入e + *q = e; + + // 3.表长增1 + (*L).length++; + + return OK; +} + +/* + * ████████ 算法2.5 ████████ + * + * 删除 + * + * 删除顺序表第i个位置上的元素,并将被删除元素存储到e中。 + * 删除成功则返回OK,否则返回ERROR。 + * + *【备注】 + * 教材中i的含义是元素位置,从1开始计数 + */ +Status ListDelete(SqList* L, int i, ElemType* e) { + ElemType* p, * q; + + // 确保顺序表结构存在 + if(L == NULL || (*L).elem == NULL) { + return ERROR; + } + + // i值越界 + if(i < 1 || i > (*L).length) { + return ERROR; + } + + // p为被删除元素的位置 + p = &(*L).elem[i - 1]; + + // 1.获取被删除元素 + *e = *p; + + // 表尾元素位置 + q = (*L).elem + (*L).length - 1; + + // 2.左移元素,被删除元素的位置上会有新元素进来 + for(++p; p <= q; ++p) { + *(p - 1) = *p; + } + + // 3.表长减1 + (*L).length--; + + return OK; +} + +/* + * 遍历 + * + * 用visit函数访问顺序表L + */ +void ListTraverse(SqList L, void(Visit)(ElemType)) { + int i; + + for(i = 0; i < L.length; i++) { + Visit(L.elem[i]); + } + + printf("\n"); +} diff --git a/CLion/ExerciseBook/05.17/SqList.h b/CLion/ExerciseBook/05.17/SqList.h new file mode 100644 index 0000000..51e9e93 --- /dev/null +++ b/CLion/ExerciseBook/05.17/SqList.h @@ -0,0 +1,149 @@ +/*============================= + * 线性表的顺序存储结构(顺序表) + * + * 包含算法: 2.3、2.4、2.5、2.6 + =============================*/ + +#ifndef SQLIST_H +#define SQLIST_H + +#include +#include // 提供malloc、realloc、free、exit原型 +#include "Status.h" //**▲01 绪论**// + +/* 宏定义 */ +#define LIST_INIT_SIZE 100 // 顺序表存储空间的初始分配量 +#define LISTINCREMENT 10 // 顺序表存储空间的分配增量 + +/* 顺序表元素类型定义 */ +typedef int ElemType; + +/* + * 顺序表结构 + * + * 注:elem在使用前需要先为其分配内存,且元素从elem[0]处开始存储 + */ +typedef struct { + ElemType* elem; // 顺序表存储空间的基址(指向顺序表所占内存的起始位置) + int length; // 当前顺序表长度(包含多少元素) + int listsize; // 当前分配的存储容量(可以存储多少元素) +} SqList; + + +/* + * ████████ 算法2.3 ████████ + * + * 初始化 + * + * 初始化成功则返回OK,否则返回ERROR。 + */ +Status InitList(SqList* L); + +/* + * 销毁(结构) + * + * 释放顺序表所占内存。 + */ +Status DestroyList(SqList* L); + +/* + * 置空(内容) + * + * 只是清理顺序表中存储的数据,不释放顺序表所占内存。 + */ +Status ClearList(SqList* L); + +/* + * 判空 + * + * 判断顺序表中是否包含有效数据。 + * + * 返回值: + * TRUE : 顺序表为空 + * FALSE: 顺序表不为空 + */ +Status ListEmpty(SqList L); + +/* + * 计数 + * + * 返回顺序表包含的有效元素的数量。 + */ +int ListLength(SqList L); + +/* + * 取值 + * + * 获取顺序表中第i个元素,将其存储到e中。 + * 如果可以找到,返回OK,否则,返回ERROR。 + * + *【备注】 + * 教材中i的含义是元素位置,从1开始计数,但这不符合编码的通用约定。 + * 通常,i的含义应该指索引,即从0开始计数。 + */ +Status GetElem(SqList L, int i, ElemType* e); + +/* + * ████████ 算法2.6 ████████ + * + * 查找 + * + * 返回顺序表中首个与e满足Compare关系的元素位序。 + * 如果不存在这样的元素,则返回0。 + * + *【备注】 + * 元素e是Compare函数第二个形参 + */ +int LocateElem(SqList L, ElemType e, Status(Compare)(ElemType, ElemType)); + +/* + * 前驱 + * + * 获取元素cur_e的前驱, + * 如果存在,将其存储到pre_e中,返回OK, + * 如果不存在,则返回ERROR。 + */ +Status PriorElem(SqList L, ElemType cur_e, ElemType* pre_e); + +/* + * 后继 + * + * 获取元素cur_e的后继, + * 如果存在,将其存储到next_e中,返回OK, + * 如果不存在,则返回ERROR。 + */ +Status NextElem(SqList L, ElemType cur_e, ElemType* next_e); + +/* + * ████████ 算法2.4 ████████ + * + * 插入 + * + * 向顺序表第i个位置上插入e,插入成功则返回OK,否则返回ERROR。 + * + *【备注】 + * 教材中i的含义是元素位置,从1开始计数 + */ +Status ListInsert(SqList* L, int i, ElemType e); + +/* + * ████████ 算法2.5 ████████ + * + * 删除 + * + * 删除顺序表第i个位置上的元素,并将被删除元素存储到e中。 + * 删除成功则返回OK,否则返回ERROR。 + * + *【备注】 + * 教材中i的含义是元素位置,从1开始计数 + */ +Status ListDelete(SqList* L, int i, ElemType* e); + +/* + * 遍历 + * + * 用visit函数访问顺序表L + */ +void ListTraverse(SqList L, void (Visit)(ElemType)); + +#endif diff --git a/CLion/ExerciseBook/05.18/05.18.c b/CLion/ExerciseBook/05.18/05.18.c new file mode 100644 index 0000000..10f91a3 --- /dev/null +++ b/CLion/ExerciseBook/05.18/05.18.c @@ -0,0 +1,91 @@ +#include +#include // 提供 system、rand、srand 原型 +#include // 提供 time 原型 +#include "Status.h" //**▲01 绪论**// +#include "Array.h" //**▲05 数组和广义表**// + +/* + * 将数组A中的元素循环右移k个位置 + */ +Status Algo_5_18(Array A, int k); + +// 逆置[begin, end]范围内的元素 +static Status Reversal_5_18(Array A, int begin, int end); + + +int main(int argc, char* argv[]) { + Array A; + ElemType e; + int i; + int k = 7; // 右移位数 + + // 初始化长度为10的一维数组 + InitArray(&A, 1, 10); + + srand((unsigned) time(NULL)); // 用系统时间做随机数种子 + + for(i = 0; i < Length(A); i++) { + e = rand() % 100; + Assign(&A, e, i); + } + + printf("数组A包含的元素为:\n"); + for(i = 0; i < Length(A); i++) { + Value(A, &e, i); + printf("%2d ", e); + } + printf("\n"); + + printf("将数组A循环右移 %d 位后:\n", k); + Algo_5_18(A, k); + for(i = 0; i < Length(A); i++) { + Value(A, &e, i); + printf("%2d ", e); + } + printf("\n"); + + return 0; +} + + +/* + * 将数组A中的元素循环右移k个位置 + */ +Status Algo_5_18(Array A, int k) { + int n, p; + + n = Length(A); + + p = k % n; // 计算实际需要循环右移的位数 + if(p <= 0) { + return ERROR; + } + + Reversal_5_18(A, 0, n-1); // 逆置[0, n-1]范围内的元素 + Reversal_5_18(A, 0, p-1); // 逆置[0, p-1]范围内的元素 + Reversal_5_18(A, p, n-1); // 逆置[p, n-1]范围内的元素 + + return OK; +} + +// 逆置[begin, end]范围内的元素 +static Status Reversal_5_18(Array A, int begin, int end) { + int i; + ElemType e1, e2; + + if(begin < 0 || end > Length(A)-1 || begin >= end) { + return ERROR; + } + + // 用"交换法"逆置 + for(i = 0; i < (end - begin + 1) / 2; i++) { + Value(A, &e1, begin + i); // 获取中点前的元素 + Value(A, &e2, end - i); // 获取中点后的元素 + + // 两元素完成交换 + Assign(&A, e2, begin + i); + Assign(&A, e1, end - i); + } + + return OK; +} diff --git a/CLion/ExerciseBook/05.18/Array.c b/CLion/ExerciseBook/05.18/Array.c new file mode 100644 index 0000000..db277ac --- /dev/null +++ b/CLion/ExerciseBook/05.18/Array.c @@ -0,0 +1,195 @@ +/*======== + * 多维数组 + =========*/ + +#include "Array.h" //**▲05 数组和广义表**// + +/* + * 初始化。 + * + * 初始化维数为dim的数组,可变参数指示各维度的大小。 + */ +Status InitArray(Array* A, int dim, ...) { + int elemtotal; // 统计数组中总元素个数 + va_list ap; // ap存放可变参数表信息,指示各维度的大小 + int i; + + if(A == NULL) { + return ERROR; + } + + if(dim < 1 || dim > MAX_ARRAY_DIM) { // 数组维数有限制 + return ERROR; + } + + (*A).dim = dim; // 初始化数组维度 + + // 初始化数组维度信息表 + (*A).bounds = (int*) malloc(dim * sizeof(int)); + if((*A).bounds == NULL) { + exit(OVERFLOW); + } + + // 若维度长度合法,则存入bounds,并求出A的元素总数elemtotal + elemtotal = 1; + + // 使ap指向第一个可变参数,dim相当于起始标识 + va_start(ap, dim); + + for(i = 0; i < dim; i++) { + // 记录当前维度的宽度 + (*A).bounds[i] = va_arg(ap, int); + if((*A).bounds[i] <= 0) { + return ERROR; + } + + elemtotal *= A->bounds[i]; + } + + // 置空ap + va_end(ap); + + // 初始化数组空间,以存放元素 + (*A).base = (ElemType*) malloc(elemtotal * sizeof(ElemType)); + if((*A).base == NULL) { + exit(OVERFLOW); + } + + // 初始化数组映像函数常量信息表 + (*A).constants = (int*) malloc(dim * sizeof(int)); + if((*A).constants == NULL) { + exit(OVERFLOW); + } + + // 遍历最后一个维度,每次总是需要跨越一个元素 + (*A).constants[dim - 1] = 1; + for(i = dim - 2; i >= 0; i--) { + (*A).constants[i] = (*A).bounds[i + 1] * (*A).constants[i + 1]; + } + + /* + * 举例: + * 对于三维数组[2,3,4]来说,bounds的值为<2,3,4>,constants的值为<12,4,1> + * 分析bounds,第一维中包含2个元素,第二维中包含3个元素,第三维中包含4个元素 + * 分析constants,遍历第一维,每次需要跨过12个元素,遍历第二维,每次需要跨越4个元素,遍历第三维,每次需要跨越1个元素 + */ + + return OK; +} + +/* + * 销毁(结构)。 + * + * 销毁数组占用的空间。 + */ +Status DestroyArray(Array* A) { + if(A == NULL || (*A).base == NULL || (*A).bounds == NULL || (*A).constants == NULL) { + return ERROR; + } + + free((*A).base); + (*A).base = NULL; + + free((*A).bounds); + (*A).bounds = NULL; + + free((*A).constants); + (*A).constants = NULL; + + (*A).dim = 0; + + return OK; +} + +/* + * 取值。 + * + * 获取指定下标处的元素值,可变参数为dim个下标值,指示待获取元素所在下标。 + */ +Status Value(Array A, ElemType* e, ...) { + va_list ap; + Status result; + int off; + + va_start(ap, e); + + // 计算从起点元素到目标元素需要跨越的元素数量 + result = Locate(A, ap, &off); + + va_end(ap); + + if(result == OVERFLOW) { + return result; + } + + *e = *(A.base + off); + + return OK; +} + +/* + * 赋值。 + * + * 为指定下标处的元素赋值,可变参数为dim个下标值,指示待赋值元素所在下标。 + */ +Status Assign(Array* A, ElemType e, ...) { + va_list ap; + Status result; + int off; + + va_start(ap, e); + + // 计算从起点元素到目标元素需要跨越的元素数量 + result = Locate(*A, ap, &off); + + va_end(ap); + + if(result == OVERFLOW) { + return result; + } + + *(A->base + off) = e; + + return OK; +} + +/* + * 求出ap指示的值在数组A中的相对位置, + * 即计算从起点元素到目标元素需要跨越的元素数量。 + */ +static Status Locate(Array A, va_list ap, int* off) { + int i, ind; + + *off = 0; + + for(i = 0; i < A.dim; i++) { + ind = va_arg(ap, int); + + // 保证下标不越界 + if(ind < 0 || ind >= A.bounds[i]) { + return OVERFLOW; + } + + // 某个维度的单位元素个数*需要跨过的单位 + *off += A.constants[i] * ind; + } + + return OK; +} + +/* + * 计算数组中元素的个数 + * + *【注】 + * 此为新增的函数 + */ +int Length(Array A) { + int i; + int elemtotal = 1; + + for(i = 0; i < A.dim; i++) { + elemtotal *= A.bounds[i]; + } + + return elemtotal; +} diff --git a/CLion/ExerciseBook/05.18/Array.h b/CLion/ExerciseBook/05.18/Array.h new file mode 100644 index 0000000..d97e1e8 --- /dev/null +++ b/CLion/ExerciseBook/05.18/Array.h @@ -0,0 +1,70 @@ +/*======== + * 多维数组 + =========*/ + +#ifndef ARRAY_H +#define ARRAY_H + +#include +#include // 提供malloc、realloc、free、exit原型 +#include // 提供宏va_start、va_arg、va_end +#include "Status.h" //**▲01 绪论**// + +/* 宏定义 */ +#define MAX_ARRAY_DIM 8 // 这里假设数组的最大维度为8 + +/* 数组元素类型 */ +typedef int ElemType; + +/* 数组的顺序存储表示 */ +typedef struct { + ElemType* base; // 数组元素基址(存放数组元素) + int dim; // 数组维数 + int* bounds; // 数组维界基址(存放数组行、列信息) + int* constants; // 数组映像函数常量基址(存储遍历某个维度时,每次需要越过的元素个数) +} Array; + + +/* + * 初始化。 + * + * 初始化维数为dim的数组,可变参数指示各维度的大小。 + */ +Status InitArray(Array* A, int dim, ...); + +/* + * 销毁(结构)。 + * + * 销毁数组占用的空间。 + */ +Status DestroyArray(Array* A); + +/* + * 取值。 + * + * 获取指定下标处的元素值,可变参数为dim个下标值,指示待获取元素所在下标。 + */ +Status Value(Array A, ElemType* e, ...); + +/* + * 赋值。 + * + * 为指定下标处的元素赋值,可变参数为dim个下标值,指示待赋值元素所在下标。 + */ +Status Assign(Array* A, ElemType e, ...); + +/* + * 求出ap指示的值在数组A中的相对位置, + * 即计算从起点元素到目标元素需要跨越的元素数量。 + */ +static Status Locate(Array A, va_list ap, int *off); + +/* + * 计算数组中元素的个数 + * + *【注】 + * 此为新增的函数 + */ +int Length(Array A); + +#endif diff --git a/CLion/ExerciseBook/05.18/CMakeLists.txt b/CLion/ExerciseBook/05.18/CMakeLists.txt new file mode 100644 index 0000000..6902b25 --- /dev/null +++ b/CLion/ExerciseBook/05.18/CMakeLists.txt @@ -0,0 +1,7 @@ +# 包含公共库 +include_directories(${CMAKE_SOURCE_DIR}/Status) + +# 生成可执行文件 +add_executable(05.18 Array.h Array.c 05.18.c) +# 链接公共库 +target_link_libraries(05.18 Scanf_lib) \ No newline at end of file diff --git a/CLion/ExerciseBook/05.19/05.19.c b/CLion/ExerciseBook/05.19/05.19.c new file mode 100644 index 0000000..67d9b0e --- /dev/null +++ b/CLion/ExerciseBook/05.19/05.19.c @@ -0,0 +1,114 @@ +#include +#include +#include +#include "Array.h" //**▲05 数组和广义表**// + +/* 数组元素坐标 */ +typedef struct { + int x; + int y; + ElemType value; +} Elem; + +/* + * 寻找二维数组A中的马鞍点 + * + *【注】 + * 数组每行每列的元素不唯一 + */ +void Algo_5_19(Array A); + + +int main(int argc, char* argv[]) { + int a[3][4] = { + {10, 16, 13, 14}, + {15, 18, 15, 20}, + { 5, 8, 12, 32} + }; + int i, j; + Array A; + + // 准备测试数据 + InitArray(&A, 2, 3, 4); + for(i = 0; i < 3; i++) { + for(j = 0; j < 4; j++) { + Assign(&A, a[i][j], i, j); + } + } + + // 寻找马鞍点 + Algo_5_19(A); + + return 0; +} + + +/* + * 寻找二维数组A中的马鞍点 + * + *【注】 + * 数组每行每列的元素不唯一 + */ +void Algo_5_19(Array A) { + int row, col; // 行数与列数 + Elem* Min; // 存储数组A中每行的最小值信息 + ElemType* Max; // 存储数组A中每列的最大值(只存储值) + int total, k; // total记录Min中存储的元素数量 + int i, j; + ElemType e; + int count; + int min; + + row = A.bounds[0]; + col = A.bounds[1]; + + Min = (Elem*) malloc(row * col * sizeof(Elem)); + + Max = (ElemType*) malloc(col * sizeof(ElemType)); + // 初始化最大值数组 + for(j = 0; j < col; j++) { + Max[j] = INT_MIN; + } + + total = 0; + + for(i = 0; i < row; i++) { + min = INT_MAX; // 当前行最小值 + + for(j = 0; j < col; j++) { + // 获取元素A[i][j] + Value(A, &e, i, j); + + // 记录最大值 + if(e > Max[j]) { + Max[j] = e; + } + + // 记录最小值信息 + if(e <= min) { + // 每次发现更小的,k都需要重置 + if(e < min) { + k = total; // 重新统计当前行的最小值元素数量 + min = e; + } + + Min[k].x = i; + Min[k].y = j; + Min[k].value = e; + + k++; + } + } + + // 累加本次新增的元素数量 + total += (k - total); + } + + count = 0; + for(k = 0; k < total; k++) { + // 如果当前最小值所在列的最大值与当前最小值一致,则遇到了马鞍点 + if(Max[Min[k].y] == Min[k].value) { + printf("第 %2d 个马鞍点是位于 (%2d, %2d) 处的 %d\n", ++count, Min[k].x, Min[k].y, Min[k].value); + } + } +} diff --git a/CLion/ExerciseBook/05.19/Array.c b/CLion/ExerciseBook/05.19/Array.c new file mode 100644 index 0000000..db6347e --- /dev/null +++ b/CLion/ExerciseBook/05.19/Array.c @@ -0,0 +1,178 @@ +/*======== + * 多维数组 + =========*/ + +#include "Array.h" //**▲05 数组和广义表**// + +/* + * 初始化。 + * + * 初始化维数为dim的数组,可变参数指示各维度的大小。 + */ +Status InitArray(Array* A, int dim, ...) { + int elemtotal; // 统计数组中总元素个数 + va_list ap; // ap存放可变参数表信息,指示各维度的大小 + int i; + + if(A == NULL) { + return ERROR; + } + + if(dim < 1 || dim > MAX_ARRAY_DIM) { // 数组维数有限制 + return ERROR; + } + + (*A).dim = dim; // 初始化数组维度 + + // 初始化数组维度信息表 + (*A).bounds = (int*) malloc(dim * sizeof(int)); + if((*A).bounds == NULL) { + exit(OVERFLOW); + } + + // 若维度长度合法,则存入bounds,并求出A的元素总数elemtotal + elemtotal = 1; + + // 使ap指向第一个可变参数,dim相当于起始标识 + va_start(ap, dim); + + for(i = 0; i < dim; i++) { + // 记录当前维度的宽度 + (*A).bounds[i] = va_arg(ap, int); + if((*A).bounds[i] <= 0) { + return ERROR; + } + + elemtotal *= A->bounds[i]; + } + + // 置空ap + va_end(ap); + + // 初始化数组空间,以存放元素 + (*A).base = (ElemType*) malloc(elemtotal * sizeof(ElemType)); + if((*A).base == NULL) { + exit(OVERFLOW); + } + + // 初始化数组映像函数常量信息表 + (*A).constants = (int*) malloc(dim * sizeof(int)); + if((*A).constants == NULL) { + exit(OVERFLOW); + } + + // 遍历最后一个维度,每次总是需要跨越一个元素 + (*A).constants[dim - 1] = 1; + for(i = dim - 2; i >= 0; i--) { + (*A).constants[i] = (*A).bounds[i + 1] * (*A).constants[i + 1]; + } + + /* + * 举例: + * 对于三维数组[2,3,4]来说,bounds的值为<2,3,4>,constants的值为<12,4,1> + * 分析bounds,第一维中包含2个元素,第二维中包含3个元素,第三维中包含4个元素 + * 分析constants,遍历第一维,每次需要跨过12个元素,遍历第二维,每次需要跨越4个元素,遍历第三维,每次需要跨越1个元素 + */ + + return OK; +} + +/* + * 销毁(结构)。 + * + * 销毁数组占用的空间。 + */ +Status DestroyArray(Array* A) { + if(A == NULL || (*A).base == NULL || (*A).bounds == NULL || (*A).constants == NULL) { + return ERROR; + } + + free((*A).base); + (*A).base = NULL; + + free((*A).bounds); + (*A).bounds = NULL; + + free((*A).constants); + (*A).constants = NULL; + + (*A).dim = 0; + + return OK; +} + +/* + * 取值。 + * + * 获取指定下标处的元素值,可变参数为dim个下标值,指示待获取元素所在下标。 + */ +Status Value(Array A, ElemType* e, ...) { + va_list ap; + Status result; + int off; + + va_start(ap, e); + + // 计算从起点元素到目标元素需要跨越的元素数量 + result = Locate(A, ap, &off); + + va_end(ap); + + if(result == OVERFLOW) { + return result; + } + + *e = *(A.base + off); + + return OK; +} + +/* + * 赋值。 + * + * 为指定下标处的元素赋值,可变参数为dim个下标值,指示待赋值元素所在下标。 + */ +Status Assign(Array* A, ElemType e, ...) { + va_list ap; + Status result; + int off; + + va_start(ap, e); + + // 计算从起点元素到目标元素需要跨越的元素数量 + result = Locate(*A, ap, &off); + + va_end(ap); + + if(result == OVERFLOW) { + return result; + } + + *(A->base + off) = e; + + return OK; +} + +/* + * 求出ap指示的值在数组A中的相对位置, + * 即计算从起点元素到目标元素需要跨越的元素数量。 + */ +static Status Locate(Array A, va_list ap, int* off) { + int i, ind; + + *off = 0; + + for(i = 0; i < A.dim; i++) { + ind = va_arg(ap, int); + + // 保证下标不越界 + if(ind < 0 || ind >= A.bounds[i]) { + return OVERFLOW; + } + + // 某个维度的单位元素个数*需要跨过的单位 + *off += A.constants[i] * ind; + } + + return OK; +} diff --git a/CLion/ExerciseBook/05.19/Array.h b/CLion/ExerciseBook/05.19/Array.h new file mode 100644 index 0000000..fe63aed --- /dev/null +++ b/CLion/ExerciseBook/05.19/Array.h @@ -0,0 +1,62 @@ +/*======== + * 多维数组 + =========*/ + +#ifndef ARRAY_H +#define ARRAY_H + +#include +#include // 提供malloc、realloc、free、exit原型 +#include // 提供宏va_start、va_arg、va_end +#include "Status.h" //**▲01 绪论**// + +/* 宏定义 */ +#define MAX_ARRAY_DIM 8 // 这里假设数组的最大维度为8 + +/* 数组元素类型 */ +typedef int ElemType; + +/* 数组的顺序存储表示 */ +typedef struct { + ElemType* base; // 数组元素基址(存放数组元素) + int dim; // 数组维数 + int* bounds; // 数组维界基址(存放数组行、列信息) + int* constants; // 数组映像函数常量基址(存储遍历某个维度时,每次需要越过的元素个数) +} Array; + + +/* + * 初始化。 + * + * 初始化维数为dim的数组,可变参数指示各维度的大小。 + */ +Status InitArray(Array* A, int dim, ...); + +/* + * 销毁(结构)。 + * + * 销毁数组占用的空间。 + */ +Status DestroyArray(Array* A); + +/* + * 取值。 + * + * 获取指定下标处的元素值,可变参数为dim个下标值,指示待获取元素所在下标。 + */ +Status Value(Array A, ElemType* e, ...); + +/* + * 赋值。 + * + * 为指定下标处的元素赋值,可变参数为dim个下标值,指示待赋值元素所在下标。 + */ +Status Assign(Array* A, ElemType e, ...); + +/* + * 求出ap指示的值在数组A中的相对位置, + * 即计算从起点元素到目标元素需要跨越的元素数量。 + */ +static Status Locate(Array A, va_list ap, int *off); + +#endif diff --git a/CLion/ExerciseBook/05.19/CMakeLists.txt b/CLion/ExerciseBook/05.19/CMakeLists.txt new file mode 100644 index 0000000..47f532c --- /dev/null +++ b/CLion/ExerciseBook/05.19/CMakeLists.txt @@ -0,0 +1,7 @@ +# 包含公共库 +include_directories(${CMAKE_SOURCE_DIR}/Status) + +# 生成可执行文件 +add_executable(05.19 Array.h Array.c 05.19.c) +# 链接公共库 +target_link_libraries(05.19 Scanf_lib) \ No newline at end of file diff --git a/CLion/ExerciseBook/05.20/05.20.c b/CLion/ExerciseBook/05.20/05.20.c new file mode 100644 index 0000000..096516e --- /dev/null +++ b/CLion/ExerciseBook/05.20/05.20.c @@ -0,0 +1,112 @@ +#include +#include // 提供 system、rand、srand 原型 +#include // 提供 time 原型 +#include "Array.h" //**▲05 数组和广义表**// + +// 根据多项式系数表,输出多项式 +void Algo_5_20(Array A); + +// 数组输出函数的内部实现 +static void Print(Array A, int dim, int index[]); + + +int main(int argc, char* argv[]) { + Array A; + int i, j, k; + ElemType e = 0; + + // 初始化一个维度为<2,3,4>的三维数组 + InitArray(&A, 3, 2, 3, 4); + + srand((unsigned) time(NULL)); // 用系统时间做随机数种子 + + // 准备测试数据 + for(i = 0; i < A.bounds[0]; i++) { + for(j = 0; j < A.bounds[1]; j++) { + for(k = 0; k < A.bounds[2]; k++) { + e = rand() % 50 - 25; // 用随机数填充数组 + Assign(&A, e, i, j, k); + } + } + } + + // 输出多项式 + Algo_5_20(A); + + return 0; +} + + +// 根据多项式系数表,输出多项式 +void Algo_5_20(Array A) { + int i; + int* index; + + // 在遍历数组元素时,记录每个元素的索引(只记录前dim-1维) + index = (int*) malloc((A.dim - 1) * sizeof(int)); + for(i = 0; i < A.dim - 1; i++) { + index[i] = -1; + } + + Print(A, 1, index); + + printf("\n"); +} + +// 数组输出函数的内部实现 +static void Print(Array A, int dim, int index[]) { + int i, j; + int start; + ElemType coef; + + if(dim == A.dim) { + start = 0; + + // 计算本次遍历的起始元素位置 + for(i = 0; i < dim - 1; i++) { + start += index[i] * A.constants[i]; + } + + // 遍历最后一个维度内的元素 + for(i = 0; i < A.bounds[dim - 1]; i++) { + // 获取系数 + coef = A.base[start + i]; + + // 系数为0的项不必输出 + if(coef == 0) { + continue; + } + + if(coef < 0) { + printf(" - "); + } else { + printf(" + "); + } + + // 系数的绝对值为1时,无需输出系数 + if(abs(coef) != 1) { + // 输出系数(不带符号,前面已经输出过符号),第一项也会带着符号 + printf("%d", abs(coef)); + } + + /* + * 输出多项式的每一项,未知数依次用a、b、c...命名 + * + *【注】 + * 对于指数位0或者指数位1的情形,这里依然将其打印出来了 + * 可以选择不打印这些标记 + */ + for(j = 0; j < dim - 1; j++) { + printf("%c^%d", 'a' + j, index[j]); + } + printf("%c^%d", 'a' + j, i); + } + } else { + for(i = 0; i < A.bounds[dim - 1]; i++) { + // 索引轮转 + index[dim - 1] = (index[dim - 1] + 1 + A.bounds[dim - 1]) % A.bounds[dim - 1]; + + Print(A, dim + 1, index); + } + } +} diff --git a/CLion/ExerciseBook/05.20/Array.c b/CLion/ExerciseBook/05.20/Array.c new file mode 100644 index 0000000..db6347e --- /dev/null +++ b/CLion/ExerciseBook/05.20/Array.c @@ -0,0 +1,178 @@ +/*======== + * 多维数组 + =========*/ + +#include "Array.h" //**▲05 数组和广义表**// + +/* + * 初始化。 + * + * 初始化维数为dim的数组,可变参数指示各维度的大小。 + */ +Status InitArray(Array* A, int dim, ...) { + int elemtotal; // 统计数组中总元素个数 + va_list ap; // ap存放可变参数表信息,指示各维度的大小 + int i; + + if(A == NULL) { + return ERROR; + } + + if(dim < 1 || dim > MAX_ARRAY_DIM) { // 数组维数有限制 + return ERROR; + } + + (*A).dim = dim; // 初始化数组维度 + + // 初始化数组维度信息表 + (*A).bounds = (int*) malloc(dim * sizeof(int)); + if((*A).bounds == NULL) { + exit(OVERFLOW); + } + + // 若维度长度合法,则存入bounds,并求出A的元素总数elemtotal + elemtotal = 1; + + // 使ap指向第一个可变参数,dim相当于起始标识 + va_start(ap, dim); + + for(i = 0; i < dim; i++) { + // 记录当前维度的宽度 + (*A).bounds[i] = va_arg(ap, int); + if((*A).bounds[i] <= 0) { + return ERROR; + } + + elemtotal *= A->bounds[i]; + } + + // 置空ap + va_end(ap); + + // 初始化数组空间,以存放元素 + (*A).base = (ElemType*) malloc(elemtotal * sizeof(ElemType)); + if((*A).base == NULL) { + exit(OVERFLOW); + } + + // 初始化数组映像函数常量信息表 + (*A).constants = (int*) malloc(dim * sizeof(int)); + if((*A).constants == NULL) { + exit(OVERFLOW); + } + + // 遍历最后一个维度,每次总是需要跨越一个元素 + (*A).constants[dim - 1] = 1; + for(i = dim - 2; i >= 0; i--) { + (*A).constants[i] = (*A).bounds[i + 1] * (*A).constants[i + 1]; + } + + /* + * 举例: + * 对于三维数组[2,3,4]来说,bounds的值为<2,3,4>,constants的值为<12,4,1> + * 分析bounds,第一维中包含2个元素,第二维中包含3个元素,第三维中包含4个元素 + * 分析constants,遍历第一维,每次需要跨过12个元素,遍历第二维,每次需要跨越4个元素,遍历第三维,每次需要跨越1个元素 + */ + + return OK; +} + +/* + * 销毁(结构)。 + * + * 销毁数组占用的空间。 + */ +Status DestroyArray(Array* A) { + if(A == NULL || (*A).base == NULL || (*A).bounds == NULL || (*A).constants == NULL) { + return ERROR; + } + + free((*A).base); + (*A).base = NULL; + + free((*A).bounds); + (*A).bounds = NULL; + + free((*A).constants); + (*A).constants = NULL; + + (*A).dim = 0; + + return OK; +} + +/* + * 取值。 + * + * 获取指定下标处的元素值,可变参数为dim个下标值,指示待获取元素所在下标。 + */ +Status Value(Array A, ElemType* e, ...) { + va_list ap; + Status result; + int off; + + va_start(ap, e); + + // 计算从起点元素到目标元素需要跨越的元素数量 + result = Locate(A, ap, &off); + + va_end(ap); + + if(result == OVERFLOW) { + return result; + } + + *e = *(A.base + off); + + return OK; +} + +/* + * 赋值。 + * + * 为指定下标处的元素赋值,可变参数为dim个下标值,指示待赋值元素所在下标。 + */ +Status Assign(Array* A, ElemType e, ...) { + va_list ap; + Status result; + int off; + + va_start(ap, e); + + // 计算从起点元素到目标元素需要跨越的元素数量 + result = Locate(*A, ap, &off); + + va_end(ap); + + if(result == OVERFLOW) { + return result; + } + + *(A->base + off) = e; + + return OK; +} + +/* + * 求出ap指示的值在数组A中的相对位置, + * 即计算从起点元素到目标元素需要跨越的元素数量。 + */ +static Status Locate(Array A, va_list ap, int* off) { + int i, ind; + + *off = 0; + + for(i = 0; i < A.dim; i++) { + ind = va_arg(ap, int); + + // 保证下标不越界 + if(ind < 0 || ind >= A.bounds[i]) { + return OVERFLOW; + } + + // 某个维度的单位元素个数*需要跨过的单位 + *off += A.constants[i] * ind; + } + + return OK; +} diff --git a/CLion/ExerciseBook/05.20/Array.h b/CLion/ExerciseBook/05.20/Array.h new file mode 100644 index 0000000..fe63aed --- /dev/null +++ b/CLion/ExerciseBook/05.20/Array.h @@ -0,0 +1,62 @@ +/*======== + * 多维数组 + =========*/ + +#ifndef ARRAY_H +#define ARRAY_H + +#include +#include // 提供malloc、realloc、free、exit原型 +#include // 提供宏va_start、va_arg、va_end +#include "Status.h" //**▲01 绪论**// + +/* 宏定义 */ +#define MAX_ARRAY_DIM 8 // 这里假设数组的最大维度为8 + +/* 数组元素类型 */ +typedef int ElemType; + +/* 数组的顺序存储表示 */ +typedef struct { + ElemType* base; // 数组元素基址(存放数组元素) + int dim; // 数组维数 + int* bounds; // 数组维界基址(存放数组行、列信息) + int* constants; // 数组映像函数常量基址(存储遍历某个维度时,每次需要越过的元素个数) +} Array; + + +/* + * 初始化。 + * + * 初始化维数为dim的数组,可变参数指示各维度的大小。 + */ +Status InitArray(Array* A, int dim, ...); + +/* + * 销毁(结构)。 + * + * 销毁数组占用的空间。 + */ +Status DestroyArray(Array* A); + +/* + * 取值。 + * + * 获取指定下标处的元素值,可变参数为dim个下标值,指示待获取元素所在下标。 + */ +Status Value(Array A, ElemType* e, ...); + +/* + * 赋值。 + * + * 为指定下标处的元素赋值,可变参数为dim个下标值,指示待赋值元素所在下标。 + */ +Status Assign(Array* A, ElemType e, ...); + +/* + * 求出ap指示的值在数组A中的相对位置, + * 即计算从起点元素到目标元素需要跨越的元素数量。 + */ +static Status Locate(Array A, va_list ap, int *off); + +#endif diff --git a/CLion/ExerciseBook/05.20/CMakeLists.txt b/CLion/ExerciseBook/05.20/CMakeLists.txt new file mode 100644 index 0000000..f671f08 --- /dev/null +++ b/CLion/ExerciseBook/05.20/CMakeLists.txt @@ -0,0 +1,7 @@ +# 包含公共库 +include_directories(${CMAKE_SOURCE_DIR}/Status) + +# 生成可执行文件 +add_executable(05.20 Array.h Array.c 05.20.c) +# 链接公共库 +target_link_libraries(05.20 Scanf_lib) \ No newline at end of file diff --git a/CLion/ExerciseBook/05.21/05.21.c b/CLion/ExerciseBook/05.21/05.21.c new file mode 100644 index 0000000..6c147a6 --- /dev/null +++ b/CLion/ExerciseBook/05.21/05.21.c @@ -0,0 +1,43 @@ +#include +#include "Status.h" //**▲01 绪论**// +#include "TSMatrix.h" //**▲05 数组和广义表**// + +/* + * 稀疏矩阵加法:AddSMatrix + * + *【注】 + * 该函数已在TSMatrix相关文件中定义 + */ +Status Algo_5_21(TSMatrix A, TSMatrix B, TSMatrix* C); + + +int main(int argc, char* argv[]) { + TSMatrix A, B, C; + + printf("█ 创建两个稀疏矩阵 A、B ...\n"); + CreateSMatrix(&A, "TestData_A.txt"); + CreateSMatrix(&B, "TestData_B.txt"); + printf("█ A = \n"); + PrintSMatrix(A); + printf("█ B = \n"); + PrintSMatrix(B); + + // 矩阵相加 + Algo_5_21(A, B, &C); + + printf("█ C = A + B = \n"); + PrintSMatrix(C); + + return 0; +} + + +/* + * 稀疏矩阵加法:AddSMatrix + * + *【注】 + * 该函数已在TSMatrix相关文件中定义 + */ +Status Algo_5_21(TSMatrix A, TSMatrix B, TSMatrix* C) { + return AddSMatrix(A, B, C); +} diff --git a/CLion/ExerciseBook/05.21/CMakeLists.txt b/CLion/ExerciseBook/05.21/CMakeLists.txt new file mode 100644 index 0000000..ff970ec --- /dev/null +++ b/CLion/ExerciseBook/05.21/CMakeLists.txt @@ -0,0 +1,13 @@ +# 包含公共库 +include_directories(${CMAKE_SOURCE_DIR}/Status) + +# 生成可执行文件 +add_executable(05.21 TSMatrix.h TSMatrix.c 05.21.c) +# 链接公共库 +target_link_libraries(05.21 Scanf_lib) + + +# 记录要拷贝到*.exe目录下的资源文件 +file(GLOB TestData TestData*.txt) +# 将资源文件拷贝到*.exe目录下,不然无法加载 +file(COPY ${TestData} DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) diff --git a/CLion/ExerciseBook/05.21/TSMatrix.c b/CLion/ExerciseBook/05.21/TSMatrix.c new file mode 100644 index 0000000..7bbf239 --- /dev/null +++ b/CLion/ExerciseBook/05.21/TSMatrix.c @@ -0,0 +1,433 @@ +/*======================= + * 三元组顺序表(稀疏矩阵) + * + * 包含算法: 5.1、5.2 + ========================*/ + +#include "TSMatrix.h" //**▲05 数组和广义表**// + +/* + * 创建稀疏矩阵M + * + * + *【备注】 + * + * 教材中默认从控制台读取数据。 + * 这里为了方便测试,避免每次运行都手动输入数据, + * 因而允许选择从预设的文件path中读取测试数据。 + * + * 如果需要从控制台读取数据,则path为NULL或者为空串, + * 如果需要从文件中读取数据,则需要在path中填写文件名信息。 + */ +Status CreateSMatrix(TSMatrix* M, char* path) { + int k; + FILE* fp; + int readFromConsole; // 是否从控制台读取数据 + + // 如果没有文件路径信息,则从控制台读取输入 + readFromConsole = path == NULL || strcmp(path, "") == 0; + + // 如果没有文件路径信息,则从控制台读取输入 + if(readFromConsole) { + printf("请输入行数:"); + scanf("%d", &((*M).mu)); + printf("请输入列数:"); + scanf("%d", &((*M).nu)); + printf("请输入非零元素个数:"); + scanf("%d", &((*M).tu)); + printf("请输入%d个三元组信息\n", (*M).tu); + for(k = 1; k <= (*M).tu; k++) { + printf("第%2d组:", k); + scanf("%d%d%d", &((*M).data[k].i), &((*M).data[k].j), &((*M).data[k].e)); + } + } else { + fp = fopen(path, "r"); + + ReadData(fp, "%d%d%d", &((*M).mu), &((*M).nu), &((*M).tu)); + + for(k = 1; k <= (*M).tu; k++) { + ReadData(fp, "%d%d%d", &((*M).data[k].i), &((*M).data[k].j), &((*M).data[k].e)); + } + + fclose(fp); + } + + return OK; +} + +/* + * 销毁稀疏矩阵 + * + *【注】 + * 三元组顺序表的结构无法销毁。 + */ +Status DestroySMatrix(TSMatrix* M) { + if(M == NULL) { + return ERROR; + } + + (*M).mu = 0; + (*M).nu = 0; + (*M).tu = 0; + + return OK; +} + +/* + * 矩阵复制 + * + * 创建一个新矩阵T,该矩阵包含了从矩阵M中包含的数据。 + */ +Status CopySMatrix(TSMatrix M, TSMatrix* T) { + (*T) = M; // 结构体之间可以直接复制,即使内部包含数组也可以 + + return OK; +} + +/* + * 矩阵加法 + * + * Q = M + N。 + */ +Status AddSMatrix(TSMatrix M, TSMatrix N, TSMatrix* Q) { + int m, n, k; + + if(M.mu != N.mu || M.nu != N.nu) { + printf("两矩阵的行数、列数不满足相加条件!!\n"); + return ERROR; + } + + // 初始化Q + (*Q).mu = M.mu; + (*Q).nu = M.nu; + (*Q).tu = 0; + + m = n = k = 1; + + // 依次遍历M与N的三元组 + while(m <= M.tu && n <= N.tu) { + // M中的三元组行下标较小 + if(M.data[m].i < N.data[n].i) { + (*Q).data[k] = M.data[m]; + m++; + + // N中的三元组行下标较小 + } else if(M.data[m].i > N.data[n].i) { + (*Q).data[k] = N.data[n]; + n++; + + // M与N中的三元组行下标一致,需要进一步比较列坐标 + } else { + // M中的三元组列下标较小 + if(M.data[m].j < N.data[n].j) { + (*Q).data[k] = M.data[m]; + m++; + + // N中的三元组列下标较小 + } else if(M.data[m].j > N.data[n].j) { + (*Q).data[k] = N.data[n]; + n++; + + // M与N中的三元组列下标一致,需要进行加法运算 + } else { + // 值已经加为0的话,不需要存储该元素 + if((M.data[m].e + N.data[n].e) == 0) { + m++; + n++; + continue; + } else { + (*Q).data[k].i = M.data[m].i; + (*Q).data[k].j = M.data[m].j; + (*Q).data[k].e = M.data[m].e + N.data[n].e; + m++; + n++; + } + } + } + + k++; + (*Q).tu++; + } + + // 遍历M中剩余的三元组 + while(m <= M.tu) { + (*Q).data[k] = M.data[m]; + m++; + k++; + (*Q).tu++; + } + + // 遍历N中剩余的三元组 + while(n <= N.tu) { + (*Q).data[k] = N.data[n]; + n++; + k++; + (*Q).tu++; + } + + return OK; +} + +/* + * 矩阵减法 + * + * Q = M - N。 + */ +Status SubSMatrix(TSMatrix M, TSMatrix N, TSMatrix* Q) { + int m, n, k; + + if(M.mu != N.mu || M.nu != N.nu) { + printf("两矩阵的行数、列数不满足相减条件!!\n"); + return ERROR; + } + + // 初始化Q + (*Q).mu = M.mu; + (*Q).nu = M.nu; + (*Q).tu = 0; + + m = n = k = 1; + + // 依次遍历M与N的三元组 + while(m <= M.tu && n <= N.tu) { + // M中的三元组行下标较小 + if(M.data[m].i < N.data[n].i) { + (*Q).data[k] = M.data[m]; + m++; + + // N中的三元组行下标较小 + } else if(M.data[m].i > N.data[n].i) { + (*Q).data[k].i = N.data[n].i; + (*Q).data[k].j = N.data[n].j; + (*Q).data[k].e = -N.data[n].e; // 由于是相减,所以要对元素值取相反数 + n++; + + // M与N中的三元组行下标一致,需要进一步比较列坐标 + } else { + // M中的三元组列下标较小 + if(M.data[m].j < N.data[n].j) { + (*Q).data[k] = M.data[m]; + m++; + + // N中的三元组列下标较小 + } else if(M.data[m].j > N.data[n].j) { + (*Q).data[k].i = N.data[n].i; + (*Q).data[k].j = N.data[n].j; + (*Q).data[k].e = -N.data[n].e; // 由于是相减,所以要对元素值取相反数 + n++; + + // M与N中的三元组列下标一致,需要进行减法运算 + } else { + // 值已经减为0的话,不需要存储该元素 + if((M.data[m].e - N.data[n].e) == 0) { + m++; + n++; + continue; + } else { + (*Q).data[k].i = M.data[m].i; + (*Q).data[k].j = M.data[m].j; + (*Q).data[k].e = M.data[m].e - N.data[n].e; + m++; + n++; + } + } + } + + k++; + (*Q).tu++; + } + + // 遍历M中剩余的三元组 + while(m <= M.tu) { + (*Q).data[k] = M.data[m]; + m++; + k++; + (*Q).tu++; + } + + // 遍历N中剩余的三元组 + while(n <= N.tu) { + (*Q).data[k].i = N.data[n].i; + (*Q).data[k].j = N.data[n].j; + (*Q).data[k].e = -N.data[n].e; + n++; + k++; + (*Q).tu++; + } + + return OK; +} + +/* + * 矩阵乘法 + * + * Q = M * N,这里实现的是传统矩阵乘法。 + */ +Status MultSMatrix(TSMatrix M, TSMatrix N, TSMatrix* Q) { + int m, n, i, j, k; + ElemType c, c1, c2; + + // M的列数需要等于N的行数 + if(M.nu != N.mu) { + printf("两矩阵的行数、列数不满足相乘条件!!\n"); + return ERROR; + } + + // 初始化Q + (*Q).mu = M.mu; + (*Q).nu = N.nu; + (*Q).tu = 0; + + // 如果存在零矩阵 + if(M.tu * N.tu == 0) { + return OK; + } + + // 遍历矩阵M的行 + for(i = 1; i <= M.mu; i++) { + // 遍历矩阵N的列 + for(j = 1; j <= N.nu; j++) { + c = 0; + for(k = 1; k <= M.nu; k++) { + // 记录M[i][k]的值 + c1 = 0; + // 依次寻找位于指定位置的M三元组 + for(m = 1; m <= M.tu; m++) { + if(M.data[m].i == i && M.data[m].j == k) { + c1 = M.data[m].e; + break; + } + } + + // 记录N[k][j]的值 + c2 = 0; + //依次寻找位于指定位置的N三元组 + for(n = 1; n <= N.tu; n++) { + if(N.data[n].i == k && N.data[n].j == j) { + c2 = N.data[n].e; + break; + } + } + + // 计算Q[i][j]的值 + if(c1 && c2) { + c += c1 * c2; + } + } + + // 如果计算结果不为0,则进行存储 + if(c != 0) { + (*Q).tu++; + (*Q).data[(*Q).tu].i = i; + (*Q).data[(*Q).tu].j = j; + (*Q).data[(*Q).tu].e = c; + } + } + } + + return OK; +} + +/* + * ████████ 算法5.1 ████████ + * + * 矩阵转置 + */ +Status TransposeSMatrix(TSMatrix M, TSMatrix* T) { + int p, q, col; + + (*T).mu = M.nu; + (*T).nu = M.mu; + (*T).tu = M.tu; + + if((*T).tu != 0) { + q = 1; // q用于T中非零元的计数 + + // col代表M的列,T的行 + for(col = 1; col <= M.nu; ++col) { + // 在M中查找第j列的元素,依次将其转置到T中 + for(p = 1; p <= M.tu; ++p) { + if(M.data[p].j == col) { + (*T).data[q].i = M.data[p].j; // M的列变为T的行 + (*T).data[q].j = M.data[p].i; // M的行变为T的列 + (*T).data[q].e = M.data[p].e; // 每个三元组值不变 + ++q; + } + } + } + } + + return OK; +} + +/* + * ████████ 算法5.2 ████████ + * + * 矩阵快速转置 + */ +Status FastTransposeSMatrix(TSMatrix M, TSMatrix* T) { + int col, t, p, q; + int* num; // num[col] 表示M第col列中非零元的个数 + int* copt; // copt[col]表示M第col列第一个非零元在转置后矩阵中的位置 + + (*T).mu = M.nu; + (*T).nu = M.mu; + (*T).tu = M.tu; + + // 提前返回 + if((*T).tu == 0) { + return ERROR; + } + + num = (int*) malloc(M.nu * sizeof(int)); + copt = (int*) malloc(M.nu * sizeof(int)); + + // 初始化数组num + for(col = 1; col <= M.nu; ++col) { + num[col] = 0; + } + + // 统计M中的非零元,统计每列非零元的个数 + for(t = 1; t <= M.tu; ++t) { + num[M.data[t].j]++; + } + + // 第1列第1个非零元总是位于转置后矩阵中的首位 + copt[1] = 1; + // 计算各列第1个非零元在转置矩阵中的位置 + for(col = 2; col <= M.nu; ++col) { + copt[col] = copt[col - 1] + num[col - 1]; + } + + // 依次扫描M中的三元组 + for(p = 1; p <= M.tu; ++p) { + col = M.data[p].j; // 计算当前非零元所处的列 + q = copt[col]; // 计算当前非零元在转置矩阵中的位置 + (*T).data[q].i = M.data[p].j; + (*T).data[q].j = M.data[p].i; + (*T).data[q].e = M.data[p].e; + ++copt[col]; // 再遇到此列元素时,其在转置矩阵中的位置应当增一(该步骤很重要) + } + + return OK; +} + +/* + * 输出矩阵 + */ +void PrintSMatrix(TSMatrix M) { + int r, c; + int k = 1; + + for(r = 1; r <= M.mu; r++) { + for(c = 1; c <= M.nu; c++) { + if(r == M.data[k].i && c == M.data[k].j) { + printf("%3d ", M.data[k].e); + k++; + } else { + printf("%3d ", 0); + } + } + printf("\n"); + } +} diff --git a/CLion/ExerciseBook/05.21/TSMatrix.h b/CLion/ExerciseBook/05.21/TSMatrix.h new file mode 100644 index 0000000..81cbd8f --- /dev/null +++ b/CLion/ExerciseBook/05.21/TSMatrix.h @@ -0,0 +1,104 @@ +/*======================= + * 三元组顺序表(稀疏矩阵) + * + * 包含算法: 5.1、5.2 + ========================*/ + +#ifndef TSMATRIX_H +#define TSMATRIX_H + +#include +#include // 提供 malloc 原型 +#include // 提供 strstr 原型 +#include "Status.h" //**▲01 绪论**// + +/* 宏定义 */ +#define MAXSIZE 12500 // 非零元数量的最大值 + +/* 三元组稀疏矩阵元素类型 */ +typedef int ElemType; + +/* 三元组类型定义,主要用来存储非零元 */ +typedef struct { + int i, j; // 该三元组非零元的行下标和列下标 + ElemType e; +} Triple; + +/* 三元组稀疏矩阵类型定义 */ +typedef struct { + Triple data[MAXSIZE + 1]; // 非零元三元组表,data[0]未用 + int mu, nu, tu; // 矩阵的行数、列数和非零元个数 +} TSMatrix; + + +/* + * 创建稀疏矩阵M + * + * + *【备注】 + * + * 教材中默认从控制台读取数据。 + * 这里为了方便测试,避免每次运行都手动输入数据, + * 因而允许选择从预设的文件path中读取测试数据。 + * + * 如果需要从控制台读取数据,则path为NULL或者为空串, + * 如果需要从文件中读取数据,则需要在path中填写文件名信息。 + */ +Status CreateSMatrix(TSMatrix* M, char* path); + +/* + * 销毁稀疏矩阵 + * + *【注】 + * 三元组顺序表的结构无法销毁。 + */ +Status DestroySMatrix(TSMatrix* M); + +/* + * 矩阵复制 + * + * 创建一个新矩阵T,该矩阵包含了从矩阵M中包含的数据。 + */ +Status CopySMatrix(TSMatrix M, TSMatrix* T); + +/* + * 矩阵加法 + * + * Q = M + N。 + */ +Status AddSMatrix(TSMatrix M, TSMatrix N, TSMatrix* Q); + +/* + * 矩阵减法 + * + * Q = M - N。 + */ +Status SubSMatrix(TSMatrix M, TSMatrix N, TSMatrix* Q); + +/* + * 矩阵乘法 + * + * Q = M * N,这里实现的是传统矩阵乘法。 + */ +Status MultSMatrix(TSMatrix M, TSMatrix N, TSMatrix* Q); + +/* + * ████████ 算法5.1 ████████ + * + * 矩阵转置 + */ +Status TransposeSMatrix(TSMatrix M, TSMatrix* T); + +/* + * ████████ 算法5.2 ████████ + * + * 矩阵快速转置 + */ +Status FastTransposeSMatrix(TSMatrix M, TSMatrix* T); + +/* + * 输出矩阵 + */ +void PrintSMatrix(TSMatrix M); + +#endif diff --git a/CLion/ExerciseBook/05.21/TestData_A.txt b/CLion/ExerciseBook/05.21/TestData_A.txt new file mode 100644 index 0000000..5d3cb45 --- /dev/null +++ b/CLion/ExerciseBook/05.21/TestData_A.txt @@ -0,0 +1,4 @@ +行数:5 +列数:5 +非零元个数:10 +三元组:(1,2,1),(1,4,5),(2,3,-3),(2,5,2),(3,1,2),(3,2,3),(3,3,4),(4,4,2),(5,1,3),(5,2,-1) \ No newline at end of file diff --git a/CLion/ExerciseBook/05.21/TestData_B.txt b/CLion/ExerciseBook/05.21/TestData_B.txt new file mode 100644 index 0000000..d567717 --- /dev/null +++ b/CLion/ExerciseBook/05.21/TestData_B.txt @@ -0,0 +1,4 @@ +行数:5 +列数:5 +非零元个数:8 +三元组:(1,1,-3)(1,3,2)(2,4,-1)(3,2,4)(4,1,6)(4,5,5)(5,1,3)(5,3,2) \ No newline at end of file diff --git a/CLion/ExerciseBook/05.22/05.22.c b/CLion/ExerciseBook/05.22/05.22.c new file mode 100644 index 0000000..a21ec49 --- /dev/null +++ b/CLion/ExerciseBook/05.22/05.22.c @@ -0,0 +1,106 @@ +#include +#include "Status.h" //**▲01 绪论**// +#include "TSMatrix.h" //**▲05 数组和广义表**// + +/* + * 稀疏矩阵加法:AddSMatrix + * + *【注】 + * 计算结果需要保存到原矩阵A中 + */ +Status Algo_5_22(TSMatrix* A, TSMatrix B); + + +int main(int argc, char* argv[]) { + TSMatrix A, B; + + printf("█ 创建两个稀疏矩阵 A、B ...\n"); + CreateSMatrix(&A, "TestData_A.txt"); + CreateSMatrix(&B, "TestData_B.txt"); + printf("█ A = \n"); + PrintSMatrix(A); + printf("█ B = \n"); + PrintSMatrix(B); + + // 矩阵相加 + Algo_5_22(&A, B); + + printf("█ A = A + B = \n"); + PrintSMatrix(A); + + return 0; +} + + +/* + * 稀疏矩阵加法:AddSMatrix + * + *【注】 + * 计算结果需要保存到原矩阵A中 + */ +Status Algo_5_22(TSMatrix* A, TSMatrix B) { + int m, n, k; + + if((*A).mu != B.mu || (*A).nu != B.nu) { + printf("两矩阵的行数、列数不满足相加条件!!\n"); + return ERROR; + } + + // A中元素向后移动,移动长度为B的元素个数 + for(k = (*A).tu; k > 0; k--) { + (*A).data[k + B.tu] = (*A).data[k]; + } + + m = B.tu + 1; // 遍历A的起点 + n = 1; // 遍历B的起点 + k = 0; // 指向计算结果的游标 + + // 依次遍历A与B的三元组 + while(m <= (*A).tu + B.tu && n <= B.tu) { + // A中的三元组行下标较小 + if((*A).data[m].i < B.data[n].i) { + (*A).data[++k] = (*A).data[m++]; + + // B中的三元组行下标较小 + } else if((*A).data[m].i > B.data[n].i) { + (*A).data[++k] = B.data[n++]; + + // A与B中的三元组行下标一致,需要进一步比较列坐标 + } else { + // A中的三元组列下标较小 + if((*A).data[m].j < B.data[n].j) { + (*A).data[++k] = (*A).data[m++]; + + // B中的三元组列下标较小 + } else if((*A).data[m].j > B.data[n].j) { + (*A).data[++k] = B.data[n++]; + + // A与B中的三元组列下标一致,需要进行加法运算 + } else { + // 值不为0时,需要存储该元素 + if(((*A).data[m].e + B.data[n].e) != 0) { + k++; + (*A).data[k].i = (*A).data[m].i; + (*A).data[k].j = (*A).data[m].j; + (*A).data[k].e = (*A).data[m].e + B.data[n].e; + } + m++; + n++; + } + } + } + + // 遍历A中剩余的三元组 + while(m <= (*A).tu + B.tu) { + (*A).data[++k] = (*A).data[m++]; + } + + // 遍历B中剩余的三元组 + while(n <= B.tu) { + (*A).data[++k] = B.data[n++]; + } + + (*A).tu = k; + + return OK; +} diff --git a/CLion/ExerciseBook/05.22/CMakeLists.txt b/CLion/ExerciseBook/05.22/CMakeLists.txt new file mode 100644 index 0000000..4ea7f1d --- /dev/null +++ b/CLion/ExerciseBook/05.22/CMakeLists.txt @@ -0,0 +1,13 @@ +# 包含公共库 +include_directories(${CMAKE_SOURCE_DIR}/Status) + +# 生成可执行文件 +add_executable(05.22 TSMatrix.h TSMatrix.c 05.22.c) +# 链接公共库 +target_link_libraries(05.22 Scanf_lib) + + +# 记录要拷贝到*.exe目录下的资源文件 +file(GLOB TestData TestData*.txt) +# 将资源文件拷贝到*.exe目录下,不然无法加载 +file(COPY ${TestData} DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) diff --git a/CLion/ExerciseBook/05.22/TSMatrix.c b/CLion/ExerciseBook/05.22/TSMatrix.c new file mode 100644 index 0000000..7bbf239 --- /dev/null +++ b/CLion/ExerciseBook/05.22/TSMatrix.c @@ -0,0 +1,433 @@ +/*======================= + * 三元组顺序表(稀疏矩阵) + * + * 包含算法: 5.1、5.2 + ========================*/ + +#include "TSMatrix.h" //**▲05 数组和广义表**// + +/* + * 创建稀疏矩阵M + * + * + *【备注】 + * + * 教材中默认从控制台读取数据。 + * 这里为了方便测试,避免每次运行都手动输入数据, + * 因而允许选择从预设的文件path中读取测试数据。 + * + * 如果需要从控制台读取数据,则path为NULL或者为空串, + * 如果需要从文件中读取数据,则需要在path中填写文件名信息。 + */ +Status CreateSMatrix(TSMatrix* M, char* path) { + int k; + FILE* fp; + int readFromConsole; // 是否从控制台读取数据 + + // 如果没有文件路径信息,则从控制台读取输入 + readFromConsole = path == NULL || strcmp(path, "") == 0; + + // 如果没有文件路径信息,则从控制台读取输入 + if(readFromConsole) { + printf("请输入行数:"); + scanf("%d", &((*M).mu)); + printf("请输入列数:"); + scanf("%d", &((*M).nu)); + printf("请输入非零元素个数:"); + scanf("%d", &((*M).tu)); + printf("请输入%d个三元组信息\n", (*M).tu); + for(k = 1; k <= (*M).tu; k++) { + printf("第%2d组:", k); + scanf("%d%d%d", &((*M).data[k].i), &((*M).data[k].j), &((*M).data[k].e)); + } + } else { + fp = fopen(path, "r"); + + ReadData(fp, "%d%d%d", &((*M).mu), &((*M).nu), &((*M).tu)); + + for(k = 1; k <= (*M).tu; k++) { + ReadData(fp, "%d%d%d", &((*M).data[k].i), &((*M).data[k].j), &((*M).data[k].e)); + } + + fclose(fp); + } + + return OK; +} + +/* + * 销毁稀疏矩阵 + * + *【注】 + * 三元组顺序表的结构无法销毁。 + */ +Status DestroySMatrix(TSMatrix* M) { + if(M == NULL) { + return ERROR; + } + + (*M).mu = 0; + (*M).nu = 0; + (*M).tu = 0; + + return OK; +} + +/* + * 矩阵复制 + * + * 创建一个新矩阵T,该矩阵包含了从矩阵M中包含的数据。 + */ +Status CopySMatrix(TSMatrix M, TSMatrix* T) { + (*T) = M; // 结构体之间可以直接复制,即使内部包含数组也可以 + + return OK; +} + +/* + * 矩阵加法 + * + * Q = M + N。 + */ +Status AddSMatrix(TSMatrix M, TSMatrix N, TSMatrix* Q) { + int m, n, k; + + if(M.mu != N.mu || M.nu != N.nu) { + printf("两矩阵的行数、列数不满足相加条件!!\n"); + return ERROR; + } + + // 初始化Q + (*Q).mu = M.mu; + (*Q).nu = M.nu; + (*Q).tu = 0; + + m = n = k = 1; + + // 依次遍历M与N的三元组 + while(m <= M.tu && n <= N.tu) { + // M中的三元组行下标较小 + if(M.data[m].i < N.data[n].i) { + (*Q).data[k] = M.data[m]; + m++; + + // N中的三元组行下标较小 + } else if(M.data[m].i > N.data[n].i) { + (*Q).data[k] = N.data[n]; + n++; + + // M与N中的三元组行下标一致,需要进一步比较列坐标 + } else { + // M中的三元组列下标较小 + if(M.data[m].j < N.data[n].j) { + (*Q).data[k] = M.data[m]; + m++; + + // N中的三元组列下标较小 + } else if(M.data[m].j > N.data[n].j) { + (*Q).data[k] = N.data[n]; + n++; + + // M与N中的三元组列下标一致,需要进行加法运算 + } else { + // 值已经加为0的话,不需要存储该元素 + if((M.data[m].e + N.data[n].e) == 0) { + m++; + n++; + continue; + } else { + (*Q).data[k].i = M.data[m].i; + (*Q).data[k].j = M.data[m].j; + (*Q).data[k].e = M.data[m].e + N.data[n].e; + m++; + n++; + } + } + } + + k++; + (*Q).tu++; + } + + // 遍历M中剩余的三元组 + while(m <= M.tu) { + (*Q).data[k] = M.data[m]; + m++; + k++; + (*Q).tu++; + } + + // 遍历N中剩余的三元组 + while(n <= N.tu) { + (*Q).data[k] = N.data[n]; + n++; + k++; + (*Q).tu++; + } + + return OK; +} + +/* + * 矩阵减法 + * + * Q = M - N。 + */ +Status SubSMatrix(TSMatrix M, TSMatrix N, TSMatrix* Q) { + int m, n, k; + + if(M.mu != N.mu || M.nu != N.nu) { + printf("两矩阵的行数、列数不满足相减条件!!\n"); + return ERROR; + } + + // 初始化Q + (*Q).mu = M.mu; + (*Q).nu = M.nu; + (*Q).tu = 0; + + m = n = k = 1; + + // 依次遍历M与N的三元组 + while(m <= M.tu && n <= N.tu) { + // M中的三元组行下标较小 + if(M.data[m].i < N.data[n].i) { + (*Q).data[k] = M.data[m]; + m++; + + // N中的三元组行下标较小 + } else if(M.data[m].i > N.data[n].i) { + (*Q).data[k].i = N.data[n].i; + (*Q).data[k].j = N.data[n].j; + (*Q).data[k].e = -N.data[n].e; // 由于是相减,所以要对元素值取相反数 + n++; + + // M与N中的三元组行下标一致,需要进一步比较列坐标 + } else { + // M中的三元组列下标较小 + if(M.data[m].j < N.data[n].j) { + (*Q).data[k] = M.data[m]; + m++; + + // N中的三元组列下标较小 + } else if(M.data[m].j > N.data[n].j) { + (*Q).data[k].i = N.data[n].i; + (*Q).data[k].j = N.data[n].j; + (*Q).data[k].e = -N.data[n].e; // 由于是相减,所以要对元素值取相反数 + n++; + + // M与N中的三元组列下标一致,需要进行减法运算 + } else { + // 值已经减为0的话,不需要存储该元素 + if((M.data[m].e - N.data[n].e) == 0) { + m++; + n++; + continue; + } else { + (*Q).data[k].i = M.data[m].i; + (*Q).data[k].j = M.data[m].j; + (*Q).data[k].e = M.data[m].e - N.data[n].e; + m++; + n++; + } + } + } + + k++; + (*Q).tu++; + } + + // 遍历M中剩余的三元组 + while(m <= M.tu) { + (*Q).data[k] = M.data[m]; + m++; + k++; + (*Q).tu++; + } + + // 遍历N中剩余的三元组 + while(n <= N.tu) { + (*Q).data[k].i = N.data[n].i; + (*Q).data[k].j = N.data[n].j; + (*Q).data[k].e = -N.data[n].e; + n++; + k++; + (*Q).tu++; + } + + return OK; +} + +/* + * 矩阵乘法 + * + * Q = M * N,这里实现的是传统矩阵乘法。 + */ +Status MultSMatrix(TSMatrix M, TSMatrix N, TSMatrix* Q) { + int m, n, i, j, k; + ElemType c, c1, c2; + + // M的列数需要等于N的行数 + if(M.nu != N.mu) { + printf("两矩阵的行数、列数不满足相乘条件!!\n"); + return ERROR; + } + + // 初始化Q + (*Q).mu = M.mu; + (*Q).nu = N.nu; + (*Q).tu = 0; + + // 如果存在零矩阵 + if(M.tu * N.tu == 0) { + return OK; + } + + // 遍历矩阵M的行 + for(i = 1; i <= M.mu; i++) { + // 遍历矩阵N的列 + for(j = 1; j <= N.nu; j++) { + c = 0; + for(k = 1; k <= M.nu; k++) { + // 记录M[i][k]的值 + c1 = 0; + // 依次寻找位于指定位置的M三元组 + for(m = 1; m <= M.tu; m++) { + if(M.data[m].i == i && M.data[m].j == k) { + c1 = M.data[m].e; + break; + } + } + + // 记录N[k][j]的值 + c2 = 0; + //依次寻找位于指定位置的N三元组 + for(n = 1; n <= N.tu; n++) { + if(N.data[n].i == k && N.data[n].j == j) { + c2 = N.data[n].e; + break; + } + } + + // 计算Q[i][j]的值 + if(c1 && c2) { + c += c1 * c2; + } + } + + // 如果计算结果不为0,则进行存储 + if(c != 0) { + (*Q).tu++; + (*Q).data[(*Q).tu].i = i; + (*Q).data[(*Q).tu].j = j; + (*Q).data[(*Q).tu].e = c; + } + } + } + + return OK; +} + +/* + * ████████ 算法5.1 ████████ + * + * 矩阵转置 + */ +Status TransposeSMatrix(TSMatrix M, TSMatrix* T) { + int p, q, col; + + (*T).mu = M.nu; + (*T).nu = M.mu; + (*T).tu = M.tu; + + if((*T).tu != 0) { + q = 1; // q用于T中非零元的计数 + + // col代表M的列,T的行 + for(col = 1; col <= M.nu; ++col) { + // 在M中查找第j列的元素,依次将其转置到T中 + for(p = 1; p <= M.tu; ++p) { + if(M.data[p].j == col) { + (*T).data[q].i = M.data[p].j; // M的列变为T的行 + (*T).data[q].j = M.data[p].i; // M的行变为T的列 + (*T).data[q].e = M.data[p].e; // 每个三元组值不变 + ++q; + } + } + } + } + + return OK; +} + +/* + * ████████ 算法5.2 ████████ + * + * 矩阵快速转置 + */ +Status FastTransposeSMatrix(TSMatrix M, TSMatrix* T) { + int col, t, p, q; + int* num; // num[col] 表示M第col列中非零元的个数 + int* copt; // copt[col]表示M第col列第一个非零元在转置后矩阵中的位置 + + (*T).mu = M.nu; + (*T).nu = M.mu; + (*T).tu = M.tu; + + // 提前返回 + if((*T).tu == 0) { + return ERROR; + } + + num = (int*) malloc(M.nu * sizeof(int)); + copt = (int*) malloc(M.nu * sizeof(int)); + + // 初始化数组num + for(col = 1; col <= M.nu; ++col) { + num[col] = 0; + } + + // 统计M中的非零元,统计每列非零元的个数 + for(t = 1; t <= M.tu; ++t) { + num[M.data[t].j]++; + } + + // 第1列第1个非零元总是位于转置后矩阵中的首位 + copt[1] = 1; + // 计算各列第1个非零元在转置矩阵中的位置 + for(col = 2; col <= M.nu; ++col) { + copt[col] = copt[col - 1] + num[col - 1]; + } + + // 依次扫描M中的三元组 + for(p = 1; p <= M.tu; ++p) { + col = M.data[p].j; // 计算当前非零元所处的列 + q = copt[col]; // 计算当前非零元在转置矩阵中的位置 + (*T).data[q].i = M.data[p].j; + (*T).data[q].j = M.data[p].i; + (*T).data[q].e = M.data[p].e; + ++copt[col]; // 再遇到此列元素时,其在转置矩阵中的位置应当增一(该步骤很重要) + } + + return OK; +} + +/* + * 输出矩阵 + */ +void PrintSMatrix(TSMatrix M) { + int r, c; + int k = 1; + + for(r = 1; r <= M.mu; r++) { + for(c = 1; c <= M.nu; c++) { + if(r == M.data[k].i && c == M.data[k].j) { + printf("%3d ", M.data[k].e); + k++; + } else { + printf("%3d ", 0); + } + } + printf("\n"); + } +} diff --git a/CLion/ExerciseBook/05.22/TSMatrix.h b/CLion/ExerciseBook/05.22/TSMatrix.h new file mode 100644 index 0000000..81cbd8f --- /dev/null +++ b/CLion/ExerciseBook/05.22/TSMatrix.h @@ -0,0 +1,104 @@ +/*======================= + * 三元组顺序表(稀疏矩阵) + * + * 包含算法: 5.1、5.2 + ========================*/ + +#ifndef TSMATRIX_H +#define TSMATRIX_H + +#include +#include // 提供 malloc 原型 +#include // 提供 strstr 原型 +#include "Status.h" //**▲01 绪论**// + +/* 宏定义 */ +#define MAXSIZE 12500 // 非零元数量的最大值 + +/* 三元组稀疏矩阵元素类型 */ +typedef int ElemType; + +/* 三元组类型定义,主要用来存储非零元 */ +typedef struct { + int i, j; // 该三元组非零元的行下标和列下标 + ElemType e; +} Triple; + +/* 三元组稀疏矩阵类型定义 */ +typedef struct { + Triple data[MAXSIZE + 1]; // 非零元三元组表,data[0]未用 + int mu, nu, tu; // 矩阵的行数、列数和非零元个数 +} TSMatrix; + + +/* + * 创建稀疏矩阵M + * + * + *【备注】 + * + * 教材中默认从控制台读取数据。 + * 这里为了方便测试,避免每次运行都手动输入数据, + * 因而允许选择从预设的文件path中读取测试数据。 + * + * 如果需要从控制台读取数据,则path为NULL或者为空串, + * 如果需要从文件中读取数据,则需要在path中填写文件名信息。 + */ +Status CreateSMatrix(TSMatrix* M, char* path); + +/* + * 销毁稀疏矩阵 + * + *【注】 + * 三元组顺序表的结构无法销毁。 + */ +Status DestroySMatrix(TSMatrix* M); + +/* + * 矩阵复制 + * + * 创建一个新矩阵T,该矩阵包含了从矩阵M中包含的数据。 + */ +Status CopySMatrix(TSMatrix M, TSMatrix* T); + +/* + * 矩阵加法 + * + * Q = M + N。 + */ +Status AddSMatrix(TSMatrix M, TSMatrix N, TSMatrix* Q); + +/* + * 矩阵减法 + * + * Q = M - N。 + */ +Status SubSMatrix(TSMatrix M, TSMatrix N, TSMatrix* Q); + +/* + * 矩阵乘法 + * + * Q = M * N,这里实现的是传统矩阵乘法。 + */ +Status MultSMatrix(TSMatrix M, TSMatrix N, TSMatrix* Q); + +/* + * ████████ 算法5.1 ████████ + * + * 矩阵转置 + */ +Status TransposeSMatrix(TSMatrix M, TSMatrix* T); + +/* + * ████████ 算法5.2 ████████ + * + * 矩阵快速转置 + */ +Status FastTransposeSMatrix(TSMatrix M, TSMatrix* T); + +/* + * 输出矩阵 + */ +void PrintSMatrix(TSMatrix M); + +#endif diff --git a/CLion/ExerciseBook/05.22/TestData_A.txt b/CLion/ExerciseBook/05.22/TestData_A.txt new file mode 100644 index 0000000..5d3cb45 --- /dev/null +++ b/CLion/ExerciseBook/05.22/TestData_A.txt @@ -0,0 +1,4 @@ +行数:5 +列数:5 +非零元个数:10 +三元组:(1,2,1),(1,4,5),(2,3,-3),(2,5,2),(3,1,2),(3,2,3),(3,3,4),(4,4,2),(5,1,3),(5,2,-1) \ No newline at end of file diff --git a/CLion/ExerciseBook/05.22/TestData_B.txt b/CLion/ExerciseBook/05.22/TestData_B.txt new file mode 100644 index 0000000..d567717 --- /dev/null +++ b/CLion/ExerciseBook/05.22/TestData_B.txt @@ -0,0 +1,4 @@ +行数:5 +列数:5 +非零元个数:8 +三元组:(1,1,-3)(1,3,2)(2,4,-1)(3,2,4)(4,1,6)(4,5,5)(5,1,3)(5,3,2) \ No newline at end of file diff --git a/CLion/ExerciseBook/05.23/05.23.c b/CLion/ExerciseBook/05.23/05.23.c new file mode 100644 index 0000000..93b0b15 --- /dev/null +++ b/CLion/ExerciseBook/05.23/05.23.c @@ -0,0 +1,52 @@ +#include +#include "Status.h" //**▲01 绪论**// +#include "RLSMatrix.h" //**▲05 数组和广义表**// + +/* + * 获取矩阵中第i行第j列的元素,并将其存储到e中 + */ +Status Algo_5_23(RLSMatrix M, int i, int j, int* e); + + +int main(int argc, char* argv[]) { + RLSMatrix M; + int e; + + printf("█ 创建个稀疏矩阵 M ...\n"); + CreateSMatrix(&M, "TestData_M.txt"); + printf("M = \n"); + PrintSMatrix(M); + + Algo_5_23(M, 2, 3, &e); + printf("█ 第 %d 行 %d 列的元素为 %d\n", 2, 3, e); + + return 0; +} + + +/* + * 获取矩阵中第i行第j列的元素,并将其存储到e中 + */ +Status Algo_5_23(RLSMatrix M, int i, int j, int* e) { + int begin, end, k; + + if(i < 1 || i > M.mu || j < 1 || j > M.nu) { + return ERROR; + } + + // 获取第i行中首个非零元在三元组表中的位置 + begin = M.rpos[i]; + end = (i == M.mu ? M.tu : M.rpos[i + 1] - 1); + + *e = 0; // 默认为0 + + for(k = begin; k <= end; k++) { + // 找到对应列下标的元素 + if(M.data[k].j == j) { + *e = M.data[k].e; + break; + } + } + + return OK; +} diff --git a/CLion/ExerciseBook/05.23/CMakeLists.txt b/CLion/ExerciseBook/05.23/CMakeLists.txt new file mode 100644 index 0000000..fc406d4 --- /dev/null +++ b/CLion/ExerciseBook/05.23/CMakeLists.txt @@ -0,0 +1,13 @@ +# 包含公共库 +include_directories(${CMAKE_SOURCE_DIR}/Status) + +# 生成可执行文件 +add_executable(05.23 RLSMatrix.h RLSMatrix.c 05.23.c) +# 链接公共库 +target_link_libraries(05.23 Scanf_lib) + + +# 记录要拷贝到*.exe目录下的资源文件 +file(GLOB TestData TestData*.txt) +# 将资源文件拷贝到*.exe目录下,不然无法加载 +file(COPY ${TestData} DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) diff --git a/CLion/ExerciseBook/05.23/RLSMatrix.c b/CLion/ExerciseBook/05.23/RLSMatrix.c new file mode 100644 index 0000000..9a9870e --- /dev/null +++ b/CLion/ExerciseBook/05.23/RLSMatrix.c @@ -0,0 +1,515 @@ +/*============================= + * 行逻辑链接的顺序表(稀疏矩阵) + * + * 包含算法: 5.3 + ==============================*/ + +#include "RLSMatrix.h" //**▲05 数组和广义表**// + +/* + * 创建稀疏矩阵M + * + * + *【备注】 + * + * 教材中默认从控制台读取数据。 + * 这里为了方便测试,避免每次运行都手动输入数据, + * 因而允许选择从预设的文件path中读取测试数据。 + * + * 如果需要从控制台读取数据,则path为NULL或者为空串, + * 如果需要从文件中读取数据,则需要在path中填写文件名信息。 + */ +Status CreateSMatrix(RLSMatrix* M, char* path) { + int k; + FILE* fp; + int readFromConsole; // 是否从控制台读取数据 + + // 如果没有文件路径信息,则从控制台读取输入 + readFromConsole = path == NULL || strcmp(path, "") == 0; + + // 如果没有文件路径信息,则从控制台读取输入 + if(readFromConsole) { + printf("请输入行数:"); + scanf("%d", &((*M).mu)); + printf("请输入列数:"); + scanf("%d", &((*M).nu)); + printf("请输入非零元素个数:"); + scanf("%d", &((*M).tu)); + printf("请输入%d个三元组信息\n", (*M).tu); + for(k = 1; k <= (*M).tu; k++) { + printf("第%2d组:", k); + scanf("%d%d%d", &((*M).data[k].i), &((*M).data[k].j), &((*M).data[k].e)); + } + } else { + fp = fopen(path, "r"); + + ReadData(fp, "%d%d%d", &((*M).mu), &((*M).nu), &((*M).tu)); + + for(k = 1; k <= (*M).tu; k++) { + ReadData(fp, "%d%d%d", &((*M).data[k].i), &((*M).data[k].j), &((*M).data[k].e)); + } + + fclose(fp); + } + + // 为rpos数组赋值 + AssignRpos(M); + + return OK; +} + +/* + * 销毁稀疏矩阵 + * + *【注】 + * 行逻辑链接的顺序表结构无法销毁。 + */ +Status DestroySMatrix(RLSMatrix* M) { + int i; + + if(M == NULL) { + return ERROR; + } + + M->mu = 0; + M->nu = 0; + M->tu = 0; + + for(i = 0; i <= MAXRC; ++i) { + M->rpos[i] = 0; + } + + return OK; +} + +/* + * 矩阵复制 + * + * 创建一个新矩阵T,该矩阵包含了从矩阵M中包含的数据。 + */ +Status CopySMatrix(RLSMatrix M, RLSMatrix* T) { + (*T) = M; // 结构体之间可以直接复制,即使内部包含数组也可以 + + return OK; +} + +/* + * 矩阵加法 + * + * Q = M + N。 + */ +Status AddSMatrix(RLSMatrix M, RLSMatrix N, RLSMatrix* Q) { + int m, n, k; + + if(M.mu != N.mu || M.nu != N.nu) { + printf("两矩阵的行数、列数不满足相加条件!!\n"); + return ERROR; + } + + // 初始化Q的行列信息 + (*Q).mu = M.mu; + (*Q).nu = M.nu; + (*Q).tu = 0; + + m = n = k = 1; + + // 依次遍历M与N的三元组 + while(m <= M.tu && n <= N.tu) { + // M中的三元组行下标较小 + if(M.data[m].i < N.data[n].i) { + (*Q).data[k] = M.data[m]; + m++; + + // N中的三元组行下标较小 + } else if(M.data[m].i > N.data[n].i) { + (*Q).data[k] = N.data[n]; + n++; + + // M与N中的三元组行下标一致,需要进一步比较列坐标 + } else { + // M中的三元组列下标较小 + if(M.data[m].j < N.data[n].j) { + (*Q).data[k] = M.data[m]; + m++; + + // N中的三元组列下标较小 + } else if(M.data[m].j > N.data[n].j) { + (*Q).data[k] = N.data[n]; + n++; + + // M与N中的三元组列下标一致,需要进行加法运算 + } else { + // 值已经加为0的话,不需要存储该元素 + if((M.data[m].e + N.data[n].e) == 0) { + m++; + n++; + continue; + } else { + (*Q).data[k].i = M.data[m].i; + (*Q).data[k].j = M.data[m].j; + (*Q).data[k].e = M.data[m].e + N.data[n].e; + m++; + n++; + } + } + } + + k++; + (*Q).tu++; + } + + // 遍历M中剩余的三元组 + while(m <= M.tu) { + (*Q).data[k] = M.data[m]; + m++; + k++; + (*Q).tu++; + } + + // 遍历N中剩余的三元组 + while(n <= N.tu) { + (*Q).data[k] = N.data[n]; + n++; + k++; + (*Q).tu++; + } + + // 为rpos数组赋值 + AssignRpos(Q); + + return OK; +} + +/* + * 矩阵减法 + * + * Q = M - N。 + */ +Status SubSMatrix(RLSMatrix M, RLSMatrix N, RLSMatrix* Q) { + int m, n, k; + + if(M.mu != N.mu || M.nu != N.nu) { + printf("两矩阵的行数、列数不满足相减条件!!\n"); + return ERROR; + } + + // 初始化Q的行列信息 + (*Q).mu = M.mu; + (*Q).nu = M.nu; + (*Q).tu = 0; + + m = n = k = 1; + + // 依次遍历M与N的三元组 + while(m <= M.tu && n <= N.tu) { + // M中的三元组行下标较小 + if(M.data[m].i < N.data[n].i) { + (*Q).data[k] = M.data[m]; + m++; + + // N中的三元组行下标较小 + } else if(M.data[m].i > N.data[n].i) { + (*Q).data[k].i = N.data[n].i; + (*Q).data[k].j = N.data[n].j; + (*Q).data[k].e = -N.data[n].e; // 由于是相减,所以要对元素值取相反数 + n++; + + // M与N中的三元组行下标一致,需要进一步比较列坐标 + } else { + // M中的三元组列下标较小 + if(M.data[m].j < N.data[n].j) { + (*Q).data[k] = M.data[m]; + m++; + + // N中的三元组列下标较小 + } else if(M.data[m].j > N.data[n].j) { + (*Q).data[k].i = N.data[n].i; + (*Q).data[k].j = N.data[n].j; + (*Q).data[k].e = -N.data[n].e; // 由于是相减,所以要对元素值取相反数 + n++; + + // M与N中的三元组列下标一致,需要进行减法运算 + } else { + // 值已经减为0的话,不需要存储该元素 + if((M.data[m].e - N.data[n].e) == 0) { + m++; + n++; + continue; + } else { + (*Q).data[k].i = M.data[m].i; + (*Q).data[k].j = M.data[m].j; + (*Q).data[k].e = M.data[m].e - N.data[n].e; + m++; + n++; + } + } + } + + k++; + (*Q).tu++; + } + + // 遍历M中剩余的三元组 + while(m <= M.tu) { + (*Q).data[k] = M.data[m]; + m++; + k++; + (*Q).tu++; + } + + // 遍历N中剩余的三元组 + while(n <= N.tu) { + (*Q).data[k].i = N.data[n].i; + (*Q).data[k].j = N.data[n].j; + (*Q).data[k].e = -N.data[n].e; + n++; + k++; + (*Q).tu++; + } + + // 为rpos数组赋值 + AssignRpos(Q); + + return OK; +} + +/* + * ████████ 算法5.3 ████████ + * + * 矩阵乘法 + * + * Q = M * N。 + */ +Status MultSMatrix(RLSMatrix M, RLSMatrix N, RLSMatrix* Q) { + int arow, p, tp; + int brow, q, tq; + int ccol; + int* ctemp; // Q中各行元素值累加器,ctemp[0]单元弃用 + int i; + + // M的列数需要等于N的行数 + if(M.nu != N.mu) { + printf("两矩阵的行数、列数不满足相乘条件!!\n"); + return ERROR; + } + + // 初始化Q的行列信息 + (*Q).mu = M.mu; + (*Q).nu = N.nu; + (*Q).tu = 0; + + // 如果存在零矩阵 + if(M.tu * N.tu == 0) { + return OK; + } + + ctemp = (int*) malloc((N.nu + 1) * sizeof(int)); + + // 处理M的每一行 + for(arow = 1; arow <= M.mu; ++arow) { + // 初始化Q中行元素值计数器 + for(i = 0; i <= N.nu; ++i) { + ctemp[i] = 0; + } + + // tp指向M当前行的下一行第一个非零元位置 + if(arow < M.mu) { + tp = M.rpos[arow + 1]; + } else { + tp = M.tu + 1; + } + + // 遍历M中arow行的所有非零元 + for(p = M.rpos[arow]; p < tp; ++p) { + // 获取该非零元在N中的行号 + brow = M.data[p].j; + + // tq指向N当前行的下一行第一个非零元位置 + if(brow < N.mu) { + tq = N.rpos[brow + 1]; + } else { + tq = N.tu + 1; + } + + // 遍历N中brow行的所有非零元 + for(q = N.rpos[brow]; q < tq; ++q) { + // 乘积元素在Q中的列号 + ccol = N.data[q].j; + + // 累加乘积 + ctemp[ccol] += M.data[p].e * N.data[q].e; + } + } + + /* + * 至此,Q中第arow行元素已求出 + */ + + // 遍历计算后的乘积,选取非零元存入Q中 + for(ccol = 1; ccol <= (*Q).nu; ++ccol) { + // 若Q中第arow行ccol列元素不为0 + if(ctemp[ccol]) { + ++(*Q).tu; + + // 非零元个数超出限制 + if((*Q).tu > MAXSIZE) { + return ERROR; + } + + (*Q).data[(*Q).tu].i = arow; + (*Q).data[(*Q).tu].j = ccol; + (*Q).data[(*Q).tu].e = ctemp[ccol]; + } + } + } + + // 为rpos数组赋值 + AssignRpos(Q); + + return OK; +} + +/* + * 矩阵转置 + */ +Status TransposeSMatrix(RLSMatrix M, RLSMatrix* T) { + int p, q, col; + + (*T).mu = M.nu; + (*T).nu = M.mu; + (*T).tu = M.tu; + + if((*T).tu) { + q = 1; // q用于T中非零元的计数 + + // col代表M的列,T的行 + for(col = 1; col <= M.nu; ++col) { + // 在M中查找第j列的元素,依次将其转置到T中 + for(p = 1; p <= M.tu; ++p) { + if(M.data[p].j == col) { + (*T).data[q].i = M.data[p].j; // M的列变为T的行 + (*T).data[q].j = M.data[p].i; // M的行变为T的列 + (*T).data[q].e = M.data[p].e; // 每个三元组值不变 + + ++q; + } + } + } + } + + // 为rpos数组赋值 + AssignRpos(T); + + return OK; +} + +/* + * 矩阵快速转置 + */ +Status FastTransposeSMatrix(RLSMatrix M, RLSMatrix* T) { + int col, t, p, q; + int* num; // num[col] 表示M第col列中非零元的个数 + int* copt; // copt[col]表示M第col列第一个非零元在转置后矩阵中的位置 + + (*T).mu = M.nu; + (*T).nu = M.mu; + (*T).tu = M.tu; + + // 提前返回 + if((*T).tu == 0) { + return ERROR; + } + + num = (int*) malloc(M.nu * sizeof(int)); + copt = (int*) malloc(M.nu * sizeof(int)); + + // 初始化数组num + for(col = 1; col <= M.nu; ++col) { + num[col] = 0; + } + + // 统计M中的非零元,统计每列非零元的个数 + for(t = 1; t <= M.tu; ++t) { + num[M.data[t].j]++; + } + + // 第1列第1个非零元总是位于转置后矩阵中的首位 + copt[1] = 1; + // 计算各列第1个非零元在转置矩阵中的位置 + for(col = 2; col <= M.nu; ++col) { + copt[col] = copt[col - 1] + num[col - 1]; + } + + // 依次扫描M中的三元组 + for(p = 1; p <= M.tu; ++p) { + col = M.data[p].j; // 计算当前非零元所处的列 + q = copt[col]; // 计算当前非零元在转置矩阵中的位置 + (*T).data[q].i = M.data[p].j; + (*T).data[q].j = M.data[p].i; + (*T).data[q].e = M.data[p].e; + ++copt[col]; // 再遇到此列元素时,其在转置矩阵中的位置应当增一(该步骤很重要) + } + + // 为rpos数组赋值 + AssignRpos(T); + + return OK; +} + +/* + * 输出矩阵 + */ +void PrintSMatrix(RLSMatrix M) { + int r, c; + int k = 1; + + for(r = 1; r <= M.mu; ++r) { + for(c = 1; c <= M.nu; ++c) { + if(r == M.data[k].i && c == M.data[k].j) { + printf("%3d ", M.data[k].e); + k++; + } else { + printf("%3d ", 0); + } + } + printf("\n"); + } + + printf("rpos = "); + for(k = 1; k <= M.mu; ++k) { + printf("%d ", M.rpos[k]); + } + printf("\n"); +} + +// 为rpos数组赋值 +static void AssignRpos(RLSMatrix* M) { + int k, m; + + // 初始化数组rpos + for(k = 0; k <= MAXRC; ++k) { + (*M).rpos[k] = 0; + } + + for(k = 1; k <= (*M).tu; k++) { + m = (*M).data[k].i; // 当前三元组元素在矩阵中的行位置 + + // 记录每行第一个非零元的在三元组表中的位置 + if((*M).rpos[m] == 0) { + (*M).rpos[m] = k; // 只会在当前行有非零元的情况下记录 + } + } + + // 处理那些没有非零元的行 + for(k = (*M).mu; k >= 1; k--) { + // 如果当前行没有非零元,则此处会直接取用下一行的参数 + if((*M).rpos[k] == 0) { + // 如果是最后一行无非零元,因为已经不存在下一行了,所以需特殊处理 + if(k == (*M).mu) { + (*M).rpos[k] = (*M).tu + 1; + } else { + (*M).rpos[k] = (*M).rpos[k + 1]; + } + } + } +} diff --git a/CLion/ExerciseBook/05.23/RLSMatrix.h b/CLion/ExerciseBook/05.23/RLSMatrix.h new file mode 100644 index 0000000..bb1c595 --- /dev/null +++ b/CLion/ExerciseBook/05.23/RLSMatrix.h @@ -0,0 +1,107 @@ +/*============================= + * 行逻辑链接的顺序表(稀疏矩阵) + * + * 包含算法: 5.3 + ==============================*/ + +#ifndef RLSMATRIX_H +#define RLSMATRIX_H + +#include +#include // 提供 malloc 原型 +#include // 提供 strstr 原型 +#include "Status.h" //**▲01 绪论**// + +/* 宏定义 */ +#define MAXSIZE 12500 // 非零元数量的最大值 +#define MAXRC 20 // 各行元素个数的最大值 + +/* 行逻辑链接的稀疏矩阵元素类型 */ +typedef int ElemType; + +/* 三元组类型定义,主要用来存储非零元 */ +typedef struct { + int i, j; // 该非零元的行下标和列下标 + ElemType e; +} Triple; + +/* 行逻辑链接的稀疏矩阵类型定义 */ +typedef struct { + Triple data[MAXSIZE + 1]; // 非零元三元组表,data[0]未用 + int rpos[MAXRC + 1]; // 各行第一个非零元在三元组表中的位置表,rpos[0]未用 + int mu, nu, tu; // 矩阵的行数、列数和非零元个数 +} RLSMatrix; + + +/* + * 创建稀疏矩阵M + * + * + *【备注】 + * + * 教材中默认从控制台读取数据。 + * 这里为了方便测试,避免每次运行都手动输入数据, + * 因而允许选择从预设的文件path中读取测试数据。 + * + * 如果需要从控制台读取数据,则path为NULL或者为空串, + * 如果需要从文件中读取数据,则需要在path中填写文件名信息。 + */ +Status CreateSMatrix(RLSMatrix* M, char* path); + +/* + * 销毁稀疏矩阵 + * + *【注】 + * 行逻辑链接的顺序表结构无法销毁。 + */ +Status DestroySMatrix(RLSMatrix* M); + +/* + * 矩阵复制 + * + * 创建一个新矩阵T,该矩阵包含了从矩阵M中包含的数据。 + */ +Status CopySMatrix(RLSMatrix M, RLSMatrix* T); + +/* + * 矩阵加法 + * + * Q = M + N。 + */ +Status AddSMatrix(RLSMatrix M, RLSMatrix N, RLSMatrix* Q); + +/* + * 矩阵减法 + * + * Q = M - N。 + */ +Status SubSMatrix(RLSMatrix M, RLSMatrix N, RLSMatrix* Q); + +/* + * ████████ 算法5.3 ████████ + * + * 矩阵乘法 + * + * Q = M * N。 + */ +Status MultSMatrix(RLSMatrix M, RLSMatrix N, RLSMatrix* Q); + +/* + * 矩阵转置 + */ +Status TransposeSMatrix(RLSMatrix M, RLSMatrix* T); + +/* + * 矩阵快速转置 + */ +Status FastTransposeSMatrix(RLSMatrix M, RLSMatrix* T); + +/* + * 输出矩阵 + */ +void PrintSMatrix(RLSMatrix M); + +// 为rpos数组赋值 +static void AssignRpos(RLSMatrix* M); + +#endif diff --git a/CLion/ExerciseBook/05.23/TestData_M.txt b/CLion/ExerciseBook/05.23/TestData_M.txt new file mode 100644 index 0000000..5d3cb45 --- /dev/null +++ b/CLion/ExerciseBook/05.23/TestData_M.txt @@ -0,0 +1,4 @@ +行数:5 +列数:5 +非零元个数:10 +三元组:(1,2,1),(1,4,5),(2,3,-3),(2,5,2),(3,1,2),(3,2,3),(3,3,4),(4,4,2),(5,1,3),(5,2,-1) \ No newline at end of file diff --git a/CLion/ExerciseBook/05.24/05.24.c b/CLion/ExerciseBook/05.24/05.24.c new file mode 100644 index 0000000..c21de6c --- /dev/null +++ b/CLion/ExerciseBook/05.24/05.24.c @@ -0,0 +1,49 @@ +#include +#include "Status.h" //**▲01 绪论**// +#include "SMatrix.h" //**稀疏矩阵**// + +/* + * 获取矩阵中第i行第j列的元素,并将其存储到e中 + */ +Status Algo_5_24(SMatrix M, int i, int j, int* e); + + +int main(int argc, char* argv[]) { + SMatrix M; + int e; + + printf("█ 创建个稀疏矩阵 M ...\n"); + CreateSMatrix(&M, "TestData_M.txt"); + printf("M = \n"); + PrintSMatrix(M); + + Algo_5_24(M, 2, 3, &e); + printf("第 %d 行 %d 列的元素为 %d\n", 2, 3, e); + + return 0; +} + + +/* + * 获取矩阵中第i行第j列的元素,并将其存储到e中 + */ +Status Algo_5_24(SMatrix M, int i, int j, int* e) { + int s, p; + + if(i < 1 || i > M.mu || j < 1 || j > M.nu) { + return ERROR; + } + + for(p = 1, s = (i - 1) * M.nu + j; M.data[p].seq < s; p++) { + // 寻找指定的元素 + } + + *e = 0; // 默认为0 + + // 找到对应列下标的元素 + if(M.data[p].seq == s) { + *e = M.data[p].e; + } + + return OK; +} diff --git a/CLion/ExerciseBook/05.24/CMakeLists.txt b/CLion/ExerciseBook/05.24/CMakeLists.txt new file mode 100644 index 0000000..1c29d0b --- /dev/null +++ b/CLion/ExerciseBook/05.24/CMakeLists.txt @@ -0,0 +1,13 @@ +# 包含公共库 +include_directories(${CMAKE_SOURCE_DIR}/Status) + +# 生成可执行文件 +add_executable(05.24 SMatrix.h SMatrix.c 05.24.c) +# 链接公共库 +target_link_libraries(05.24 Scanf_lib) + + +# 记录要拷贝到*.exe目录下的资源文件 +file(GLOB TestData TestData*.txt) +# 将资源文件拷贝到*.exe目录下,不然无法加载 +file(COPY ${TestData} DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) diff --git a/CLion/ExerciseBook/05.24/SMatrix.c b/CLion/ExerciseBook/05.24/SMatrix.c new file mode 100644 index 0000000..23b1c67 --- /dev/null +++ b/CLion/ExerciseBook/05.24/SMatrix.c @@ -0,0 +1,44 @@ +/*====================== + * 稀疏矩阵,用于习题5.24 + =======================*/ + +#include "SMatrix.h" //**稀疏矩阵**// + +// 创建稀疏矩阵M +Status CreateSMatrix(SMatrix* M, char* path) { + FILE* fp; + int k, i, j; + + fp = fopen(path, "r"); + + ReadData(fp, "%d%d%d", &((*M).mu), &((*M).nu), &((*M).tu)); + + // 读取元素 + for(k = 1; k <= (*M).tu; k++) { + ReadData(fp, "%d%d%d", &i, &j, &((*M).data[k].e)); + (*M).data[k].seq = (i - 1) * (*M).nu + j; + } + + fclose(fp); + + return OK; +} + +// 输出稀疏矩阵M +void PrintSMatrix(SMatrix M) { + int r, c; + int k = 1; + + for(r = 1; r <= M.mu; r++) { + for(c = 1; c <= M.nu; c++) { + if(r == (M.data[k].seq - 1) / M.nu + 1 && c == (M.data[k].seq - 1) % M.nu + 1) { + + printf("%3d ", M.data[k].e); + k++; + } else { + printf(" 0 "); + } + } + printf("\n"); + } +} diff --git a/CLion/ExerciseBook/05.24/SMatrix.h b/CLion/ExerciseBook/05.24/SMatrix.h new file mode 100644 index 0000000..be19445 --- /dev/null +++ b/CLion/ExerciseBook/05.24/SMatrix.h @@ -0,0 +1,32 @@ +/*====================== + * 稀疏矩阵,用于习题5.24 + =======================*/ + +#ifndef SMATRIX_H +#define SMATRIX_H + +#include +#include "Status.h" //**▲01 绪论**// + +#define MAXSIZE 100 // 假设非零元个数的最大值为400 + +/* 非零元类型 */ +typedef struct { + int seq; // 该非零元在矩阵中的序号(以行序为主序) + int e; +} SElem; + +/* 稀疏矩阵 */ +typedef struct { + SElem data[MAXSIZE + 1]; // 存储各非零元素,data[0]未用 + int mu, nu, tu; // 矩阵的行数、列数和非零元个数 +} SMatrix; + + +// 创建稀疏矩阵M +Status CreateSMatrix(SMatrix* M, char* path); + +// 输出稀疏矩阵M +void PrintSMatrix(SMatrix M); + +#endif diff --git a/CLion/ExerciseBook/05.24/TestData_M.txt b/CLion/ExerciseBook/05.24/TestData_M.txt new file mode 100644 index 0000000..5d3cb45 --- /dev/null +++ b/CLion/ExerciseBook/05.24/TestData_M.txt @@ -0,0 +1,4 @@ +行数:5 +列数:5 +非零元个数:10 +三元组:(1,2,1),(1,4,5),(2,3,-3),(2,5,2),(3,1,2),(3,2,3),(3,3,4),(4,4,2),(5,1,3),(5,2,-1) \ No newline at end of file diff --git a/CLion/ExerciseBook/05.25/05.25.c b/CLion/ExerciseBook/05.25/05.25.c new file mode 100644 index 0000000..bb5b99b --- /dev/null +++ b/CLion/ExerciseBook/05.25/05.25.c @@ -0,0 +1,79 @@ +#include +#include "Status.h" //**▲01 绪论**// +#include "SMatrix.h" //**稀疏矩阵**// + +/* + * 稀疏矩阵加法:AddSMatrix + */ +Status Algo_5_25(SMatrix P, SMatrix Q, SMatrix* R); + + +int main(int argc, char* argv[]) { + SMatrix M, N, Q; + + printf("█ 创建两个稀疏矩阵 M、N ...\n"); + CreateSMatrix(&M, "TestData_M.txt"); + CreateSMatrix(&N, "TestData_N.txt"); + printf("█ M = \n"); + PrintSMatrix(M); + printf("█ N = \n"); + PrintSMatrix(N); + + Algo_5_25(M, N, &Q); + printf("Q = M + N = \n"); + PrintSMatrix(Q); + + return 0; +} + + +/* + * 稀疏矩阵加法:AddSMatrix + */ +Status Algo_5_25(SMatrix P, SMatrix Q, SMatrix* R) { + int i, j; + int p, q, r; + + if(P.mu != Q.mu || P.nu != Q.nu) { + printf("两矩阵的行数、列数不满足相加条件!!\n"); + return ERROR; + } + + // 初始化R的信息 + (*R).mu = P.mu; + (*R).nu = P.nu; + (*R).tu = 0; + memset((*R).V, 0, sizeof((*R).V)); + memset((*R).B, 0, sizeof((*R).B)); + + // 指向P、Q、R中的数组V + p = q = r = 0; + + for(i = 0; i < P.mu; ++i) { + for(j = 0; j < P.nu; ++j) { + if(P.B[i][j] == 0 && Q.B[i][j] == 0) { + continue; + } else if(P.B[i][j] == 0 && Q.B[i][j] == 1) { + (*R).V[r++] = Q.V[q++]; + (*R).B[i][j] = 1; + } else if(P.B[i][j] == 1 && Q.B[i][j] == 0) { + (*R).V[r++] = P.V[p++]; + (*R).B[i][j] = 1; + + // 如果P、Q两处均有非零元,则尝试相加 + } else { + if((P.V[p] + Q.V[q])!=0) { + (*R).V[r++] = P.V[p] + Q.V[q]; + (*R).B[i][j] = 1; + } + + p++; + q++; + } + } + } + + (*R).tu = r; + + return OK; +} diff --git a/CLion/ExerciseBook/05.25/CMakeLists.txt b/CLion/ExerciseBook/05.25/CMakeLists.txt new file mode 100644 index 0000000..dd27f45 --- /dev/null +++ b/CLion/ExerciseBook/05.25/CMakeLists.txt @@ -0,0 +1,13 @@ +# 包含公共库 +include_directories(${CMAKE_SOURCE_DIR}/Status) + +# 生成可执行文件 +add_executable(05.25 SMatrix.h SMatrix.c 05.25.c) +# 链接公共库 +target_link_libraries(05.25 Scanf_lib) + + +# 记录要拷贝到*.exe目录下的资源文件 +file(GLOB TestData TestData*.txt) +# 将资源文件拷贝到*.exe目录下,不然无法加载 +file(COPY ${TestData} DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) diff --git a/CLion/ExerciseBook/05.25/SMatrix.c b/CLion/ExerciseBook/05.25/SMatrix.c new file mode 100644 index 0000000..1775e2d --- /dev/null +++ b/CLion/ExerciseBook/05.25/SMatrix.c @@ -0,0 +1,48 @@ +/*====================== + * 稀疏矩阵,用于习题5.25 + =======================*/ + +#include "SMatrix.h" //**稀疏矩阵**// + +// 创建稀疏矩阵M +Status CreateSMatrix(SMatrix* M, char* path) { + FILE* fp; + int v, i, j; + + fp = fopen(path, "r"); + + ReadData(fp, "%d%d%d", &((*M).mu), &((*M).nu), &((*M).tu)); + + memset((*M).V, 0, sizeof((*M).V)); + memset((*M).B, 0, sizeof((*M).B)); + + for(v=0; v < (*M).tu; v++) { + // 读取非零元信息,将元素存入数组V中 + ReadData(fp, "%d%d%d", &i, &j, &((*M).V[v])); + + (*M).B[i-1][j-1] = 1; + } + + fclose(fp); + + return OK; +} + +// 输出稀疏矩阵M +void PrintSMatrix(SMatrix M) { + int v, i, j; + + v = 0; // 遍历V的游标 + + for(i = 1; i <= M.mu; i++) { + for(j = 1; j <= M.nu; j++) { + if(M.B[i-1][j-1] == 1) { + printf("%3d ", M.V[v++]); + } else { + printf("%3d ", M.B[i-1][j-1]); + } + } + + printf("\n"); + } +} diff --git a/CLion/ExerciseBook/05.25/SMatrix.h b/CLion/ExerciseBook/05.25/SMatrix.h new file mode 100644 index 0000000..6f8eb91 --- /dev/null +++ b/CLion/ExerciseBook/05.25/SMatrix.h @@ -0,0 +1,32 @@ +/*====================== + * 稀疏矩阵,用于习题5.25 + =======================*/ + +#ifndef SMATRIX_H +#define SMATRIX_H + +#include +#include +#include +#include "Status.h" //**▲01 绪论**// + +/* 宏定义 */ +#define Mu 20 // 假设矩阵行数最大值为20 +#define Nu 20 // 假设矩阵列数最大值为20 +#define MAXSIZE 400 // 假设非零元个数的最大值为400 + +/* 稀疏矩阵类型定义 */ +typedef struct { + int V[MAXSIZE]; // 存储矩阵的元素 + int B[Mu][Nu]; // 标记矩阵中各位置元素是否为非零元 + int mu, nu, tu; // 矩阵行数,列数,非零元个数 +} SMatrix; + + +// 创建稀疏矩阵M +Status CreateSMatrix(SMatrix* M, char* path); + +// 输出稀疏矩阵M +void PrintSMatrix(SMatrix M); + +#endif diff --git a/CLion/ExerciseBook/05.25/TestData_M.txt b/CLion/ExerciseBook/05.25/TestData_M.txt new file mode 100644 index 0000000..5d3cb45 --- /dev/null +++ b/CLion/ExerciseBook/05.25/TestData_M.txt @@ -0,0 +1,4 @@ +行数:5 +列数:5 +非零元个数:10 +三元组:(1,2,1),(1,4,5),(2,3,-3),(2,5,2),(3,1,2),(3,2,3),(3,3,4),(4,4,2),(5,1,3),(5,2,-1) \ No newline at end of file diff --git a/CLion/ExerciseBook/05.25/TestData_N.txt b/CLion/ExerciseBook/05.25/TestData_N.txt new file mode 100644 index 0000000..d567717 --- /dev/null +++ b/CLion/ExerciseBook/05.25/TestData_N.txt @@ -0,0 +1,4 @@ +行数:5 +列数:5 +非零元个数:8 +三元组:(1,1,-3)(1,3,2)(2,4,-1)(3,2,4)(4,1,6)(4,5,5)(5,1,3)(5,3,2) \ No newline at end of file diff --git a/CLion/ExerciseBook/05.26/05.26.c b/CLion/ExerciseBook/05.26/05.26.c new file mode 100644 index 0000000..17fffe5 --- /dev/null +++ b/CLion/ExerciseBook/05.26/05.26.c @@ -0,0 +1,49 @@ +#include +#include "Status.h" //**▲01 绪论**// +#include "CrossList.h" //**▲05 数组和广义表**// + +/* + * 以三元组形式输出十字链表 + */ +Status Algo_5_26(CrossList M); + + +int main(int argc, char* argv[]) { + CrossList M; + + printf("创建十字链表 M...\n"); + CreateSMatrix(&M, "TestData_M.txt"); + printf("M = \n"); + PrintSMatrix(M); + + printf("按三元组形式输出 M...\n"); + printf(" 行 列 值\n"); + Algo_5_26(M); + + return 0; +} + + +/* + * 以三元组形式输出十字链表 + */ +Status Algo_5_26(CrossList M) { + int i, j; + OLNode* p; + + if(M.tu==0) { + return ERROR; + } + + for(i = 1; i <= M.mu; ++i) { + p = M.rhead[i]; + for(j = 1; j <= M.nu; ++j) { + if(p && p->j == j) { + printf("(%2d %2d %3d)\n", i, j, p->e); + p = p->right; + } + } + } + + return OK; +} diff --git a/CLion/ExerciseBook/05.26/CMakeLists.txt b/CLion/ExerciseBook/05.26/CMakeLists.txt new file mode 100644 index 0000000..b669009 --- /dev/null +++ b/CLion/ExerciseBook/05.26/CMakeLists.txt @@ -0,0 +1,13 @@ +# 包含公共库 +include_directories(${CMAKE_SOURCE_DIR}/Status) + +# 生成可执行文件 +add_executable(05.26 CrossList.h CrossList.c 05.26.c) +# 链接公共库 +target_link_libraries(05.26 Scanf_lib) + + +# 记录要拷贝到*.exe目录下的资源文件 +file(GLOB TestData TestData*.txt) +# 将资源文件拷贝到*.exe目录下,不然无法加载 +file(COPY ${TestData} DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) diff --git a/CLion/ExerciseBook/05.26/CrossList.c b/CLion/ExerciseBook/05.26/CrossList.c new file mode 100644 index 0000000..2a29342 --- /dev/null +++ b/CLion/ExerciseBook/05.26/CrossList.c @@ -0,0 +1,885 @@ +/*=================== + * 十字链表(稀疏矩阵) + * + * 包含算法: 5.4 + ====================*/ + +#include "CrossList.h" //**▲05 数组和广义表**// + +/* + * ████████ 算法5.4 ████████ + * + * 创建稀疏矩阵M + * + * + *【备注】 + * + * 教材中默认从控制台读取数据。 + * 这里为了方便测试,避免每次运行都手动输入数据, + * 因而允许选择从预设的文件path中读取测试数据。 + * + * 如果需要从控制台读取数据,则path为NULL或者为空串, + * 如果需要从文件中读取数据,则需要在path中填写文件名信息。 + */ +Status CreateSMatrix(CrossList* M, char* path) { + int i, j, k; + OLNode* p, * q; + FILE* fp; + int readFromConsole; // 是否从控制台读取数据 + + // 如果没有文件路径信息,则从控制台读取输入 + readFromConsole = path == NULL || strcmp(path, "") == 0; + + if(readFromConsole) { + printf("请输入行数:"); + scanf("%d", &((*M).mu)); + printf("请输入列数:"); + scanf("%d", &((*M).nu)); + printf("请输入非零元素个数:"); + scanf("%d", &((*M).tu)); + printf("请输入%d个三元组信息\n", (*M).tu); + } else { + fp = fopen(path, "r"); + ReadData(fp, "%d%d%d", &((*M).mu), &((*M).nu), &((*M).tu)); + } + + // 创建行链(类似行索引,0号单元弃用) + (*M).rhead = (OLink*) malloc(((*M).mu + 1) * sizeof(OLink)); + if((*M).rhead == NULL) { + exit(OVERFLOW); + } + + // 创建列链(类似列索引,0号单元弃用) + (*M).chead = (OLink*) malloc(((*M).nu + 1) * sizeof(OLink)); + if((*M).chead == NULL) { + exit(OVERFLOW); + } + + // 初始化行链索引为NULL + for(k = 0; k <= (*M).mu; ++k) { + (*M).rhead[k] = NULL; + } + + // 初始化列链索引为NULL + for(k = 0; k <= (*M).nu; ++k) { + (*M).chead[k] = NULL; + } + + // 依次录入非零元 + for(k = 1; k <= (*M).tu; ++k) { + // 创建三元组结点 + p = (OLNode*) malloc(sizeof(OLNode)); + if(p == NULL) { + exit(OVERFLOW); + } + + if(readFromConsole) { + printf("第%2d组:", k); + scanf("%d%d%d", &i, &j, &(p->e)); + } else { + ReadData(fp, "%d%d%d", &i, &j, &(p->e)); + } + + p->i = i; // 行号 + p->j = j; // 列号 + p->right = p->down = NULL; + + /* + * 开始行的插入 + */ + + // 如果该行还没有元素,或已有元素均位于该元素右侧,则可以直接插入 + if((*M).rhead[i] == NULL || (*M).rhead[i]->j > j) { + // 定位行表中的插入位置 + p->right = (*M).rhead[i]; + (*M).rhead[i] = p; + } else { + // 寻找插入位置的前一个位置 + for(q = (*M).rhead[i]; (q->right) && (q->right->j < j); q = q->right) { + } + + if(q->j == p->j || ((q->right) && q->right->j == p->j)) { + printf("此位置已被占用!!\n"); + exit(ERROR); + } + + p->right = q->right; + q->right = p; + } + + /* + * 开始列的插入 + */ + + // 如果该列还没有元素,或已有元素均位于该元素下侧,则可以直接插入 + if((*M).chead[j] == NULL || (*M).chead[j]->i > i) { + // 定位列表中的插入位置 + p->down = (*M).chead[j]; + (*M).chead[j] = p; + } else { + // 寻找插入位置的前一个位置 + for(q = (*M).chead[j]; (q->down) && (q->down->i < i); q = q->down) { + } + + if(q->i == p->i || ((q->down) && q->down->i == p->i)) { + printf("此位置已被占用!!\n"); + exit(ERROR); + } + + p->down = q->down; + q->down = p; + } + } + + if(!readFromConsole) { + fclose(fp); + } + + return OK; +} + +/* + * 销毁稀疏矩阵 + */ +Status DestroySMatrix(CrossList* M) { + int i; + OLNode* p, * q; + + // 无论从按行还是按列,只需要朝着一个方向去遍历销毁就可以了 + for(i = 1; i <= (*M).mu; ++i) { + p = (*M).rhead[i]; + while(p != NULL) { + q = p; + p = p->right; + free(q); + } + } + + free((*M).rhead); + free((*M).chead); + + (*M).rhead = (*M).chead = NULL; + (*M).mu = (*M).nu = (*M).tu = 0; + + return OK; +} + +/* + * 矩阵复制 + * + * 创建一个新矩阵T,该矩阵包含了从矩阵M中包含的数据。 + */ +Status CopySMatrix(CrossList M, CrossList* T) { + int k; + OLNode* p, * q, * r, * l; + + if(T == NULL) { + return ERROR; + } + + // 复制行列信息 + (*T).mu = M.mu; + (*T).nu = M.nu; + (*T).tu = M.tu; + + // 创建行链(类似行索引,0号单元弃用) + (*T).rhead = (OLink*) malloc(((*T).mu + 1) * sizeof(OLink)); + if((*T).rhead == NULL) { + exit(OVERFLOW); + } + + // 创建列链(类似列索引,0号单元弃用) + (*T).chead = (OLink*) malloc(((*T).nu + 1) * sizeof(OLink)); + if((*T).chead == NULL) { + exit(OVERFLOW); + } + + // 初始化行链索引为NULL + for(k = 0; k <= (*T).mu; ++k) { //初始化行列头指针向量为空 + (*T).rhead[k] = NULL; + } + + // 初始化列链索引为NULL + for(k = 0; k <= (*T).nu; ++k) { + (*T).chead[k] = NULL; + } + + // 按行扫描,依次复制非零元 + for(k = 1; k <= M.mu; ++k) { + q = M.rhead[k]; + + // 如果当前行没有元素,直接跳过 + if(q == NULL) { + continue; + } + + r = NULL; + + while(q != NULL) { + // 创建三元组结点 + p = (OLNode*) malloc(sizeof(OLNode)); + if(p == NULL) { + exit(OVERFLOW); + } + + // 为结点赋值 + p->i = q->i; + p->j = q->j; + p->e = q->e; + p->right = p->down = NULL; + + /* + * 开始行的插入 + */ + + if(r == NULL) { + (*T).rhead[q->i] = p; + } else { + r->right = p; + } + + // r指向当前行新插入的结点 + r = p; + + /* + * 开始列的插入 + */ + + // 在列链中寻找插入位置 + if((*T).chead[q->j] == NULL || (*T).chead[q->j]->i > q->i) { + r->down = (*T).chead[q->j]; + (*T).chead[q->j] = r; + } else { + // 寻找插入位置的前一个位置 + for(l = (*T).chead[q->j]; (l->down) && (l->down->i < q->i); l = l->down) { + } + r->down = l->down; + l->down = r; + } + + q = q->right; + } + } + + return OK; +} + +/* + * 矩阵加法 + * + * Q = M + N。 + */ +Status AddSMatrix(CrossList M, CrossList N, CrossList* Q) { + int i; + OLNode* pm, * pn, * p, * r, * l; + + if(M.mu != N.mu || M.nu != N.nu) { + printf("两矩阵的行数、列数不满足相加条件!!\n"); + return ERROR; + } + + // 初始化Q的行列信息 + Q->mu = M.mu; + Q->nu = M.nu; + Q->tu = 0; + + // 创建行链(类似行索引,0号单元弃用) + Q->rhead = (OLink*) malloc((Q->mu + 1) * sizeof(OLink)); + if(!Q->rhead) { + exit(OVERFLOW); + } + + // 创建列链(类似列索引,0号单元弃用) + Q->chead = (OLink*) malloc((Q->nu + 1) * sizeof(OLink)); + if(!Q->chead) { + exit(OVERFLOW); + } + + // 初始化行链索引为NULL + for(i = 0; i <= Q->mu; ++i) { + Q->rhead[i] = NULL; + } + + // 初始化列链索引为NULL + for(i = 0; i <= Q->nu; ++i) { + Q->chead[i] = NULL; + } + + // 从第一行往下遍历 + for(i = 1; i <= M.mu; ++i) { + pm = M.rhead[i]; + pn = N.rhead[i]; + + // 如果M与N的当前行中均有未处理的非零元 + while(pm != NULL && pn != NULL) { + // 处理特殊情形 + if(pm->j == pn->j && pm->e + pn->e == 0) { + pm = pm->right; + pn = pn->right; + continue; + } + + // 创建结点 + p = (OLNode*) malloc(sizeof(OLNode)); + if(!p) { + exit(OVERFLOW); + } + + // M中的三元组列下标较小 + if(pm->j < pn->j) { + p->i = pm->i; + p->j = pm->j; + p->e = pm->e; + pm = pm->right; + + // N中的三元组列下标较小 + } else if(pm->j > pn->j) { + p->i = pn->i; + p->j = pn->j; + p->e = pn->e; + pn = pn->right; + + // M与N中的三元组列下标一致,需要进行加法运算 + } else { + p->i = pm->i; + p->j = pm->j; + p->e = pm->e + pn->e; + pm = pm->right; + pn = pn->right; + } + + p->right = p->down = NULL; + + Q->tu++; // Q中非零元个数增一 + + /* + * 开始行的插入 + */ + + if(Q->rhead[p->i] == NULL) { + Q->rhead[p->i] = p; + } else { + r->right = p; + } + + // r指向当前行新插入的结点 + r = p; + + /* + * 开始列的插入 + */ + + // 在列链中寻找插入位置 + if(Q->chead[p->j] == NULL || Q->chead[p->j]->i > p->i) { + r->down = Q->chead[p->j]; + Q->chead[p->j] = r; + } else { + // 寻找插入位置的前一个位置 + for(l = Q->chead[p->j]; (l->down) && (l->down->i < p->i); l = l->down) { + } + r->down = l->down; + l->down = r; + } + } + + // 如果M的当前行中仍有未处理的非零元 + while(pm != NULL) { + p = (OLNode*) malloc(sizeof(OLNode)); + if(p == NULL) { + exit(OVERFLOW); + } + p->i = pm->i; + p->j = pm->j; + p->e = pm->e; + p->right = p->down = NULL; + + Q->tu++; // Q中非零元个数增一 + + if(Q->rhead[p->i] == NULL) { + Q->rhead[p->i] = p; + } else { + r->right = p; + } + + // r指向当前行新插入的结点 + r = p; + + // 在列链中寻找插入位置 + if(Q->chead[p->j] == NULL || Q->chead[p->j]->i > p->i) { + r->down = Q->chead[p->j]; + Q->chead[p->j] = r; + } else { + // 寻找插入位置的前一个位置 + for(l = Q->chead[p->j]; (l->down) && (l->down->i < p->i); l = l->down) { + } + r->down = l->down; + l->down = r; + } + + pm = pm->right; + } + + // 如果N的当前行中仍有未处理的非零元 + while(pn != NULL) { + p = (OLNode*) malloc(sizeof(OLNode)); + if(p == NULL) { + exit(OVERFLOW); + } + p->i = pn->i; + p->j = pn->j; + p->e = pn->e; + p->right = p->down = NULL; + + Q->tu++; // Q中非零元个数增一 + + if(Q->rhead[p->i] == NULL) { + Q->rhead[p->i] = p; + } else { + r->right = p; + } + + // r指向当前行新插入的结点 + r = p; + + // 在列链中寻找插入位置 + if(Q->chead[p->j] == NULL || Q->chead[p->j]->i > p->i) { + r->down = Q->chead[p->j]; + Q->chead[p->j] = r; + } else { + // 寻找插入位置的前一个位置 + for(l = Q->chead[p->j]; (l->down) && (l->down->i < p->i); l = l->down) { + } + r->down = l->down; + l->down = r; + } + + pn = pn->right; + } + } + + return OK; +} + +/* + * 矩阵减法 + * + * Q = M - N。 + */ +Status SubSMatrix(CrossList M, CrossList N, CrossList* Q) { + int i; + OLNode* pm, * pn, * p, * r, * l; + + if(M.mu != N.mu || M.nu != N.nu) { + printf("两矩阵的行数、列数不满足相减条件!!\n"); + return ERROR; + } + + // 初始化Q的行列信息 + Q->mu = M.mu; + Q->nu = M.nu; + Q->tu = 0; + + // 创建行链(类似行索引,0号单元弃用) + Q->rhead = (OLink*) malloc((Q->mu + 1) * sizeof(OLink)); + if(!Q->rhead) { + exit(OVERFLOW); + } + + // 创建列链(类似列索引,0号单元弃用) + Q->chead = (OLink*) malloc((Q->nu + 1) * sizeof(OLink)); + if(!Q->chead) { + exit(OVERFLOW); + } + + // 初始化行链索引为NULL + for(i = 0; i <= Q->mu; ++i) { + Q->rhead[i] = NULL; + } + + // 初始化列链索引为NULL + for(i = 0; i <= Q->nu; ++i) { + Q->chead[i] = NULL; + } + + // 从第一行往下遍历 + for(i = 1; i <= M.mu; ++i) { + pm = M.rhead[i]; + pn = N.rhead[i]; + + // 如果M与N的当前行中均有未处理的非零元 + while(pm != NULL && pn != NULL) { + // 处理特殊情形 + if(pm->j == pn->j && pm->e - pn->e == 0) { + pm = pm->right; + pn = pn->right; + continue; + } + + // 创建结点 + p = (OLNode*) malloc(sizeof(OLNode)); + if(!p) { + exit(OVERFLOW); + } + + // M中的三元组列下标较小 + if(pm->j < pn->j) { + p->i = pm->i; + p->j = pm->j; + p->e = pm->e; + pm = pm->right; + + // N中的三元组列下标较小 + } else if(pm->j > pn->j) { + p->i = pn->i; + p->j = pn->j; + p->e = -pn->e; // 加负号 + pn = pn->right; + + // M与N中的三元组列下标一致,需要进行减法运算 + } else { + p->i = pm->i; + p->j = pm->j; + p->e = pm->e - pn->e; + pm = pm->right; + pn = pn->right; + } + + p->right = p->down = NULL; + + Q->tu++; // Q中非零元个数增一 + + /* + * 开始行的插入 + */ + + if(Q->rhead[p->i] == NULL) { + Q->rhead[p->i] = p; + } else { + r->right = p; + } + + // r指向当前行新插入的结点 + r = p; + + /* + * 开始列的插入 + */ + + // 在列链中寻找插入位置 + if(Q->chead[p->j] == NULL || Q->chead[p->j]->i > p->i) { + r->down = Q->chead[p->j]; + Q->chead[p->j] = r; + } else { + //寻找插入位置的前一个位置 + for(l = Q->chead[p->j]; (l->down) && (l->down->i < p->i); l = l->down) { + } + r->down = l->down; + l->down = r; + } + } + + // 如果M的当前行中仍有未处理的非零元 + while(pm != NULL) { + p = (OLNode*) malloc(sizeof(OLNode)); + if(!p) { + exit(OVERFLOW); + } + p->i = pm->i; + p->j = pm->j; + p->e = pm->e; + p->right = p->down = NULL; + + Q->tu++; // Q中非零元个数增一 + + if(Q->rhead[p->i] == NULL) { + Q->rhead[p->i] = p; + } else { + r->right = p; + } + + // r指向当前行新插入的结点 + r = p; + + // 在列链中寻找插入位置 + if(Q->chead[p->j] == NULL || Q->chead[p->j]->i > p->i) { + r->down = Q->chead[p->j]; + Q->chead[p->j] = r; + } else { + // 寻找插入位置的前一个位置 + for(l = Q->chead[p->j]; (l->down) && (l->down->i < p->i); l = l->down) { + } + r->down = l->down; + l->down = r; + } + + pm = pm->right; + } + + // 如果N的当前行中仍有未处理的非零元 + while(pn != NULL) { + p = (OLNode*) malloc(sizeof(OLNode)); + if(!p) { + exit(OVERFLOW); + } + p->i = pn->i; + p->j = pn->j; + p->e = -pn->e; // 加负号 + p->right = p->down = NULL; + + Q->tu++; // Q中非零元个数增一 + + if(Q->rhead[p->i] == NULL) { + Q->rhead[p->i] = p; + } else { + r->right = p; + } + + // r指向当前行新插入的结点 + r = p; + + // 在列链中寻找插入位置 + if(Q->chead[p->j] == NULL || Q->chead[p->j]->i > p->i) { + r->down = Q->chead[p->j]; + Q->chead[p->j] = r; + } else { + // 寻找插入位置的前一个位置 + for(l = Q->chead[p->j]; (l->down) && (l->down->i < p->i); l = l->down) { + } + r->down = l->down; + l->down = r; + } + + pn = pn->right; + } + } + + return OK; +} + +/* + * 矩阵乘法 + * + * Q = M * N。 + */ +Status MultSMatrix(CrossList M, CrossList N, CrossList* Q) { + int m_row, n_col, i; + ElemType e; + OLNode* pm, * pn, * p, * r, * l; + + // M的列数需要等于N的行数 + if(M.nu != N.mu) { + printf("两矩阵的行数、列数不满足相乘条件!!\n"); + return ERROR; + } + + // 初始化Q的行列信息 + Q->mu = M.mu; + Q->nu = N.nu; + Q->tu = 0; + + // 创建行链(类似行索引,0号单元弃用) + Q->rhead = (OLink*) malloc((Q->mu + 1) * sizeof(OLink)); + if(!Q->rhead) { + exit(OVERFLOW); + } + + // 创建列链(类似列索引,0号单元弃用) + Q->chead = (OLink*) malloc((Q->nu + 1) * sizeof(OLink)); + if(!Q->chead) { + exit(OVERFLOW); + } + + // 初始化行链索引为NULL + for(i = 0; i <= Q->mu; ++i) { + Q->rhead[i] = NULL; + } + + // 初始化列链索引为NULL + for(i = 0; i <= Q->nu; ++i) { + Q->chead[i] = NULL; + } + + // Q是非零矩阵 + if(M.tu * N.tu) { + for(m_row = 1; m_row <= M.mu; ++m_row) { + for(n_col = 1; n_col <= N.nu; ++n_col) { + pm = M.rhead[m_row]; + pn = N.chead[n_col]; + + e = 0; + + // M的行与N的列相乘 + while(pm && pn) { + if(pm->j < pn->i) { + pm = pm->right; + } else if(pm->j > pn->i) { + pn = pn->down; + } else { + e += pm->e * pn->e; + pm = pm->right; + pn = pn->down; + } + } + + if(e == 0) { + continue; + } + + p = (OLNode*) malloc(sizeof(OLNode)); + if(!p) { + exit(OVERFLOW); + } + + // 为结点赋值 + p->i = M.rhead[m_row]->i; + p->j = N.chead[n_col]->j; + p->e = e; + p->right = p->down = NULL; + + Q->tu++; // Q中非零元个数增一 + + if(Q->rhead[p->i] == NULL) { + Q->rhead[p->i] = p; + } else { + r->right = p; + } + + // r指向当前行新插入的结点 + r = p; + + // 在列链中寻找插入位置 + if(Q->chead[p->j] == NULL || Q->chead[p->j]->i > p->i) { + r->down = Q->chead[p->j]; + Q->chead[p->j] = r; + } else { + // 寻找插入位置的前一个位置 + for(l = Q->chead[p->j]; (l->down) && (l->down->i < p->i); l = l->down) { + } + + r->down = l->down; + l->down = r; + } + } + } + } + + return OK; +} + +/* + * 矩阵转置 + */ +Status TransposeSMatrix(CrossList M, CrossList* T) { + int i; + OLNode* p, * q, * r, * l; + + // 初始化Q的行列信息 + (*T).mu = M.nu; + (*T).nu = M.mu; + (*T).tu = M.tu; + + // 创建行链(类似行索引,0号单元弃用) + (*T).rhead = (OLink*) malloc(((*T).mu + 1) * sizeof(OLink)); + if(!(*T).rhead) { + exit(OVERFLOW); + } + + // 创建列链(类似列索引,0号单元弃用) + (*T).chead = (OLink*) malloc(((*T).nu + 1) * sizeof(OLink)); + if(!(*T).chead) { + exit(OVERFLOW); + } + + // 初始化行链索引为NULL + for(i = 0; i <= (*T).mu; ++i) { + (*T).rhead[i] = NULL; + } + + // 初始化列链索引为NULL + for(i = 0; i <= (*T).nu; ++i) { + (*T).chead[i] = NULL; + } + + // 零矩阵 + if(!(*T).tu) { + return OK; + } + + // 按列扫描 + for(i = 1; i <= M.nu; ++i) { + q = M.chead[i]; + + // 如果当前行没有元素,直接跳过 + if(q == NULL) { + continue; + } + + while(q != NULL) { + // 创建三元组结点 + p = (OLNode*) malloc(sizeof(OLNode)); + if(!p) { + exit(OVERFLOW); + } + + // 为结点赋值,行变列,列变行 + p->i = q->j; + p->j = q->i; + p->e = q->e; + p->right = p->down = NULL; + + /* + * 开始行的插入 + */ + + if((*T).rhead[p->i] == NULL) { + (*T).rhead[p->i] = p; + } else { + r->right = p; + } + + // r指向当前行新插入的结点 + r = p; + + /* + * 开始列的插入 + */ + + // 在列链中寻找插入位置 + if((*T).chead[p->j] == NULL || (*T).chead[p->j]->i > p->i) { + r->down = (*T).chead[p->j]; + (*T).chead[p->j] = r; + } else { + // 寻找插入位置的前一个位置 + for(l = (*T).chead[p->j]; (l->down) && (l->down->i < p->i); l = l->down) { + } + r->down = l->down; + l->down = r; + } + + q = q->down; + } + } + + return OK; +} + +/* + * 输出矩阵 + */ +void PrintSMatrix(CrossList M) { + int i, j; + OLNode* p; + + for(i = 1; i <= M.mu; ++i) { + p = M.rhead[i]; + for(j = 1; j <= M.nu; ++j) { + if(p && p->j == j) { + printf("%3d ", p->e); + p = p->right; + } else { + printf("%3d ", 0); + } + } + printf("\n"); + } +} diff --git a/CLion/ExerciseBook/05.26/CrossList.h b/CLion/ExerciseBook/05.26/CrossList.h new file mode 100644 index 0000000..deb950e --- /dev/null +++ b/CLion/ExerciseBook/05.26/CrossList.h @@ -0,0 +1,94 @@ +/*=================== + * 十字链表(稀疏矩阵) + * + * 包含算法: 5.4 + ====================*/ + +#ifndef CROSSLIST_H +#define CROSSLIST_H + +#include +#include // 提供malloc、realloc、free、exit原型 +#include // 提供 strstr 原型 +#include "Status.h" //**▲01 绪论**// + +/* 十字链表元素类型 */ +typedef int ElemType; + +/* 非零元类型定义 */ +typedef struct OLNode { + int i, j; // 该非零元的行下标和列下标 + ElemType e; + struct OLNode* right; // 该非零元所在的行表的后继链域 + struct OLNode* down; // 该非零元所在的列表的后继链域 +} OLNode, * OLink; + +/* 十字链表类型定义 */ +typedef struct { + OLink* rhead; // 行链表头指针 + OLink* chead; // 列链表头指针 + int mu, nu, tu; // 矩阵的行数、列数和非零元个数 +} CrossList; + + +/* + * ████████ 算法5.4 ████████ + * + * 创建稀疏矩阵M + * + * + *【备注】 + * + * 教材中默认从控制台读取数据。 + * 这里为了方便测试,避免每次运行都手动输入数据, + * 因而允许选择从预设的文件path中读取测试数据。 + * + * 如果需要从控制台读取数据,则path为NULL或者为空串, + * 如果需要从文件中读取数据,则需要在path中填写文件名信息。 + */ +Status CreateSMatrix(CrossList* M, char* path); + +/* + * 销毁稀疏矩阵 + */ +Status DestroySMatrix(CrossList* M); + +/* + * 矩阵复制 + * + * 创建一个新矩阵T,该矩阵包含了从矩阵M中包含的数据。 + */ +Status CopySMatrix(CrossList M, CrossList* T); + +/* + * 矩阵加法 + * + * Q = M + N。 + */ +Status AddSMatrix(CrossList M, CrossList N, CrossList* Q); + +/* + * 矩阵减法 + * + * Q = M - N。 + */ +Status SubSMatrix(CrossList M, CrossList N, CrossList* Q); + +/* + * 矩阵乘法 + * + * Q = M * N。 + */ +Status MultSMatrix(CrossList M, CrossList N, CrossList* Q); + +/* + * 矩阵转置 + */ +Status TransposeSMatrix(CrossList M, CrossList* T); + +/* + * 输出矩阵 + */ +void PrintSMatrix(CrossList M); + +#endif diff --git a/CLion/ExerciseBook/05.26/TestData_M.txt b/CLion/ExerciseBook/05.26/TestData_M.txt new file mode 100644 index 0000000..5d3cb45 --- /dev/null +++ b/CLion/ExerciseBook/05.26/TestData_M.txt @@ -0,0 +1,4 @@ +行数:5 +列数:5 +非零元个数:10 +三元组:(1,2,1),(1,4,5),(2,3,-3),(2,5,2),(3,1,2),(3,2,3),(3,3,4),(4,4,2),(5,1,3),(5,2,-1) \ No newline at end of file diff --git a/CLion/ExerciseBook/05.27/05.27.c b/CLion/ExerciseBook/05.27/05.27.c new file mode 100644 index 0000000..9590be8 --- /dev/null +++ b/CLion/ExerciseBook/05.27/05.27.c @@ -0,0 +1,41 @@ +#include +#include "Status.h" //**▲01 绪论**// +#include "CrossList.h" //**▲05 数组和广义表**// + +/* + * 稀疏矩阵加法:AddSMatrix + * + *【注】 + * 该函数已在CrossList相关文件中定义 + */ +Status Algo_5_27(CrossList M, CrossList N, CrossList* Q); + + +int main(int argc, char* argv[]) { + CrossList M, N, Q; + + printf("█ 创建两个稀疏矩阵 M、N ...\n"); + CreateSMatrix(&M, "TestData_M.txt"); + CreateSMatrix(&N, "TestData_N.txt"); + printf("█ M = \n"); + PrintSMatrix(M); + printf("█ N = \n"); + PrintSMatrix(N); + + Algo_5_27(M, N, &Q); + printf("█ Q = M + N = \n"); + PrintSMatrix(Q); + + return 0; +} + + +/* + * 稀疏矩阵加法:AddSMatrix + * + *【注】 + * 该函数已在CrossList相关文件中定义 + */ +Status Algo_5_27(CrossList M, CrossList N, CrossList* Q) { + return AddSMatrix(M, N, Q); +} diff --git a/CLion/ExerciseBook/05.27/CMakeLists.txt b/CLion/ExerciseBook/05.27/CMakeLists.txt new file mode 100644 index 0000000..5a3ea5a --- /dev/null +++ b/CLion/ExerciseBook/05.27/CMakeLists.txt @@ -0,0 +1,13 @@ +# 包含公共库 +include_directories(${CMAKE_SOURCE_DIR}/Status) + +# 生成可执行文件 +add_executable(05.27 CrossList.h CrossList.c 05.27.c) +# 链接公共库 +target_link_libraries(05.27 Scanf_lib) + + +# 记录要拷贝到*.exe目录下的资源文件 +file(GLOB TestData TestData*.txt) +# 将资源文件拷贝到*.exe目录下,不然无法加载 +file(COPY ${TestData} DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) diff --git a/CLion/ExerciseBook/05.27/CrossList.c b/CLion/ExerciseBook/05.27/CrossList.c new file mode 100644 index 0000000..2a29342 --- /dev/null +++ b/CLion/ExerciseBook/05.27/CrossList.c @@ -0,0 +1,885 @@ +/*=================== + * 十字链表(稀疏矩阵) + * + * 包含算法: 5.4 + ====================*/ + +#include "CrossList.h" //**▲05 数组和广义表**// + +/* + * ████████ 算法5.4 ████████ + * + * 创建稀疏矩阵M + * + * + *【备注】 + * + * 教材中默认从控制台读取数据。 + * 这里为了方便测试,避免每次运行都手动输入数据, + * 因而允许选择从预设的文件path中读取测试数据。 + * + * 如果需要从控制台读取数据,则path为NULL或者为空串, + * 如果需要从文件中读取数据,则需要在path中填写文件名信息。 + */ +Status CreateSMatrix(CrossList* M, char* path) { + int i, j, k; + OLNode* p, * q; + FILE* fp; + int readFromConsole; // 是否从控制台读取数据 + + // 如果没有文件路径信息,则从控制台读取输入 + readFromConsole = path == NULL || strcmp(path, "") == 0; + + if(readFromConsole) { + printf("请输入行数:"); + scanf("%d", &((*M).mu)); + printf("请输入列数:"); + scanf("%d", &((*M).nu)); + printf("请输入非零元素个数:"); + scanf("%d", &((*M).tu)); + printf("请输入%d个三元组信息\n", (*M).tu); + } else { + fp = fopen(path, "r"); + ReadData(fp, "%d%d%d", &((*M).mu), &((*M).nu), &((*M).tu)); + } + + // 创建行链(类似行索引,0号单元弃用) + (*M).rhead = (OLink*) malloc(((*M).mu + 1) * sizeof(OLink)); + if((*M).rhead == NULL) { + exit(OVERFLOW); + } + + // 创建列链(类似列索引,0号单元弃用) + (*M).chead = (OLink*) malloc(((*M).nu + 1) * sizeof(OLink)); + if((*M).chead == NULL) { + exit(OVERFLOW); + } + + // 初始化行链索引为NULL + for(k = 0; k <= (*M).mu; ++k) { + (*M).rhead[k] = NULL; + } + + // 初始化列链索引为NULL + for(k = 0; k <= (*M).nu; ++k) { + (*M).chead[k] = NULL; + } + + // 依次录入非零元 + for(k = 1; k <= (*M).tu; ++k) { + // 创建三元组结点 + p = (OLNode*) malloc(sizeof(OLNode)); + if(p == NULL) { + exit(OVERFLOW); + } + + if(readFromConsole) { + printf("第%2d组:", k); + scanf("%d%d%d", &i, &j, &(p->e)); + } else { + ReadData(fp, "%d%d%d", &i, &j, &(p->e)); + } + + p->i = i; // 行号 + p->j = j; // 列号 + p->right = p->down = NULL; + + /* + * 开始行的插入 + */ + + // 如果该行还没有元素,或已有元素均位于该元素右侧,则可以直接插入 + if((*M).rhead[i] == NULL || (*M).rhead[i]->j > j) { + // 定位行表中的插入位置 + p->right = (*M).rhead[i]; + (*M).rhead[i] = p; + } else { + // 寻找插入位置的前一个位置 + for(q = (*M).rhead[i]; (q->right) && (q->right->j < j); q = q->right) { + } + + if(q->j == p->j || ((q->right) && q->right->j == p->j)) { + printf("此位置已被占用!!\n"); + exit(ERROR); + } + + p->right = q->right; + q->right = p; + } + + /* + * 开始列的插入 + */ + + // 如果该列还没有元素,或已有元素均位于该元素下侧,则可以直接插入 + if((*M).chead[j] == NULL || (*M).chead[j]->i > i) { + // 定位列表中的插入位置 + p->down = (*M).chead[j]; + (*M).chead[j] = p; + } else { + // 寻找插入位置的前一个位置 + for(q = (*M).chead[j]; (q->down) && (q->down->i < i); q = q->down) { + } + + if(q->i == p->i || ((q->down) && q->down->i == p->i)) { + printf("此位置已被占用!!\n"); + exit(ERROR); + } + + p->down = q->down; + q->down = p; + } + } + + if(!readFromConsole) { + fclose(fp); + } + + return OK; +} + +/* + * 销毁稀疏矩阵 + */ +Status DestroySMatrix(CrossList* M) { + int i; + OLNode* p, * q; + + // 无论从按行还是按列,只需要朝着一个方向去遍历销毁就可以了 + for(i = 1; i <= (*M).mu; ++i) { + p = (*M).rhead[i]; + while(p != NULL) { + q = p; + p = p->right; + free(q); + } + } + + free((*M).rhead); + free((*M).chead); + + (*M).rhead = (*M).chead = NULL; + (*M).mu = (*M).nu = (*M).tu = 0; + + return OK; +} + +/* + * 矩阵复制 + * + * 创建一个新矩阵T,该矩阵包含了从矩阵M中包含的数据。 + */ +Status CopySMatrix(CrossList M, CrossList* T) { + int k; + OLNode* p, * q, * r, * l; + + if(T == NULL) { + return ERROR; + } + + // 复制行列信息 + (*T).mu = M.mu; + (*T).nu = M.nu; + (*T).tu = M.tu; + + // 创建行链(类似行索引,0号单元弃用) + (*T).rhead = (OLink*) malloc(((*T).mu + 1) * sizeof(OLink)); + if((*T).rhead == NULL) { + exit(OVERFLOW); + } + + // 创建列链(类似列索引,0号单元弃用) + (*T).chead = (OLink*) malloc(((*T).nu + 1) * sizeof(OLink)); + if((*T).chead == NULL) { + exit(OVERFLOW); + } + + // 初始化行链索引为NULL + for(k = 0; k <= (*T).mu; ++k) { //初始化行列头指针向量为空 + (*T).rhead[k] = NULL; + } + + // 初始化列链索引为NULL + for(k = 0; k <= (*T).nu; ++k) { + (*T).chead[k] = NULL; + } + + // 按行扫描,依次复制非零元 + for(k = 1; k <= M.mu; ++k) { + q = M.rhead[k]; + + // 如果当前行没有元素,直接跳过 + if(q == NULL) { + continue; + } + + r = NULL; + + while(q != NULL) { + // 创建三元组结点 + p = (OLNode*) malloc(sizeof(OLNode)); + if(p == NULL) { + exit(OVERFLOW); + } + + // 为结点赋值 + p->i = q->i; + p->j = q->j; + p->e = q->e; + p->right = p->down = NULL; + + /* + * 开始行的插入 + */ + + if(r == NULL) { + (*T).rhead[q->i] = p; + } else { + r->right = p; + } + + // r指向当前行新插入的结点 + r = p; + + /* + * 开始列的插入 + */ + + // 在列链中寻找插入位置 + if((*T).chead[q->j] == NULL || (*T).chead[q->j]->i > q->i) { + r->down = (*T).chead[q->j]; + (*T).chead[q->j] = r; + } else { + // 寻找插入位置的前一个位置 + for(l = (*T).chead[q->j]; (l->down) && (l->down->i < q->i); l = l->down) { + } + r->down = l->down; + l->down = r; + } + + q = q->right; + } + } + + return OK; +} + +/* + * 矩阵加法 + * + * Q = M + N。 + */ +Status AddSMatrix(CrossList M, CrossList N, CrossList* Q) { + int i; + OLNode* pm, * pn, * p, * r, * l; + + if(M.mu != N.mu || M.nu != N.nu) { + printf("两矩阵的行数、列数不满足相加条件!!\n"); + return ERROR; + } + + // 初始化Q的行列信息 + Q->mu = M.mu; + Q->nu = M.nu; + Q->tu = 0; + + // 创建行链(类似行索引,0号单元弃用) + Q->rhead = (OLink*) malloc((Q->mu + 1) * sizeof(OLink)); + if(!Q->rhead) { + exit(OVERFLOW); + } + + // 创建列链(类似列索引,0号单元弃用) + Q->chead = (OLink*) malloc((Q->nu + 1) * sizeof(OLink)); + if(!Q->chead) { + exit(OVERFLOW); + } + + // 初始化行链索引为NULL + for(i = 0; i <= Q->mu; ++i) { + Q->rhead[i] = NULL; + } + + // 初始化列链索引为NULL + for(i = 0; i <= Q->nu; ++i) { + Q->chead[i] = NULL; + } + + // 从第一行往下遍历 + for(i = 1; i <= M.mu; ++i) { + pm = M.rhead[i]; + pn = N.rhead[i]; + + // 如果M与N的当前行中均有未处理的非零元 + while(pm != NULL && pn != NULL) { + // 处理特殊情形 + if(pm->j == pn->j && pm->e + pn->e == 0) { + pm = pm->right; + pn = pn->right; + continue; + } + + // 创建结点 + p = (OLNode*) malloc(sizeof(OLNode)); + if(!p) { + exit(OVERFLOW); + } + + // M中的三元组列下标较小 + if(pm->j < pn->j) { + p->i = pm->i; + p->j = pm->j; + p->e = pm->e; + pm = pm->right; + + // N中的三元组列下标较小 + } else if(pm->j > pn->j) { + p->i = pn->i; + p->j = pn->j; + p->e = pn->e; + pn = pn->right; + + // M与N中的三元组列下标一致,需要进行加法运算 + } else { + p->i = pm->i; + p->j = pm->j; + p->e = pm->e + pn->e; + pm = pm->right; + pn = pn->right; + } + + p->right = p->down = NULL; + + Q->tu++; // Q中非零元个数增一 + + /* + * 开始行的插入 + */ + + if(Q->rhead[p->i] == NULL) { + Q->rhead[p->i] = p; + } else { + r->right = p; + } + + // r指向当前行新插入的结点 + r = p; + + /* + * 开始列的插入 + */ + + // 在列链中寻找插入位置 + if(Q->chead[p->j] == NULL || Q->chead[p->j]->i > p->i) { + r->down = Q->chead[p->j]; + Q->chead[p->j] = r; + } else { + // 寻找插入位置的前一个位置 + for(l = Q->chead[p->j]; (l->down) && (l->down->i < p->i); l = l->down) { + } + r->down = l->down; + l->down = r; + } + } + + // 如果M的当前行中仍有未处理的非零元 + while(pm != NULL) { + p = (OLNode*) malloc(sizeof(OLNode)); + if(p == NULL) { + exit(OVERFLOW); + } + p->i = pm->i; + p->j = pm->j; + p->e = pm->e; + p->right = p->down = NULL; + + Q->tu++; // Q中非零元个数增一 + + if(Q->rhead[p->i] == NULL) { + Q->rhead[p->i] = p; + } else { + r->right = p; + } + + // r指向当前行新插入的结点 + r = p; + + // 在列链中寻找插入位置 + if(Q->chead[p->j] == NULL || Q->chead[p->j]->i > p->i) { + r->down = Q->chead[p->j]; + Q->chead[p->j] = r; + } else { + // 寻找插入位置的前一个位置 + for(l = Q->chead[p->j]; (l->down) && (l->down->i < p->i); l = l->down) { + } + r->down = l->down; + l->down = r; + } + + pm = pm->right; + } + + // 如果N的当前行中仍有未处理的非零元 + while(pn != NULL) { + p = (OLNode*) malloc(sizeof(OLNode)); + if(p == NULL) { + exit(OVERFLOW); + } + p->i = pn->i; + p->j = pn->j; + p->e = pn->e; + p->right = p->down = NULL; + + Q->tu++; // Q中非零元个数增一 + + if(Q->rhead[p->i] == NULL) { + Q->rhead[p->i] = p; + } else { + r->right = p; + } + + // r指向当前行新插入的结点 + r = p; + + // 在列链中寻找插入位置 + if(Q->chead[p->j] == NULL || Q->chead[p->j]->i > p->i) { + r->down = Q->chead[p->j]; + Q->chead[p->j] = r; + } else { + // 寻找插入位置的前一个位置 + for(l = Q->chead[p->j]; (l->down) && (l->down->i < p->i); l = l->down) { + } + r->down = l->down; + l->down = r; + } + + pn = pn->right; + } + } + + return OK; +} + +/* + * 矩阵减法 + * + * Q = M - N。 + */ +Status SubSMatrix(CrossList M, CrossList N, CrossList* Q) { + int i; + OLNode* pm, * pn, * p, * r, * l; + + if(M.mu != N.mu || M.nu != N.nu) { + printf("两矩阵的行数、列数不满足相减条件!!\n"); + return ERROR; + } + + // 初始化Q的行列信息 + Q->mu = M.mu; + Q->nu = M.nu; + Q->tu = 0; + + // 创建行链(类似行索引,0号单元弃用) + Q->rhead = (OLink*) malloc((Q->mu + 1) * sizeof(OLink)); + if(!Q->rhead) { + exit(OVERFLOW); + } + + // 创建列链(类似列索引,0号单元弃用) + Q->chead = (OLink*) malloc((Q->nu + 1) * sizeof(OLink)); + if(!Q->chead) { + exit(OVERFLOW); + } + + // 初始化行链索引为NULL + for(i = 0; i <= Q->mu; ++i) { + Q->rhead[i] = NULL; + } + + // 初始化列链索引为NULL + for(i = 0; i <= Q->nu; ++i) { + Q->chead[i] = NULL; + } + + // 从第一行往下遍历 + for(i = 1; i <= M.mu; ++i) { + pm = M.rhead[i]; + pn = N.rhead[i]; + + // 如果M与N的当前行中均有未处理的非零元 + while(pm != NULL && pn != NULL) { + // 处理特殊情形 + if(pm->j == pn->j && pm->e - pn->e == 0) { + pm = pm->right; + pn = pn->right; + continue; + } + + // 创建结点 + p = (OLNode*) malloc(sizeof(OLNode)); + if(!p) { + exit(OVERFLOW); + } + + // M中的三元组列下标较小 + if(pm->j < pn->j) { + p->i = pm->i; + p->j = pm->j; + p->e = pm->e; + pm = pm->right; + + // N中的三元组列下标较小 + } else if(pm->j > pn->j) { + p->i = pn->i; + p->j = pn->j; + p->e = -pn->e; // 加负号 + pn = pn->right; + + // M与N中的三元组列下标一致,需要进行减法运算 + } else { + p->i = pm->i; + p->j = pm->j; + p->e = pm->e - pn->e; + pm = pm->right; + pn = pn->right; + } + + p->right = p->down = NULL; + + Q->tu++; // Q中非零元个数增一 + + /* + * 开始行的插入 + */ + + if(Q->rhead[p->i] == NULL) { + Q->rhead[p->i] = p; + } else { + r->right = p; + } + + // r指向当前行新插入的结点 + r = p; + + /* + * 开始列的插入 + */ + + // 在列链中寻找插入位置 + if(Q->chead[p->j] == NULL || Q->chead[p->j]->i > p->i) { + r->down = Q->chead[p->j]; + Q->chead[p->j] = r; + } else { + //寻找插入位置的前一个位置 + for(l = Q->chead[p->j]; (l->down) && (l->down->i < p->i); l = l->down) { + } + r->down = l->down; + l->down = r; + } + } + + // 如果M的当前行中仍有未处理的非零元 + while(pm != NULL) { + p = (OLNode*) malloc(sizeof(OLNode)); + if(!p) { + exit(OVERFLOW); + } + p->i = pm->i; + p->j = pm->j; + p->e = pm->e; + p->right = p->down = NULL; + + Q->tu++; // Q中非零元个数增一 + + if(Q->rhead[p->i] == NULL) { + Q->rhead[p->i] = p; + } else { + r->right = p; + } + + // r指向当前行新插入的结点 + r = p; + + // 在列链中寻找插入位置 + if(Q->chead[p->j] == NULL || Q->chead[p->j]->i > p->i) { + r->down = Q->chead[p->j]; + Q->chead[p->j] = r; + } else { + // 寻找插入位置的前一个位置 + for(l = Q->chead[p->j]; (l->down) && (l->down->i < p->i); l = l->down) { + } + r->down = l->down; + l->down = r; + } + + pm = pm->right; + } + + // 如果N的当前行中仍有未处理的非零元 + while(pn != NULL) { + p = (OLNode*) malloc(sizeof(OLNode)); + if(!p) { + exit(OVERFLOW); + } + p->i = pn->i; + p->j = pn->j; + p->e = -pn->e; // 加负号 + p->right = p->down = NULL; + + Q->tu++; // Q中非零元个数增一 + + if(Q->rhead[p->i] == NULL) { + Q->rhead[p->i] = p; + } else { + r->right = p; + } + + // r指向当前行新插入的结点 + r = p; + + // 在列链中寻找插入位置 + if(Q->chead[p->j] == NULL || Q->chead[p->j]->i > p->i) { + r->down = Q->chead[p->j]; + Q->chead[p->j] = r; + } else { + // 寻找插入位置的前一个位置 + for(l = Q->chead[p->j]; (l->down) && (l->down->i < p->i); l = l->down) { + } + r->down = l->down; + l->down = r; + } + + pn = pn->right; + } + } + + return OK; +} + +/* + * 矩阵乘法 + * + * Q = M * N。 + */ +Status MultSMatrix(CrossList M, CrossList N, CrossList* Q) { + int m_row, n_col, i; + ElemType e; + OLNode* pm, * pn, * p, * r, * l; + + // M的列数需要等于N的行数 + if(M.nu != N.mu) { + printf("两矩阵的行数、列数不满足相乘条件!!\n"); + return ERROR; + } + + // 初始化Q的行列信息 + Q->mu = M.mu; + Q->nu = N.nu; + Q->tu = 0; + + // 创建行链(类似行索引,0号单元弃用) + Q->rhead = (OLink*) malloc((Q->mu + 1) * sizeof(OLink)); + if(!Q->rhead) { + exit(OVERFLOW); + } + + // 创建列链(类似列索引,0号单元弃用) + Q->chead = (OLink*) malloc((Q->nu + 1) * sizeof(OLink)); + if(!Q->chead) { + exit(OVERFLOW); + } + + // 初始化行链索引为NULL + for(i = 0; i <= Q->mu; ++i) { + Q->rhead[i] = NULL; + } + + // 初始化列链索引为NULL + for(i = 0; i <= Q->nu; ++i) { + Q->chead[i] = NULL; + } + + // Q是非零矩阵 + if(M.tu * N.tu) { + for(m_row = 1; m_row <= M.mu; ++m_row) { + for(n_col = 1; n_col <= N.nu; ++n_col) { + pm = M.rhead[m_row]; + pn = N.chead[n_col]; + + e = 0; + + // M的行与N的列相乘 + while(pm && pn) { + if(pm->j < pn->i) { + pm = pm->right; + } else if(pm->j > pn->i) { + pn = pn->down; + } else { + e += pm->e * pn->e; + pm = pm->right; + pn = pn->down; + } + } + + if(e == 0) { + continue; + } + + p = (OLNode*) malloc(sizeof(OLNode)); + if(!p) { + exit(OVERFLOW); + } + + // 为结点赋值 + p->i = M.rhead[m_row]->i; + p->j = N.chead[n_col]->j; + p->e = e; + p->right = p->down = NULL; + + Q->tu++; // Q中非零元个数增一 + + if(Q->rhead[p->i] == NULL) { + Q->rhead[p->i] = p; + } else { + r->right = p; + } + + // r指向当前行新插入的结点 + r = p; + + // 在列链中寻找插入位置 + if(Q->chead[p->j] == NULL || Q->chead[p->j]->i > p->i) { + r->down = Q->chead[p->j]; + Q->chead[p->j] = r; + } else { + // 寻找插入位置的前一个位置 + for(l = Q->chead[p->j]; (l->down) && (l->down->i < p->i); l = l->down) { + } + + r->down = l->down; + l->down = r; + } + } + } + } + + return OK; +} + +/* + * 矩阵转置 + */ +Status TransposeSMatrix(CrossList M, CrossList* T) { + int i; + OLNode* p, * q, * r, * l; + + // 初始化Q的行列信息 + (*T).mu = M.nu; + (*T).nu = M.mu; + (*T).tu = M.tu; + + // 创建行链(类似行索引,0号单元弃用) + (*T).rhead = (OLink*) malloc(((*T).mu + 1) * sizeof(OLink)); + if(!(*T).rhead) { + exit(OVERFLOW); + } + + // 创建列链(类似列索引,0号单元弃用) + (*T).chead = (OLink*) malloc(((*T).nu + 1) * sizeof(OLink)); + if(!(*T).chead) { + exit(OVERFLOW); + } + + // 初始化行链索引为NULL + for(i = 0; i <= (*T).mu; ++i) { + (*T).rhead[i] = NULL; + } + + // 初始化列链索引为NULL + for(i = 0; i <= (*T).nu; ++i) { + (*T).chead[i] = NULL; + } + + // 零矩阵 + if(!(*T).tu) { + return OK; + } + + // 按列扫描 + for(i = 1; i <= M.nu; ++i) { + q = M.chead[i]; + + // 如果当前行没有元素,直接跳过 + if(q == NULL) { + continue; + } + + while(q != NULL) { + // 创建三元组结点 + p = (OLNode*) malloc(sizeof(OLNode)); + if(!p) { + exit(OVERFLOW); + } + + // 为结点赋值,行变列,列变行 + p->i = q->j; + p->j = q->i; + p->e = q->e; + p->right = p->down = NULL; + + /* + * 开始行的插入 + */ + + if((*T).rhead[p->i] == NULL) { + (*T).rhead[p->i] = p; + } else { + r->right = p; + } + + // r指向当前行新插入的结点 + r = p; + + /* + * 开始列的插入 + */ + + // 在列链中寻找插入位置 + if((*T).chead[p->j] == NULL || (*T).chead[p->j]->i > p->i) { + r->down = (*T).chead[p->j]; + (*T).chead[p->j] = r; + } else { + // 寻找插入位置的前一个位置 + for(l = (*T).chead[p->j]; (l->down) && (l->down->i < p->i); l = l->down) { + } + r->down = l->down; + l->down = r; + } + + q = q->down; + } + } + + return OK; +} + +/* + * 输出矩阵 + */ +void PrintSMatrix(CrossList M) { + int i, j; + OLNode* p; + + for(i = 1; i <= M.mu; ++i) { + p = M.rhead[i]; + for(j = 1; j <= M.nu; ++j) { + if(p && p->j == j) { + printf("%3d ", p->e); + p = p->right; + } else { + printf("%3d ", 0); + } + } + printf("\n"); + } +} diff --git a/CLion/ExerciseBook/05.27/CrossList.h b/CLion/ExerciseBook/05.27/CrossList.h new file mode 100644 index 0000000..deb950e --- /dev/null +++ b/CLion/ExerciseBook/05.27/CrossList.h @@ -0,0 +1,94 @@ +/*=================== + * 十字链表(稀疏矩阵) + * + * 包含算法: 5.4 + ====================*/ + +#ifndef CROSSLIST_H +#define CROSSLIST_H + +#include +#include // 提供malloc、realloc、free、exit原型 +#include // 提供 strstr 原型 +#include "Status.h" //**▲01 绪论**// + +/* 十字链表元素类型 */ +typedef int ElemType; + +/* 非零元类型定义 */ +typedef struct OLNode { + int i, j; // 该非零元的行下标和列下标 + ElemType e; + struct OLNode* right; // 该非零元所在的行表的后继链域 + struct OLNode* down; // 该非零元所在的列表的后继链域 +} OLNode, * OLink; + +/* 十字链表类型定义 */ +typedef struct { + OLink* rhead; // 行链表头指针 + OLink* chead; // 列链表头指针 + int mu, nu, tu; // 矩阵的行数、列数和非零元个数 +} CrossList; + + +/* + * ████████ 算法5.4 ████████ + * + * 创建稀疏矩阵M + * + * + *【备注】 + * + * 教材中默认从控制台读取数据。 + * 这里为了方便测试,避免每次运行都手动输入数据, + * 因而允许选择从预设的文件path中读取测试数据。 + * + * 如果需要从控制台读取数据,则path为NULL或者为空串, + * 如果需要从文件中读取数据,则需要在path中填写文件名信息。 + */ +Status CreateSMatrix(CrossList* M, char* path); + +/* + * 销毁稀疏矩阵 + */ +Status DestroySMatrix(CrossList* M); + +/* + * 矩阵复制 + * + * 创建一个新矩阵T,该矩阵包含了从矩阵M中包含的数据。 + */ +Status CopySMatrix(CrossList M, CrossList* T); + +/* + * 矩阵加法 + * + * Q = M + N。 + */ +Status AddSMatrix(CrossList M, CrossList N, CrossList* Q); + +/* + * 矩阵减法 + * + * Q = M - N。 + */ +Status SubSMatrix(CrossList M, CrossList N, CrossList* Q); + +/* + * 矩阵乘法 + * + * Q = M * N。 + */ +Status MultSMatrix(CrossList M, CrossList N, CrossList* Q); + +/* + * 矩阵转置 + */ +Status TransposeSMatrix(CrossList M, CrossList* T); + +/* + * 输出矩阵 + */ +void PrintSMatrix(CrossList M); + +#endif diff --git a/CLion/ExerciseBook/05.27/TestData_M.txt b/CLion/ExerciseBook/05.27/TestData_M.txt new file mode 100644 index 0000000..5d3cb45 --- /dev/null +++ b/CLion/ExerciseBook/05.27/TestData_M.txt @@ -0,0 +1,4 @@ +行数:5 +列数:5 +非零元个数:10 +三元组:(1,2,1),(1,4,5),(2,3,-3),(2,5,2),(3,1,2),(3,2,3),(3,3,4),(4,4,2),(5,1,3),(5,2,-1) \ No newline at end of file diff --git a/CLion/ExerciseBook/05.27/TestData_N.txt b/CLion/ExerciseBook/05.27/TestData_N.txt new file mode 100644 index 0000000..d567717 --- /dev/null +++ b/CLion/ExerciseBook/05.27/TestData_N.txt @@ -0,0 +1,4 @@ +行数:5 +列数:5 +非零元个数:8 +三元组:(1,1,-3)(1,3,2)(2,4,-1)(3,2,4)(4,1,6)(4,5,5)(5,1,3)(5,3,2) \ No newline at end of file diff --git a/CLion/ExerciseBook/05.28-05.29/05.28-05.29.c b/CLion/ExerciseBook/05.28-05.29/05.28-05.29.c new file mode 100644 index 0000000..7a00901 --- /dev/null +++ b/CLion/ExerciseBook/05.28-05.29/05.28-05.29.c @@ -0,0 +1,336 @@ +#include +#include "MPList.h" //**▲05 数组和广义表**// + +/* + * 求m元多项式P中第一变元的偏导函数PD。 + * + * 这里预设第一元为最外部的项 + */ +Status Algo_5_28(MPList P, MPList* PD); + +/* + * 将指数exp乘到多项式P的原子结点的系数上 + */ +static void HandleExp(MPList P, int exp); + +/* + * 多项式加法:R = P + Q + */ +Status Algo_5_29(MPList P, MPList Q, MPList* R); + +/* + * 对非空的对多项式P和Q相加,P和Q指向的是各元列表的头结点。 + */ +static void AddMpList(MPList P, MPList Q, MPList* R); + +/* + * 视需求创建一个新结点。 + * 如果tp不为NULL,为原子结点添加一个头结点,否则,为子表结点添加头结点。 + * 变量v作为所创建的头结点的元标记 + */ +static MPList VirtualNode(int v, MPList tp, MPList hp); + + +int main(int argc, char* argv[]) { + MPList P, Q; + MPList PD, QD; + MPList R; + char *p = "z((3,y((1,x((3, 1))))),(2,y((2,1))),(0,3))"; + char *q = "z((4,1),(3,y((1,x((3,-1))))),(2,x((1,1))),(0,y((1,1),(0,4))))"; + + printf("创建三元多项式...\n"); + CreateMPList(&P, p, "zyx"); + printf("P = "); + PrintGraph(P); + CreateMPList(&Q, q, "zyx"); + printf("Q = "); + PrintGraph(Q); + + // 求第一元的偏导数 + printf("P' = "); + Algo_5_28(P, &PD); + PrintGraph(PD); + printf("Q' = "); + Algo_5_28(Q, &QD); + PrintGraph(QD); + + // 多项式加法 + printf("R = "); + Algo_5_29(P, Q, &R); + PrintGraph(R); +} + + +/* + * 求m元多项式P中第一变元的偏导函数PD。 + * + * 这里预设第一元为最外部的项 + */ +Status Algo_5_28(MPList P, MPList* PD) { + MPList r, rd, s; + int count; + + if(P == NULL || PD == NULL) { + return ERROR; + } + + // 创建多项式 + *PD = (MPList) malloc(sizeof(MPNode)); + (*PD)->tag = List; + (*PD)->exp = P->exp; + (*PD)->tp = NULL; + + // 创建头结点 + (*PD)->Node.hp = (MPList) malloc(sizeof(MPNode)); + (*PD)->Node.hp->tag = P->Node.hp->tag; + (*PD)->Node.hp->exp = P->Node.hp->exp; + (*PD)->Node.hp->Node.hp = P->Node.hp->Node.hp; + + r = P->Node.hp; // 指向P的头结点 + rd = (*PD)->Node.hp; // 指向PD的头结点 + count = 0; + + // 遍历第一元的列表 + while(r->tp != NULL) { + r = r->tp; + + // 如果没有遇到"常数"结点,或者,多项式P仅有一个"常数"结点 + if(r->exp!=0 || count==0) { + rd->tp = (MPList) malloc(sizeof(MPNode)); + rd = rd->tp; + } + + /* + * 遇到"常数"结点,则求导后变为0 + * 注:"常数"结点指数为0,其排在最后 + */ + if(r->exp == 0) { + // 如果多项式P仅有一个"常数"结点 + if(count==0) { + rd->tag = Atom; + rd->exp = 0; + rd->Node.coef = 0; + } + + break; + } + + rd->tag = r->tag; + rd->exp = r->exp - 1; + + // 如果是原子结点,直接计算新系数 + if(r->tag==Atom) { + rd->Node.coef = r->Node.coef * r->exp; // 指数域系数相乘 + + // 如果是子表结点,需要将指数乘到合适的位置 + } else { + Copy(r->Node.hp, &(rd->Node.hp)); + + // 指数为1时,是没必要乘的 + if(r->exp!=1) { + // 将指数exp乘到多项式P的原子结点的系数上 + HandleExp(rd->Node.hp, r->exp); + } + } + + count++; + } + + rd->tp = NULL; + + return OK; +} + +/* + * 将指数exp乘到多项式P的原子结点的系数上 + */ +static void HandleExp(MPList P, int exp) { + MPList r; + + if(P == NULL) { + return; + } + + for(r = P->tp; r != NULL; r = r->tp) { + if(r->tag == Atom) { + r->Node.coef *= exp; + } else { + HandleExp(r->Node.hp, exp); + } + } +} + +/* + * 多项式加法:R = P + Q + */ +Status Algo_5_29(MPList P, MPList Q, MPList* R) { + MPList r; + + // 要求两个多项式的元相等 + if(P == NULL || Q == NULL || R==NULL || P->exp != Q->exp) { + return ERROR; + } + + // 创建多项式 + *R = (MPList) malloc(sizeof(MPNode)); + if(*R == NULL) { + exit(OVERFLOW); + } + (*R)->tag = List; + (*R)->exp = P->exp; // 多项式的元数量不变 + (*R)->tp = NULL; + + AddMpList(P->Node.hp, Q->Node.hp, &r); + + if(r->tp == NULL) { + r->tp = (MPList) malloc(sizeof(MPNode)); + r->tp->tag = Atom; + r->tp->exp = 0; + r->tp->Node.coef = 0.0f; + r->tp->tp = NULL; + } + + (*R)->Node.hp = r; + + return OK; +} + +/* + * 对非空的对多项式P和Q相加,P和Q指向的是各元列表的头结点。 + */ +static void AddMpList(MPList P, MPList Q, MPList* R) { + MPList p, q, h, r; + MPList t; + MPList tp; + float sum; + int a, b; + int v; + + // 如果不是同一个元 + if(P->exp!=Q->exp) { + + a = (int)(strchr(Var, P->exp)-Var); + b = (int)(strchr(Var, Q->exp)-Var); + + if(aexp, NULL, Q); + v = P->exp; + } + + if(a>b) { + P = VirtualNode(Q->exp, NULL, P); + v = Q->exp; + } + } else { + v = P->exp; + } + + // 创建头结点 + *R = (MPList) malloc(sizeof(MPNode)); + (*R)->tag = List; + (*R)->exp = v; + (*R)->Node.hp =NULL; + + h = *R; + + p = P->tp; + q = Q->tp; + + while(p!=NULL && q!=NULL){ + if(p->exp>q->exp) { + tp = p->tp; + p->tp = NULL; + Copy(p, &(h->tp)); + p->tp = tp; + p = p->tp; + h = h->tp; + } else if(p->expexp) { + tp = q->tp; + q->tp = NULL; + Copy(q, &(h->tp)); + q->tp = tp; + q = q->tp; + h = h->tp; + + // 指数相同 + } else { + sum = 0.0f; // 初始化系数和,不一定用得上 + r = NULL; + + if(p->tag==Atom && q->tag==List) { + t = VirtualNode(q->Node.hp->exp, p, NULL); + tp = p->tp; + p->tp = NULL; + AddMpList(t, q->Node.hp, &r); + p->tp = tp; + } else if(p->tag==List && q->tag==Atom) { + t = VirtualNode(p->Node.hp->exp, q, NULL); + tp = q->tp; + q->tp = NULL; + AddMpList(p->Node.hp, t, &r); + q->tp = tp; + + // 都是子表 + } else if(p->tag==List && q->tag==List) { + AddMpList(p->Node.hp, q->Node.hp, &r); + + // 都是原子的话,可以直接相加 + } else if(p->tag==Atom && q->tag==Atom) { + sum = p->Node.coef + q->Node.coef; + } + + if(sum!=0.0f || (r!=NULL && r->tp!=NULL)) { + h->tp = (MPList) malloc(sizeof(MPNode)); + h = h->tp; + h->exp = p->exp; + + if(sum!=0.0f) { + h->tag = Atom; + h->Node.coef = sum; + } else { + h->tag = List; + h->Node.hp = r; + } + } + + p = p->tp; + q = q->tp; + } + } + + h->tp = NULL; + + if(p!=NULL){ + Copy(p, &(h->tp)); + } + + if(q!=NULL){ + Copy(q, &(h->tp)); + } +} + +/* + * 视需求创建一个新结点。 + * 如果tp不为NULL,为原子结点添加一个头结点,否则,为子表结点添加头结点。 + * 变量v作为所创建的头结点的元标记 + */ +static MPList VirtualNode(int v, MPList tp, MPList hp){ + MPList P; + + P = (MPList) malloc(sizeof(MPNode)); + P->tag = List; + P->exp = v; + P->Node.hp = NULL; + + if(tp!=NULL) { + P->tp = tp; + } else { + P->tp = (MPList) malloc(sizeof(MPNode)); + P->tp->exp = 0; + P->tp->tag = List; + P->tp->Node.hp = hp; + P->tp->tp = NULL; + } + + return P; +} diff --git a/CLion/ExerciseBook/05.28-05.29/CMakeLists.txt b/CLion/ExerciseBook/05.28-05.29/CMakeLists.txt new file mode 100644 index 0000000..20db9a4 --- /dev/null +++ b/CLion/ExerciseBook/05.28-05.29/CMakeLists.txt @@ -0,0 +1,7 @@ +# 包含公共库 +include_directories(${CMAKE_SOURCE_DIR}/Status) + +# 生成可执行文件 +add_executable(05.28-05.29 StringUtil.h StringUtil.c MPList.h MPList.c 05.28-05.29.c) +# 链接公共库 +target_link_libraries(05.28-05.29 Scanf_lib) \ No newline at end of file diff --git a/CLion/ExerciseBook/05.28-05.29/MPList.c b/CLion/ExerciseBook/05.28-05.29/MPList.c new file mode 100644 index 0000000..bccdc6b --- /dev/null +++ b/CLion/ExerciseBook/05.28-05.29/MPList.c @@ -0,0 +1,233 @@ +/*========== + * m元多项式 + ===========*/ + +#include "MPList.h" + +// 参见头文件中的声明 +char Var[27]; + +/* + * 创建 + * + * 由字符串S创建m元多项P。 + * 不会校验S是否书写正确。 + * + * P : 待建的多项式 + * S : 多项式字符串 + * vars: 变量列表,从第一元开始排列,比如xyz代表三元多项式中的未知数标记 + */ +Status CreateMPList(MPList* P, char* S, char* vars) { + if(P == NULL) { + return ERROR; + } + + // 清理字符串S中的空白,包括清理不可打印字符和清理空格 + ClearBlank(&S); + + if(strlen(S) == 0) { + *P = NULL; + return ERROR; + } + + // 初始化元信息 + strcpy(Var, vars); + + *P = (MPList) malloc(sizeof(MPNode)); + if(*P == NULL) { + exit(OVERFLOW); + } + + (*P)->tag = List; + (*P)->exp = (int) strlen(vars); + (*P)->tp = NULL; + + Create(&(*P)->Node.hp, S); + + return OK; +} + +/* + * m元多项式创建函数 + */ +static Status Create(MPList* P, char* S) { + char* Sc; + char* hhstr, * hstr, * str; + char* sub; + MPList r; + float f; + + // 获取S的一个副本 + SubString(&Sc, S, 1, (int) strlen(S)); + + *P = (MPList) malloc(sizeof(MPNode)); + if(*P == NULL) { + exit(OVERFLOW); + } + + (*P)->tag = List; + (*P)->exp = (int) Sc[0]; // 记下未知数标记,例如x、y、z + (*P)->Node.hp = NULL; + (*P)->tp = NULL; + + StrDelete(&Sc, 1, 1); // 删掉未知数标记 + SubString(&str, Sc, 2, (int) strlen(Sc) - 2); // 脱去最外层括号 + + r = *P; + + while(!StrEmpty(str)) { + // 拆分 + sever(&hstr, &str); + + SubString(&sub, hstr, 2, (int) strlen(hstr) - 2); // 脱去最外层括号 + sever(&hhstr, &sub); + + // 建立子结点 + r->tp = (MPList) malloc(sizeof(MPNode)); + if(r->tp == NULL) { + exit(OVERFLOW); + } + GetElem(hhstr, 1, &f); + r->tp->exp = (int) f; // 获取指数 + r->tp->tp = NULL; + + if(ElemCount(sub) == 1) { + r->tp->tag = Atom; + GetElem(sub, 1, &f); + r->tp->Node.coef = f; + } else { + r->tp->tag = List; + Create(&(r->tp->Node.hp), sub); + } + + r = r->tp; + } + + return OK; +} + +/* + * 图形化输出 + * + * 带括号输出m元多项P。 + */ +void PrintGraph(MPList P) { + if(P == NULL) { + printf("\n"); + return; + } + Print(P->Node.hp); + printf("\n"); +} + +/* + * 图形化输出的内部实现 + */ +static void Print(MPList head) { + MPList p; + + if(head == NULL) { + return; + } + + printf("%c(", head->exp); + + p = head->tp; + + while(p != NULL) { + printf("(%d,", p->exp); + + if(p->tag == List) { + Print(p->Node.hp); + } else { + printf("%.2f", p->Node.coef); + } + + printf(")"); + + p = p->tp; + + if(p != NULL) { + printf(","); + } + } + + printf(")"); +} + +/* + * 将非空串str分割成两部分:hsub为第一个','之前的子串,str为第一个','之后的子串。 + * + *【注】 + * 1.这里假设字符串str输入正确,其中无空白符号,且str【已经脱去最外层括号】。 + * 2.分离完成后,str也会发生变化 + */ +static void sever(char** hstr, char** str) { + int i, k, n; + + char* head, * tail; + + // str为空时,hstr也为空 + if(strlen(*str) == 0) { + *hstr = NULL; + return; + } + + n = (int) strlen(*str); + + i = 0; // 遍历字符串时的游标 + k = 0; // 标记遇到的未配对括号数量 + + do { + if((*str)[i] == '(') { + ++k; + } + + if((*str)[i] == ')') { + --k; + } + + i++; + } while(i < n && ((*str)[i] != ',' || k != 0)); + + if(i < n) { + head = (char*) malloc((i + 1) * sizeof(char)); + tail = (char*) malloc((n - i - 1 + 1) * sizeof(char)); + + strncpy(head, *str, i); + head[i] = '\0'; + + strncpy(tail, (*str + i + 1), n - i - 1); + tail[n - i - 1] = '\0'; + } else { + head = *str; + tail = (char*) malloc(sizeof(char)); + tail[0] = '\0'; + } + + *hstr = head; + *str = tail; +} + + +/* + * 复制多项式,从P复制到Q + */ +void Copy(MPList P, MPList* Q) { + if(P == NULL) { + *Q = NULL; + return; + } + + *Q = (MPList) malloc(sizeof(MPNode)); + (*Q)->tag = P->tag; + (*Q)->exp = P->exp; + + if(P->tag == List) { + Copy(P->Node.hp, &((*Q)->Node.hp)); + } else { + (*Q)->Node.coef = P->Node.coef; + } + + Copy(P->tp, &((*Q)->tp)); +} diff --git a/CLion/ExerciseBook/05.28-05.29/MPList.h b/CLion/ExerciseBook/05.28-05.29/MPList.h new file mode 100644 index 0000000..1ca2056 --- /dev/null +++ b/CLion/ExerciseBook/05.28-05.29/MPList.h @@ -0,0 +1,97 @@ +/*========== + * m元多项式 + ===========*/ + +#ifndef MPLIST_H +#define MPLIST_H + +#include +#include // 提供 malloc、realloc、free、exit 原型 +#include // 提供 strlen 原型 +#include "Status.h" //**▲01 绪论**// +#include "StringUtil.h" //**字符串工具类**// + +/* + * ████ 提示 ████ + * + * 1.对于多元函数,约定第一元位于最外层。 + * 2.未知数标记默认为a~z或A~Z这26个字母 + * 3.约定多项式的每个元其指数是【递减】的,如3、2、1 + */ + + +/* + * 储存当前多项式的遍历信息,如x、y、z等 + * 约定var中的字符顺序即位各元的次序,如: + * "zyx"指示z为第一元,y为第二元,x为第三元 + */ +extern char Var[27]; + +/* + * m元多项式结点标记 + * + * Atom-0:原子结点 + * List-1:表结点 + */ +typedef enum { Atom, List } ElemTag; + +/* m元多项式元素结点 */ +typedef struct MPNode { + ElemTag tag; // 区分原子结点和表结点 + int exp; // 指数域,对于头结点,存储未知数标记,如x、y、z等 + union { + float coef; // 系数域 + struct MPNode* hp; // 表结点的表头指针 + } Node; + struct MPNode* tp; // 相当于线性链表的next,指向下一个元素结点 +} MPNode; + +/* m元多项式广义表类型 */ +typedef MPNode* MPList; + + +/* + * 创建 + * + * 由字符串S创建m元多项P。 + * 不会校验S是否书写正确。 + * + * P : 待建的多项式 + * S : 多项式字符串 + * vars: 变量列表,从第一元开始排列,比如xyz代表三元多项式中的未知数标记 + */ +Status CreateMPList(MPList* P, char* S, char* vars); + +/* + * m元多项式创建函数 + */ +static Status Create(MPList* P, char* S); + +/* + * 图形化输出 + * + * 带括号输出m元多项P。 + */ +void PrintGraph(MPList P); + +/* + * 图形化输出的内部实现 + */ +static void Print(MPList P); + +/* + * 将非空串str分割成两部分:hsub为第一个','之前的子串,str为第一个','之后的子串。 + * + *【注】 + * 1.这里假设字符串str输入正确,其中无空白符号,且str【已经脱去最外层括号】。 + * 2.分离完成后,str也会发生变化 + */ +static void sever(char** hstr, char** str); + + +/* + * 复制多项式 + */ +void Copy(MPList P, MPList* Q); + +#endif diff --git a/CLion/ExerciseBook/05.28-05.29/StringUtil.c b/CLion/ExerciseBook/05.28-05.29/StringUtil.c new file mode 100644 index 0000000..d0981b8 --- /dev/null +++ b/CLion/ExerciseBook/05.28-05.29/StringUtil.c @@ -0,0 +1,160 @@ +/*================ + * 字符串操作工具类 + =================*/ + +#include "StringUtil.h" + +/* + * 删除 + * + * 删除s[pos, pos+len-1],pos从1开始计数。 + */ +Status StrDelete(char** s, int pos, int n) { + int len; + char* ss; + + len = (int) strlen(*s); + + if(pos < 1 || pos + n - 1 > len || n < 0) { + return ERROR; + } + + // 如果待删除的长度为0,则提前返回 + if(n == 0) { + return ERROR; + } + + ss = (char*) malloc((len - n + 1) * sizeof(char)); + + strncpy(ss, *s, pos - 1); + strncpy(ss, *s + pos + n - 1, len - pos - n + 1); + + ss[len - n] = '\0'; + + *s = ss; + + return OK; +} + +/* + * 求子串 + * + * 用sub返回s[pos, pos+len-1],pos从1开始计数。 + */ +Status SubString(char** sub, char* s, int pos, int n) { + int len, i; + + len = (int) strlen(s); + + if(pos < 1 || pos > len || n < 0 || pos + n - 1 > len) { + *sub = NULL; + return ERROR; + } + + *sub = (char*) malloc((n + 1) * sizeof(char)); + + for(i = 0; i < n; i++) { + (*sub)[i] = s[pos + i - 1]; + } + + // 确定新长度 + (*sub)[n] = '\0'; + + return OK; +} + +/* + * 判空 + * + * 判断串s中是否包含有效数据。 + */ +Status StrEmpty(char* s) { + return strlen(s) == 0 ? TRUE : FALSE; +} + +/* + * 整理 + * + * 清理字符串s中的空白,包括清理不可打印字符和清理空格。 + */ +Status ClearBlank(char** s) { + int len; + int i, j; + char* ss; + + len = (int) strlen(*s); + if(len == 0) { + return ERROR; + } + + ss = (char*) malloc((len + 1) * sizeof(char)); + + for(i = 0, j = 0; i < len; i++) { + // 如果遇到空白,则略过 + if((*s)[i] == ' ' || !isprint((*s)[i])) { + continue; + } + + ss[j++] = (*s)[i]; + } + + ss[j] = '\0'; + + *s = ss; + + return OK; +} + +/* + * 计数 + * + * 统计字符串s中的元素个数。 + * 这里的特殊之处在于:对于数字,会将其当成一个元素。 + */ +int ElemCount(const char* s) { + int count; + float f; + char c; + char* sub; + + if(s==NULL || strlen(s) == 0) { + return 0; + } + + sub = (char*) malloc((strlen(s) + 1) * sizeof(char)); + sub[0] = '\0'; + + // 如果遇到了数字 + if(sscanf(s, "%f", &f) == 1) { + sscanf(s, "%f%s", &f, sub); + } else { + sscanf(s, "%c%s", &c, sub); + } + + count = ElemCount(sub); + + return 1 + count; +} + +/* + * 取值 + * + * 获取字符串s中第pos个元素(pos从1开始计数),并用f接收。 + * 这里的特殊之处在于:对于数字,会将其当成一个元素。 + */ +Status GetElem(char* s, int pos, float* f) { + int len; + + len = (int) strlen(s); + + if(pos < 1 || pos > len) { + return ERROR; + } + + // 先尝试读数字,读取失败的话,再尝试读字符 + if(sscanf(s + pos - 1, "%f", f) < 1) { + *f = s[pos - 1]; + } + + return OK; +} diff --git a/CLion/ExerciseBook/05.28-05.29/StringUtil.h b/CLion/ExerciseBook/05.28-05.29/StringUtil.h new file mode 100644 index 0000000..4d3cc7c --- /dev/null +++ b/CLion/ExerciseBook/05.28-05.29/StringUtil.h @@ -0,0 +1,58 @@ +/*================ + * 字符串操作工具类 + =================*/ + +#ifndef STRINGUTIL_H +#define STRINGUTIL_H + +#include +#include // 提供 malloc 原型 +#include // 提供 strlen、strncpy 原型 +#include // 提供 isprint 原型 +#include "Status.h" //**▲01 绪论**// + +/* + * 删除 + * + * 删除s[pos, pos+len-1],pos从1开始计数。 + */ +Status StrDelete(char** S, int pos, int n); + +/* + * 求子串 + * + * 用sub返回s[pos, pos+len-1],pos从1开始计数。 + */ +Status SubString(char** sub, char* s, int pos, int len); + +/* + * 判空 + * + * 判断串s中是否包含有效数据。 + */ +Status StrEmpty(char* s); + +/* + * 整理 + * + * 清理字符串s中的空白,包括清理不可打印字符和清理空格。 + */ +Status ClearBlank(char** s); + +/* + * 计数 + * + * 统计字符串s中的元素个数。 + * 这里的特殊之处在于:对于数字,会将其当成一个元素。 + */ +int ElemCount(const char* s); + +/* + * 取值 + * + * 获取字符串s中第pos个元素(pos从1开始计数),并用f接收。 + * 这里的特殊之处在于:对于数字,会将其当成一个元素。 + */ +Status GetElem(char* s, int pos, float *f); + +#endif diff --git a/CLion/ExerciseBook/05.30.1/05.30.1.c b/CLion/ExerciseBook/05.30.1/05.30.1.c new file mode 100644 index 0000000..527fc7b --- /dev/null +++ b/CLion/ExerciseBook/05.30.1/05.30.1.c @@ -0,0 +1,42 @@ +#include +#include "SString.h" //**▲04 串**// +#include "GList-HT.h" //**▲05 数组和广义表**// + +// 求广义表深度(头尾链表存储表示) +int Algo_5_30_1(GList L); + + +int main(int argc, char* argv[]) { + GList L; + char* s = "((),(e),(a,(b,c,d)))"; + SString S; + + printf("创建广义表 L ...\n"); + StrAssign(S, s); + CreateGList(&L, S); + printf("L = "); + PrintGraph(L); + + printf("广义表深度为: %d\n", Algo_5_30_1(L)); + + return 0; +} + + +// 求广义表深度(头尾链表存储表示) +int Algo_5_30_1(GList L) { + int m, n; + + if(L==NULL) { + return 1; // 空表深度为1 + } + + if(L->tag == Atom) { + return 0; // 原子深度为0 + } + + m = Algo_5_30_1(L->Node.ptr.hp) + 1; + n = Algo_5_30_1(L->Node.ptr.tp); + + return m > n ? m : n; +} diff --git a/CLion/ExerciseBook/05.30.1/CMakeLists.txt b/CLion/ExerciseBook/05.30.1/CMakeLists.txt new file mode 100644 index 0000000..0a489b4 --- /dev/null +++ b/CLion/ExerciseBook/05.30.1/CMakeLists.txt @@ -0,0 +1,7 @@ +# 包含公共库 +include_directories(${CMAKE_SOURCE_DIR}/Status) + +# 生成可执行文件 +add_executable(05.30.1 SString.h SString.c GList-HT.h GList-HT.c 05.30.1.c) +# 链接公共库 +target_link_libraries(05.30.1 Scanf_lib) \ No newline at end of file diff --git a/CLion/ExerciseBook/05.30.1/GList-HT.c b/CLion/ExerciseBook/05.30.1/GList-HT.c new file mode 100644 index 0000000..ddf2766 --- /dev/null +++ b/CLion/ExerciseBook/05.30.1/GList-HT.c @@ -0,0 +1,418 @@ +/*============================ + * 广义表的头尾链表存储表示 + * + * 包含算法: 5.5、5.6、5.7、5.8 + =============================*/ + +#include "GList-HT.h" //**▲05 数组和广义表**// + +/* + * 初始化 + * + * 初始化空的广义表,长度为0,深度为1。 + * + *【注】 + * 需要对每一层去掉括号考察 + */ +Status InitGList(GList* L) { + if(L == NULL) { + return ERROR; + } + + *L = NULL; + + return OK; +} + +/* + * ████████ 算法5.7 ████████ + * + * 创建 + * + * 由字符串S创建广义表L。 + */ +Status CreateGList(GList* L, SString S) { + SString emp; // 代表空广义表的字符串 + SString hsub, sub; + GList p, q; + + if(L == NULL) { + return ERROR; + } + + // 清理字符串S中的空白,包括清理不可打印字符和清理空格 + ClearBlank(S); + + if(StrEmpty(S)) { + return ERROR; + } + + StrAssign(emp, "()"); + + /* + * 如果输入串为(),则代表需要创建空的广义表 + * + *【注】 + * 教材这里的代码是有问题的。 + * StrCompare的返回值指示的是两个字符串的大小,而不是指示两个字符串是否相等。 + * 如果给定的S与()相等,返回值应当是0。 + */ + if(!StrCompare(S, emp)) { + *L = NULL; + } else { + *L = (GList) malloc(sizeof(GLNode)); + if(*L == NULL) { + exit(OVERFLOW); + } + + // 创建原子 + if(StrLength(S) == 1) { + (*L)->tag = Atom; + (*L)->Node.atom = S[1]; + } else { + (*L)->tag = List; + + p = *L; + + // 去掉最外层括号 + SubString(sub, S, 2, StrLength(S) - 2); + + // 重复建n个子表 + do { + // 从sub中分离出表头串hsub,分离完成后,sub也会发生变化 + sever(hsub, sub); + + // 递归创建广义表 + CreateGList(&(p->Node.ptr.hp), hsub); + + q = p; + + // 如果表尾不为空,需要继续处理表尾 + if(!StrEmpty(sub)) { + p = (GList) malloc(sizeof(GLNode)); + if(p == NULL) { + exit(OVERFLOW); + } + + p->tag = List; + + q->Node.ptr.tp = p; + } + } while(!StrEmpty(sub)); + + q->Node.ptr.tp = NULL; + } + } + + return OK; +} + +/* + * 销毁 + * + * 释放广义表所占内存。 + */ +Status DestroyGList(GList* L) { + GList head, tail; + + if(L == NULL || *L == NULL) { + return ERROR; + } + + // 删除原子结点 + if((*L)->tag == Atom) { + free(*L); + *L = NULL; + + // 删除子表结点 + } else { + head = (*L)->Node.ptr.hp; + tail = (*L)->Node.ptr.tp; + free(*L); + *L = NULL; + DestroyGList(&head); + DestroyGList(&tail); + } + + return OK; +} + +/* + * ████████ 算法5.6 ████████ + * + * 复制 + * + * 由广义表L复制得到广义表T。 + */ +Status CopyGList(GList* T, GList L) { + if(T == NULL) { + return ERROR; + } + + if(L == NULL) { + *T = NULL; + } else { + // 新建广义表结点 + *T = (GList) malloc(sizeof(GLNode)); + if(*T == NULL) { + exit(OVERFLOW); + } + + (*T)->tag = L->tag; + + // 复制单原子 + if(L->tag == Atom) { + (*T)->Node.atom = L->Node.atom; + + // 复制表头和表尾 + } else { + CopyGList(&((*T)->Node.ptr.hp), L->Node.ptr.hp); + CopyGList(&((*T)->Node.ptr.tp), L->Node.ptr.tp); + } + } + + return OK; +} + +/* + * 计数 + * + * 返回广义表的长度。 + */ +int GListLength(GList L) { + int count; + + for(count = 0; L != NULL; count++, L = L->Node.ptr.tp) { + } + + return count; +} + +/* + * ████████ 算法5.5 ████████ + * + * 深度 + * + * 返回广义表的深度 + */ +int GListDepth(GList L) { + int max, deep; + GList p; + + // 空表深度为1 + if(L == NULL) { + return 1; + } + + // 原子深度为0 + if(L->tag == Atom) { + return 0; + } + + // 递归求子表深度 + for(max = 0, p = L; p != NULL; p = p->Node.ptr.tp) { + deep = GListDepth(p->Node.ptr.hp); + if(deep > max) { + max = deep; + } + } + + // 非空表的深度是各子元素最大深度加一 + return max + 1; +} + +/* + * 判空 + * + * 判断广义表是否为空。 + */ +Status GListEmpty(GList L) { + return L == NULL ? TRUE : FALSE; +} + +/* + * 表头 + */ +GList GetHead(GList L) { + GList p; + + // 空表无表头,这里不能返回NULL,不然分不清是失败了还是返回了空表 + if(L == NULL) { + exit(ERROR); + } + + CopyGList(&p, L->Node.ptr.hp); + + return p; +} + +/* + * 表尾 + */ +GList GetTail(GList L) { + GList p; + + // 空表无表尾,这里不能返回NULL,不然分不清是失败了还是返回了空表 + if(L == NULL) { + exit(ERROR); + } + + CopyGList(&p, L->Node.ptr.tp); + + return p; +} + +/* + * 插入 + * + * 将元素e插入为广义表L的第一个元素。 + */ +Status InsertFirst(GList* L, GList e) { + GList g; + + if(L == NULL) { + return ERROR; + } + + g = (GList) malloc(sizeof(GLNode)); + if(g == NULL) { + exit(OVERFLOW); + } + + g->tag = List; + g->Node.ptr.hp = e; + g->Node.ptr.tp = *L; + *L = g; + + return OK; +} + +/* + * 删除 + * + * 将广义表L的第一个元素删除,并用e返回。 + */ +Status DeleteFirst(GList* L, GList* e) { + GList p; + + // 空表无法删除 + if(L == NULL || *L == NULL) { + return ERROR; + } + + p = *L; + *L = (*L)->Node.ptr.tp; + + CopyGList(e, p->Node.ptr.hp); + + free(p); + + return OK; +} + +/* + * 遍历 + * + * 用visit函数访问广义表L。 + */ +void Traverse(GList L, void(Visit)(AtomType)) { + + if(L == NULL) { + return; + } + + if(L->tag == Atom) { + Visit(L->Node.atom); + } else { + Traverse(L->Node.ptr.hp, Visit); + Traverse(L->Node.ptr.tp, Visit); + } + +} + +/* + * 图形化输出 + * + * 带括号输出广义表L。 + */ +void PrintGraph(GList L) { + Print(L, Head); + printf("\n"); +} + +/* + * 图形化输出的内部实现,mark是图形化输出标记。 + */ +static void Print(GList L, Mark mark) { + // L为空 + if(L == NULL) { + if(mark == Head) { + printf("("); + } + + printf(")"); + + // L不为空时 + } else { + // 对于原子结点,输出原子 + if(L->tag == Atom) { + printf("%c", L->Node.atom); + + // 对于子表结点,要对表头、表尾分别讨论 + } else { + if(mark == Head) { + printf("("); + } else { + printf(","); + } + + Print(L->Node.ptr.hp, Head); + Print(L->Node.ptr.tp, Tail); + } + } +} + +/* + * ████████ 算法5.8 ████████ + * + * 将非空串str分割成两部分:hsub为第一个','之前的子串,str为第一个','之后的子串。 + * + *【注】 + * 1.这里假设字符串str输入正确,其中无空白符号,且str【已经脱去最外层括号】。 + * 2.分离完成后,str也会发生变化 + */ +static void sever(SString hstr, SString str) { + int i, k, n; + SString ch; + + n = StrLength(str); + + i = 0; // 遍历字符串时的游标 + k = 0; // 标记遇到的未配对括号数量 + + do { + ++i; + + // 截取str第一个字符 + SubString(ch, str, i, 1); + + if(ch[1] == '(') { + ++k; + } + + if(ch[1] == ')') { + --k; + } + } while(i < n && (ch[1] != ',' || k != 0)); + + // 如果存在多个广义表结点 + if(i < n) { + SubString(hstr, str, 1, i - 1); + SubString(str, str, i + 1, n - i); + + // 只有一个广义表结点 + } else { + StrCopy(hstr, str); + ClearString(str); + } +} diff --git a/CLion/ExerciseBook/05.30.1/GList-HT.h b/CLion/ExerciseBook/05.30.1/GList-HT.h new file mode 100644 index 0000000..07c0df2 --- /dev/null +++ b/CLion/ExerciseBook/05.30.1/GList-HT.h @@ -0,0 +1,164 @@ +/*============================ + * 广义表的头尾链表存储表示 + * + * 包含算法: 5.5、5.6、5.7、5.8 + =============================*/ + +#ifndef GLIST_HT_H +#define GLIST_HT_H + +#include +#include // 提供 malloc、realloc、free、exit 原型 +#include "Status.h" //**▲01 绪论**// +#include "SString.h" //**▲04 串**// + +/* 原子元素类型 */ +typedef char AtomType; + +/* + * 广义表结点标记 + * + * Atom-0:原子结点 + * List-1:表结点 + */ +typedef enum { Atom, List } ElemTag; + +/* 广义表(头尾链表存储表示)类型定义 */ +typedef struct GLNode { + ElemTag tag; // 公共标记,用于区分原子结点和表结点 + + // 原子结点和表结点的联合部分 + union { + AtomType atom; // atom是原子结点的值域,AtomType由用户定义 + struct { + struct GLNode* hp; // 指向表头 + struct GLNode* tp; // 指向表尾 + } ptr; // 表结点的指针域 + } Node; +} GLNode; + +/* 广义表类型 */ +typedef GLNode* GList; + +/* + * 图形化输出标记 + * + * Head代表广义表指针来自表头 + * Tail代表广义表指针来自表尾 + */ +typedef enum { Head, Tail } Mark; + + +/* + * 初始化 + * + * 初始化空的广义表,长度为0,深度为1。 + * + *【注】 + * 需要对每一层去掉括号考察 + */ +Status InitGList(GList* L); + +/* + * ████████ 算法5.7 ████████ + * + * 创建 + * + * 由字符串S创建广义表L。 + */ +Status CreateGList(GList* L, SString S); + +/* + * 销毁 + * + * 释放广义表所占内存。 + */ +Status DestroyGList(GList* L); + +/* + * ████████ 算法5.6 ████████ + * + * 复制 + * + * 由广义表L复制得到广义表T。 + */ +Status CopyGList(GList* T, GList L); + +/* + * 计数 + * + * 返回广义表的长度。 + */ +int GListLength(GList L); + +/* + * ████████ 算法5.5 ████████ + * + * 深度 + * + * 返回广义表的深度 + */ +int GListDepth(GList L); + +/* + * 判空 + * + * 判断广义表是否为空。 + */ +Status GListEmpty(GList L); + +/* + * 表头 + */ +GList GetHead(GList L); + +/* + * 表尾 + */ +GList GetTail(GList L); + +/* + * 插入 + * + * 将元素e插入为广义表L的第一个元素。 + */ +Status InsertFirst(GList* L, GList e); + +/* + * 删除 + * + * 将广义表L的第一个元素删除,并用e返回。 + */ +Status DeleteFirst(GList* L, GList* e); + +/* + * 遍历 + * + * 用visit函数访问广义表L。 + */ +void Traverse(GList L, void (Visit)(AtomType)); + +/* + * 图形化输出 + * + * 带括号输出广义表L。 + */ +void PrintGraph(GList L); + +/* + * 图形化输出的内部实现,mark是图形化输出标记。 + */ +static void Print(GList L, Mark mark); + +/* + * ████████ 算法5.8 ████████ + * + * 将非空串str分割成两部分:hsub为第一个','之前的子串,str为第一个','之后的子串。 + * + *【注】 + * 1.这里假设字符串str输入正确,其中无空白符号,且str【已经脱去最外层括号】。 + * 2.分离完成后,str也会发生变化 + */ +static void sever(SString hstr, SString str); + +#endif diff --git a/CLion/ExerciseBook/05.30.1/SString.c b/CLion/ExerciseBook/05.30.1/SString.c new file mode 100644 index 0000000..41d9e15 --- /dev/null +++ b/CLion/ExerciseBook/05.30.1/SString.c @@ -0,0 +1,195 @@ +/*============================= + * 串的定长顺序存储表示(顺序串) + * + * 包含算法: 4.1、4.2、4.3、4.5 + ==============================*/ + +#include "SString.h" //**▲04 串**// + +/* + * 初始化 + * + * 构造一个值为chars的串T。 + * + *【注】 + * 该操作属于最小操作子集 + */ +Status StrAssign(SString T, const char* chars) { + int i, len; + + len = (int) strlen(chars); + + // chars过长 + if(len > MAXSTRLEN) { + return ERROR; + } + + T[0] = len; + for(i = 1; i <= len; i++) { + T[i] = chars[i - 1]; + } + + return OK; +} + +/* + * 清空 + * + * 将串S清空。 + */ +Status ClearString(SString S) { + // 只需要将长度置为0就可以 + S[0] = 0; + return OK; +} + +/* + * 判空 + * + * 判断串S中是否包含有效数据。 + * + * 返回值: + * TRUE : 串S为空 + * FALSE: 串S不为空 + */ +Status StrEmpty(SString S) { + return S[0] == 0 ? TRUE : FALSE; +} + +/* + * 计数 + * + * 返回串S中元素的个数。 + * + *【注】 + * 该操作属于最小操作子集 + */ +int StrLength(SString S) { + return S[0]; +} + +/* + * ████████ 算法4.3 ████████ + * + * 求子串 + * + * 用Sub返回S[pos, pos+len-1]。 + * 返回值指示是否截取成功。 + * + *【注】 + * 该操作属于最小操作子集 + */ +Status SubString(SString Sub, SString S, int pos, int len) { + int i; + + if(pos < 1 || pos > S[0] || len < 0 || pos + len - 1 > S[0]) { + return ERROR; + } + + // 复制元素 + for(i = 1; i <= len; i++) { + Sub[i] = S[pos + i - 1]; + } + + // 确定新长度 + Sub[0] = len; + + return OK; +} + +/* + * 删除 + * + * 删除S[pos, pos+len-1]。 + */ +Status StrDelete(SString S, int pos, int len) { + int i; + + if(pos < 1 || pos + len - 1 > S[0] || len < 0) { + return ERROR; + } + + // 如果待删除的长度为0,则提前返回 + if(len == 0) { + return OK; + } + + // 把后面的元素挪到前面,覆盖掉被删除的元素 + for(i = pos + len; i <= S[0]; i++) { + S[i - len] = S[i]; + } + + // 长度减少 + S[0] -= len; + + return OK; +} + +/* + * 比较 + * + * 比较串S和串T,返回比较结果。 + * + *【注】 + * 该操作属于最小操作子集 + */ +int StrCompare(SString S, SString T) { + int i = 1; + + while(i <= S[0] && i <= T[0]) { + // 遇到不同的字符时,比较其大小 + if(S[i] != T[i]) { + return S[i] - T[i]; + } + + i++; + } + + return S[0] - T[0]; +} + +/* + * 复制 + * + * 将串S复制到串T。 + */ +Status StrCopy(SString T, SString S) { + int i; + + // 连同长度信息一起复制 + for(i = 0; i <= S[0]; i++) { + T[i] = S[i]; + } + + return OK; +} + +/* + * 清理字符串S中的空白,包括清理不可打印字符和清理空格。 + * + *【注】 + * 该函数是在本章中新增的。 + */ +Status ClearBlank(SString S) { + int i, j; + + // 如果是空串 + if(S[0] == 0) { + return ERROR; + } + + for(i = 1, j = 0; i <= S[0]; i++) { + // 如果遇到空白,则略过 + if(S[i] == ' ' || !isprint(S[i])) { + continue; + } + + j++; + + S[j] = S[i]; + } + + S[0] = j; + + return OK; +} diff --git a/CLion/ExerciseBook/05.30.1/SString.h b/CLion/ExerciseBook/05.30.1/SString.h new file mode 100644 index 0000000..e81ca79 --- /dev/null +++ b/CLion/ExerciseBook/05.30.1/SString.h @@ -0,0 +1,117 @@ +/*============================= + * 串的定长顺序存储表示(顺序串) + * + * 包含算法: 4.1、4.2、4.3、4.5 + ==============================*/ + +#ifndef SSTRING_H +#define SSTRING_H + +#include +#include // 提供 strlen 原型 +#include // 提供 isprint 原型 +#include "Status.h" //**▲01 绪论**// + +/* 宏定义 */ +#define MAXSTRLEN 255 // 顺序串的最大串长 + +/* + * 串的顺序存储类型定义 + * + * 注:有效元素从SString的1号单元开始存储 + * SString的0号单元用来存储其长度 + */ +typedef unsigned char SString[MAXSTRLEN + 1]; // 0号单元存放串的长度 + + +/* + * ████ 提示 ████ + * + * 遵循教材的书写习惯,pos指示字符的位序(不是索引),从1开始计数 + */ + + +/* + * 初始化 + * + * 构造一个值为chars的串T。 + * + *【注】 + * 该操作属于最小操作子集 + */ +Status StrAssign(SString T, const char* chars); + +/* + * 清空 + * + * 将串S清空。 + */ +Status ClearString(SString S); + +/* + * 判空 + * + * 判断串S中是否包含有效数据。 + * + * 返回值: + * TRUE : 串S为空 + * FALSE: 串S不为空 + */ +Status StrEmpty(SString S); + +/* + * 计数 + * + * 返回串S中元素的个数。 + * + *【注】 + * 该操作属于最小操作子集 + */ +int StrLength(SString S); + +/* + * ████████ 算法4.3 ████████ + * + * 求子串 + * + * 用Sub返回S[pos, pos+len-1]。 + * 返回值指示是否截取成功。 + * + *【注】 + * 该操作属于最小操作子集 + */ +Status SubString(SString Sub, SString S, int pos, int len); + +/* + * 删除 + * + * 删除S[pos, pos+len-1]。 + */ +Status StrDelete(SString S, int pos, int len); + +/* + * 比较 + * + * 比较串S和串T,返回比较结果。 + * + *【注】 + * 该操作属于最小操作子集 + */ +int StrCompare(SString S, SString T); + +/* + * 复制 + * + * 将串S复制到串T。 + */ +Status StrCopy(SString T, SString S); + +/* + * 清理字符串S中的空白,包括清理不可打印字符和清理空格。 + * + *【注】 + * 该函数是在本章中新增的。 + */ +Status ClearBlank(SString S); + +#endif diff --git a/CLion/ExerciseBook/05.30.2/05.30.2.c b/CLion/ExerciseBook/05.30.2/05.30.2.c new file mode 100644 index 0000000..8ad12c9 --- /dev/null +++ b/CLion/ExerciseBook/05.30.2/05.30.2.c @@ -0,0 +1,42 @@ +#include +#include "SString.h" //**▲04 串**// +#include "GList-E.h" //**▲05 数组和广义表**// + +// 求广义表深度(扩展线性链表存储表示) +int Algo_5_30_2(GList L); + + +int main(int argc, char* argv[]) { + GList L; + char* s = "((),(e),(a,(b,c,d)))"; + SString S; + + printf("创建广义表 L ...\n"); + StrAssign(S, s); + CreateGList(&L, S); + printf("L = "); + PrintGraph(L); + + printf("广义表深度为: %d\n", Algo_5_30_2(L)); + + return 0; +} + + +// 求广义表深度(扩展线性链表存储表示) +int Algo_5_30_2(GList L) { + int m, n; + + if(L==NULL) { + return 1; // 空表深度为1 + } + + if(L->tag == Atom) { + return 0; // 原子深度为0 + } + + m = Algo_5_30_2(L->Node.hp) + 1; + n = Algo_5_30_2(L->tp); + + return m > n ? m : n; +} diff --git a/CLion/ExerciseBook/05.30.2/CMakeLists.txt b/CLion/ExerciseBook/05.30.2/CMakeLists.txt new file mode 100644 index 0000000..34b6516 --- /dev/null +++ b/CLion/ExerciseBook/05.30.2/CMakeLists.txt @@ -0,0 +1,7 @@ +# 包含公共库 +include_directories(${CMAKE_SOURCE_DIR}/Status) + +# 生成可执行文件 +add_executable(05.30.2 SString.h SString.c GList-E.h GList-E.c 05.30.2.c) +# 链接公共库 +target_link_libraries(05.30.2 Scanf_lib) \ No newline at end of file diff --git a/CLion/ExerciseBook/05.30.2/GList-E.c b/CLion/ExerciseBook/05.30.2/GList-E.c new file mode 100644 index 0000000..d994024 --- /dev/null +++ b/CLion/ExerciseBook/05.30.2/GList-E.c @@ -0,0 +1,449 @@ +/*=========================== + * 广义表的扩展线性链表存储表示 + ============================*/ + +#include "GList-E.h" //**▲05 数组和广义表**// + +/* + * 初始化 + * + * 初始化空的广义表,长度为0,深度为1。 + * + *【注】 + * 需要对每一层带上括号考察 + */ +Status InitGList(GList* L) { + if(L == NULL) { + return ERROR; + } + + *L = (GList) malloc(sizeof(GLNode)); + if(!*L) { + exit(OVERFLOW); + } + + (*L)->tag = List; + (*L)->Node.hp = NULL; + (*L)->tp = NULL; + + return OK; +} + +/* + * 创建 + * + * 由字符串S创建广义表L。 + */ +Status CreateGList(GList* L, SString S) { + SString emp, hsub, sub, tmp; + + if(L == NULL) { + return ERROR; + } + + // 清理字符串S中的空白,包括清理不可打印字符和清理空格 + ClearBlank(S); + + if(StrEmpty(S)) { + return ERROR; + } + + // 复制是为了不破坏S + StrCopy(sub, S); + + /* + * 初次执行到此时,带着最外层的括号 + * 再次执行到此时,已经脱去了外层括号 + */ + sever(hsub, sub); + + *L = (GList) malloc(sizeof(GLNode)); + if(*L == NULL) { + exit(OVERFLOW); + } + + StrAssign(emp, "()"); + + if(!StrCompare(hsub, emp)) { + (*L)->tag = List; + (*L)->Node.hp = NULL; + } else { + if(StrLength(hsub) == 1) { + (*L)->tag = Atom; + (*L)->Node.atom = hsub[1]; + } else { + (*L)->tag = List; + + SubString(tmp, hsub, 2, StrLength(hsub) - 2); + + CreateGList(&((*L)->Node.hp), tmp); + } + } + + // 如果不存在队尾,则退出本层递归 + if(StrEmpty(sub)) { + (*L)->tp = NULL; + } else { + // 继续递归求表尾 + CreateGList(&((*L)->tp), sub); + } + + return OK; +} + +/* + * 销毁 + * + * 释放广义表所占内存。 + */ +Status DestroyGList(GList* L) { + GList head, tail; + + if(L == NULL || *L == NULL) { + return ERROR; + } + + // 处理子表结点 + if((*L)->tag == List) { + head = (*L)->Node.hp; // 表头 + tail = (*L)->tp; // 表尾 + + free(*L); + *L = NULL; + + // 递归处理表头 + if(head != NULL) { + DestroyGList(&head); + } + + // 递归处理表尾 + if(tail != NULL) { + DestroyGList(&tail); + } + + // 处理原子结点 + } else { + tail = (*L)->tp; // 表尾 + + free(*L); + *L = NULL; + + if(tail != NULL) { + DestroyGList(&tail); + } + } + + return OK; +} + +/* + * 复制 + * + * 由广义表L复制得到广义表T。 + */ +Status CopyGList(GList* T, GList L) { + + if(L == NULL) { + return ERROR; + } + + *T = (GList) malloc(sizeof(GLNode)); + if(*T == NULL) { + exit(OVERFLOW); + } + + // 复制原子 + if(L->tag == Atom) { + (*T)->tag = Atom; + (*T)->Node.atom = L->Node.atom; + + // 复制子表 + } else { + (*T)->tag = List; + + // 复制表头 + if(L->Node.hp != NULL) { + CopyGList(&((*T)->Node.hp), L->Node.hp); + } else { + (*T)->Node.hp = NULL; + } + } + + // 复制表尾 + if(L->tp != NULL) { + CopyGList(&((*T)->tp), L->tp); + } else { + (*T)->tp = NULL; + } + + return OK; +} + +/* + * 计数 + * + * 返回广义表的长度。 + */ +int GListLength(GList L) { + int count = 0; + GList p; + + // 广义表不存在 + if(L == NULL) { + return -1; + } + + p = L->Node.hp; + + while(p != NULL) { + ++count; + p = p->tp; + } + + return count; +} + +/* + * 深度 + * + * 返回广义表的深度 + */ +int GListDepth(GList L) { + int max, deep; + GList p; + + max = 0; + + // 广义表不存在 + if(L == NULL) { + return -1; + } + + // 空表深度为1 + if(L->tag == List && !L->Node.hp) { + return 1; + } + + // 原子深度为0 + if(L->tag == Atom) { + return 0; + } + + // 递归求子表深度 + for(p = L->Node.hp; p != NULL; p = p->tp) { + // 求以p为头指针的子表深度 + deep = GListDepth(p); + if(deep > max) { + max = deep; + } + } + + return max + 1; +} + +/* + * 判空 + * + * 判断广义表是否为空。 + */ +Status GListEmpty(GList L) { + // 广义表不存在 + if(L == NULL) { + return ERROR; + } + + if(L->tag == List && L->Node.hp == NULL && L->tp == NULL) { + return TRUE; + } else { + return ERROR; + } +} + +/* + * 表头 + */ +GList GetHead(GList L) { + GList p, q; + + // 广义表不存在或广义表为空表,无法获取表头 + if(L == NULL || L->Node.hp == NULL) { + return NULL; + } + + q = L->Node.hp->tp; // 临时保存L的表尾信息 + L->Node.hp->tp = NULL; // 截去L的表尾部分 + + CopyGList(&p, L->Node.hp); // 复制表头信息(已屏蔽表尾) + + L->Node.hp->tp = q; // 恢复L的表尾信息 + + return p; +} + +/* + * 表尾 + */ +GList GetTail(GList L) { + GList p, q; + + // 广义表不存在或广义表为空表,无法获取表尾 + if(L == NULL || L->Node.hp == NULL) { + return NULL; + } + + q = L->Node.hp; // 临时保存L的表头信息 + L->Node.hp = q->tp; // 摘下L的表头部分 + + CopyGList(&p, L); // 复制表尾信息(已屏蔽表头) + + q->tp = L->Node.hp; // 恢复L的表头信息 + L->Node.hp = q; + + return p; +} + +/* + * 插入 + * + * 将元素e插入为广义表L的第一个元素。 + */ +Status InsertFirst(GList* L, GList e) { + + // 广义表不存在 + if(L == NULL || *L == NULL) { + return ERROR; + } + + if(e == NULL) { + return ERROR; + } + + e->tp = (*L)->Node.hp; + (*L)->Node.hp = e; + + return OK; +} + +/* + * 删除 + * + * 将广义表L的第一个元素删除,并用e返回。 + */ +Status DeleteFirst(GList* L, GList* e) { + GList p; + + // 广义表不存在或广义表为空表,则无法删除表头 + if(*L == NULL || (*L)->Node.hp == NULL) { + return ERROR; + } + + p = (*L)->Node.hp; + (*L)->Node.hp = p->tp; + p->tp = NULL; + + *e = p; + + return OK; +} + +/* + * 遍历 + * + * 用visit函数访问广义表L。 + */ +void Traverse(GList L, void(Visit)(AtomType)) { + if(L == NULL) { + return; + } + + if(L->tag == List) { + Traverse(L->Node.hp, Visit); + } else { + Visit(L->Node.atom); + } + + Traverse(L->tp, Visit); +} + +/* + * 图形化输出 + * + * 带括号输出广义表L。 + */ +void PrintGraph(GList L) { + Print(L); + printf("\n"); +} + +/* + * 图形化输出的内部实现。 + */ +static void Print(GList L) { + if(L == NULL) { + return; + } + + // 处理表结点 + if(L->tag == List) { + printf("("); + + if(L->Node.hp) { + Print(L->Node.hp); + } + + if(L->tp) { + printf("),"); + Print(L->tp); + } else { + printf(")"); + } + + // 处理原子结点 + } else { + printf("%c", L->Node.atom); + if(L->tp) { + printf(","); + Print(L->tp); + } + } +} + +/* + * 将非空串str分割成两部分:hsub为第一个','之前的子串,str为第一个','之后的子串。 + * + *【注】 + * 1.这里假设字符串str输入正确,其中无空白符号, + * 但str外层的括号可能脱去,也可能未脱去。 + * 2.分离完成后,str也会发生变化 + */ +static void sever(SString hstr, SString str) { + int i, k, n; + SString ch; + + n = StrLength(str); + + i = 0; // 遍历字符串时的游标 + k = 0; // 标记遇到的未配对括号数量 + + do { + ++i; + + // 截取str第一个字符 + SubString(ch, str, i, 1); + + if(ch[1] == '(') { + ++k; + } + if(ch[1] == ')') { + --k; + } + } while(i < n && (ch[1] != ',' || k != 0)); + + if(i < n) { + SubString(hstr, str, 1, i - 1); + SubString(str, str, i + 1, n - i); + } else { + StrCopy(hstr, str); + ClearString(str); + } +} diff --git a/CLion/ExerciseBook/05.30.2/GList-E.h b/CLion/ExerciseBook/05.30.2/GList-E.h new file mode 100644 index 0000000..5e5b625 --- /dev/null +++ b/CLion/ExerciseBook/05.30.2/GList-E.h @@ -0,0 +1,146 @@ +/*=========================== + * 广义表的扩展线性链表存储表示 + ============================*/ + +#ifndef GLIST_E_H +#define GLIST_E_H + +#include +#include // 提供 malloc、realloc、free、exit 原型 +#include "Status.h" //**▲01 绪论**// +#include "SString.h" //**▲04 串**// + +/* 原子元素类型 */ +typedef char AtomType; //原子类型 + +/* + * 广义表结点标记 + * + * Atom-0:原子结点 + * List-1:表结点 + */ +typedef enum { Atom, List } ElemTag; + +/* 广义表(扩展线性链表存储表示)类型定义 */ +typedef struct GLNode { + ElemTag tag; // 公共标记,用于区分原子结点和表结点 + + // 原子结点和表结点的联合部分 + union + { + AtomType atom; // atom是原子结点的值域,AtomType由用户定义 + struct GLNode* hp; // 指向表头 + } Node; + struct GLNode* tp; // 指向表尾 +} GLNode; + +/* 广义表类型 */ +typedef GLNode* GList; + + +/* + * 初始化 + * + * 初始化空的广义表,长度为0,深度为1。 + * + *【注】 + * 需要对每一层带上括号考察 + */ +Status InitGList(GList* L); + +/* + * 创建 + * + * 由字符串S创建广义表L。 + */ +Status CreateGList(GList* L, SString S); + +/* + * 销毁 + * + * 释放广义表所占内存。 + */ +Status DestroyGList(GList* L); + +/* + * 复制 + * + * 由广义表L复制得到广义表T。 + */ +Status CopyGList(GList* T, GList L); + +/* + * 计数 + * + * 返回广义表的长度。 + */ +int GListLength(GList L); + +/* + * 深度 + * + * 返回广义表的深度 + */ +int GListDepth(GList L); + +/* + * 判空 + * + * 判断广义表是否为空。 + */ +Status GListEmpty(GList L); + +/* + * 表头 + */ +GList GetHead(GList L); + +/* + * 表尾 + */ +GList GetTail(GList L); + +/* + * 插入 + * + * 将元素e插入为广义表L的第一个元素。 + */ +Status InsertFirst(GList* L, GList e); + +/* + * 删除 + * + * 将广义表L的第一个元素删除,并用e返回。 + */ +Status DeleteFirst(GList* L, GList* e); + +/* + * 遍历 + * + * 用visit函数访问广义表L。 + */ +void Traverse(GList L, void(Visit)(AtomType)); + +/* + * 图形化输出 + * + * 带括号输出广义表L。 + */ +void PrintGraph(GList L); + +/* + * 图形化输出的内部实现。 + */ +static void Print(GList L); + +/* + * 将非空串str分割成两部分:hsub为第一个','之前的子串,str为第一个','之后的子串。 + * + *【注】 + * 1.这里假设字符串str输入正确,其中无空白符号, + * 但str外层的括号可能脱去,也可能未脱去。 + * 2.分离完成后,str也会发生变化 + */ +static void sever(SString hstr, SString str); + +#endif diff --git a/CLion/ExerciseBook/05.30.2/SString.c b/CLion/ExerciseBook/05.30.2/SString.c new file mode 100644 index 0000000..41d9e15 --- /dev/null +++ b/CLion/ExerciseBook/05.30.2/SString.c @@ -0,0 +1,195 @@ +/*============================= + * 串的定长顺序存储表示(顺序串) + * + * 包含算法: 4.1、4.2、4.3、4.5 + ==============================*/ + +#include "SString.h" //**▲04 串**// + +/* + * 初始化 + * + * 构造一个值为chars的串T。 + * + *【注】 + * 该操作属于最小操作子集 + */ +Status StrAssign(SString T, const char* chars) { + int i, len; + + len = (int) strlen(chars); + + // chars过长 + if(len > MAXSTRLEN) { + return ERROR; + } + + T[0] = len; + for(i = 1; i <= len; i++) { + T[i] = chars[i - 1]; + } + + return OK; +} + +/* + * 清空 + * + * 将串S清空。 + */ +Status ClearString(SString S) { + // 只需要将长度置为0就可以 + S[0] = 0; + return OK; +} + +/* + * 判空 + * + * 判断串S中是否包含有效数据。 + * + * 返回值: + * TRUE : 串S为空 + * FALSE: 串S不为空 + */ +Status StrEmpty(SString S) { + return S[0] == 0 ? TRUE : FALSE; +} + +/* + * 计数 + * + * 返回串S中元素的个数。 + * + *【注】 + * 该操作属于最小操作子集 + */ +int StrLength(SString S) { + return S[0]; +} + +/* + * ████████ 算法4.3 ████████ + * + * 求子串 + * + * 用Sub返回S[pos, pos+len-1]。 + * 返回值指示是否截取成功。 + * + *【注】 + * 该操作属于最小操作子集 + */ +Status SubString(SString Sub, SString S, int pos, int len) { + int i; + + if(pos < 1 || pos > S[0] || len < 0 || pos + len - 1 > S[0]) { + return ERROR; + } + + // 复制元素 + for(i = 1; i <= len; i++) { + Sub[i] = S[pos + i - 1]; + } + + // 确定新长度 + Sub[0] = len; + + return OK; +} + +/* + * 删除 + * + * 删除S[pos, pos+len-1]。 + */ +Status StrDelete(SString S, int pos, int len) { + int i; + + if(pos < 1 || pos + len - 1 > S[0] || len < 0) { + return ERROR; + } + + // 如果待删除的长度为0,则提前返回 + if(len == 0) { + return OK; + } + + // 把后面的元素挪到前面,覆盖掉被删除的元素 + for(i = pos + len; i <= S[0]; i++) { + S[i - len] = S[i]; + } + + // 长度减少 + S[0] -= len; + + return OK; +} + +/* + * 比较 + * + * 比较串S和串T,返回比较结果。 + * + *【注】 + * 该操作属于最小操作子集 + */ +int StrCompare(SString S, SString T) { + int i = 1; + + while(i <= S[0] && i <= T[0]) { + // 遇到不同的字符时,比较其大小 + if(S[i] != T[i]) { + return S[i] - T[i]; + } + + i++; + } + + return S[0] - T[0]; +} + +/* + * 复制 + * + * 将串S复制到串T。 + */ +Status StrCopy(SString T, SString S) { + int i; + + // 连同长度信息一起复制 + for(i = 0; i <= S[0]; i++) { + T[i] = S[i]; + } + + return OK; +} + +/* + * 清理字符串S中的空白,包括清理不可打印字符和清理空格。 + * + *【注】 + * 该函数是在本章中新增的。 + */ +Status ClearBlank(SString S) { + int i, j; + + // 如果是空串 + if(S[0] == 0) { + return ERROR; + } + + for(i = 1, j = 0; i <= S[0]; i++) { + // 如果遇到空白,则略过 + if(S[i] == ' ' || !isprint(S[i])) { + continue; + } + + j++; + + S[j] = S[i]; + } + + S[0] = j; + + return OK; +} diff --git a/CLion/ExerciseBook/05.30.2/SString.h b/CLion/ExerciseBook/05.30.2/SString.h new file mode 100644 index 0000000..e81ca79 --- /dev/null +++ b/CLion/ExerciseBook/05.30.2/SString.h @@ -0,0 +1,117 @@ +/*============================= + * 串的定长顺序存储表示(顺序串) + * + * 包含算法: 4.1、4.2、4.3、4.5 + ==============================*/ + +#ifndef SSTRING_H +#define SSTRING_H + +#include +#include // 提供 strlen 原型 +#include // 提供 isprint 原型 +#include "Status.h" //**▲01 绪论**// + +/* 宏定义 */ +#define MAXSTRLEN 255 // 顺序串的最大串长 + +/* + * 串的顺序存储类型定义 + * + * 注:有效元素从SString的1号单元开始存储 + * SString的0号单元用来存储其长度 + */ +typedef unsigned char SString[MAXSTRLEN + 1]; // 0号单元存放串的长度 + + +/* + * ████ 提示 ████ + * + * 遵循教材的书写习惯,pos指示字符的位序(不是索引),从1开始计数 + */ + + +/* + * 初始化 + * + * 构造一个值为chars的串T。 + * + *【注】 + * 该操作属于最小操作子集 + */ +Status StrAssign(SString T, const char* chars); + +/* + * 清空 + * + * 将串S清空。 + */ +Status ClearString(SString S); + +/* + * 判空 + * + * 判断串S中是否包含有效数据。 + * + * 返回值: + * TRUE : 串S为空 + * FALSE: 串S不为空 + */ +Status StrEmpty(SString S); + +/* + * 计数 + * + * 返回串S中元素的个数。 + * + *【注】 + * 该操作属于最小操作子集 + */ +int StrLength(SString S); + +/* + * ████████ 算法4.3 ████████ + * + * 求子串 + * + * 用Sub返回S[pos, pos+len-1]。 + * 返回值指示是否截取成功。 + * + *【注】 + * 该操作属于最小操作子集 + */ +Status SubString(SString Sub, SString S, int pos, int len); + +/* + * 删除 + * + * 删除S[pos, pos+len-1]。 + */ +Status StrDelete(SString S, int pos, int len); + +/* + * 比较 + * + * 比较串S和串T,返回比较结果。 + * + *【注】 + * 该操作属于最小操作子集 + */ +int StrCompare(SString S, SString T); + +/* + * 复制 + * + * 将串S复制到串T。 + */ +Status StrCopy(SString T, SString S); + +/* + * 清理字符串S中的空白,包括清理不可打印字符和清理空格。 + * + *【注】 + * 该函数是在本章中新增的。 + */ +Status ClearBlank(SString S); + +#endif diff --git a/CLion/ExerciseBook/05.31/05.31.c b/CLion/ExerciseBook/05.31/05.31.c new file mode 100644 index 0000000..c9ece2d --- /dev/null +++ b/CLion/ExerciseBook/05.31/05.31.c @@ -0,0 +1,43 @@ +#include +#include "Status.h" //**▲01 绪论**// +#include "SString.h" //**▲04 串**// +#include "GList-E.h" //**▲05 数组和广义表**// + +/* + * 广义表复制(扩展线性链表存储表示) + * + *【注】 + * 该函数已在GList-E相关文件中定义 + */ +Status Algo_5_31(GList* T, GList L); + + +int main(int argc, char* argv[]) { + GList L, T; + char* s = "((),(e),(a,(b,c,d)))"; + SString S; + + printf("创建广义表 L ...\n"); + StrAssign(S, s); + CreateGList(&L, S); + printf("L = "); + PrintGraph(L); + + printf("复制广义表到 L 到 T...\n"); + Algo_5_31(&T, L); + printf("T = "); + PrintGraph(T); + + return 0; +} + + +/* + * 广义表复制(扩展线性链表存储表示) + * + *【注】 + * 该函数已在GList-E相关文件中定义 + */ +Status Algo_5_31(GList* T, GList L) { + return CopyGList(T, L); +} diff --git a/CLion/ExerciseBook/05.31/CMakeLists.txt b/CLion/ExerciseBook/05.31/CMakeLists.txt new file mode 100644 index 0000000..141eb2a --- /dev/null +++ b/CLion/ExerciseBook/05.31/CMakeLists.txt @@ -0,0 +1,7 @@ +# 包含公共库 +include_directories(${CMAKE_SOURCE_DIR}/Status) + +# 生成可执行文件 +add_executable(05.31 SString.h SString.c GList-E.h GList-E.c 05.31.c) +# 链接公共库 +target_link_libraries(05.31 Scanf_lib) \ No newline at end of file diff --git a/CLion/ExerciseBook/05.31/GList-E.c b/CLion/ExerciseBook/05.31/GList-E.c new file mode 100644 index 0000000..d994024 --- /dev/null +++ b/CLion/ExerciseBook/05.31/GList-E.c @@ -0,0 +1,449 @@ +/*=========================== + * 广义表的扩展线性链表存储表示 + ============================*/ + +#include "GList-E.h" //**▲05 数组和广义表**// + +/* + * 初始化 + * + * 初始化空的广义表,长度为0,深度为1。 + * + *【注】 + * 需要对每一层带上括号考察 + */ +Status InitGList(GList* L) { + if(L == NULL) { + return ERROR; + } + + *L = (GList) malloc(sizeof(GLNode)); + if(!*L) { + exit(OVERFLOW); + } + + (*L)->tag = List; + (*L)->Node.hp = NULL; + (*L)->tp = NULL; + + return OK; +} + +/* + * 创建 + * + * 由字符串S创建广义表L。 + */ +Status CreateGList(GList* L, SString S) { + SString emp, hsub, sub, tmp; + + if(L == NULL) { + return ERROR; + } + + // 清理字符串S中的空白,包括清理不可打印字符和清理空格 + ClearBlank(S); + + if(StrEmpty(S)) { + return ERROR; + } + + // 复制是为了不破坏S + StrCopy(sub, S); + + /* + * 初次执行到此时,带着最外层的括号 + * 再次执行到此时,已经脱去了外层括号 + */ + sever(hsub, sub); + + *L = (GList) malloc(sizeof(GLNode)); + if(*L == NULL) { + exit(OVERFLOW); + } + + StrAssign(emp, "()"); + + if(!StrCompare(hsub, emp)) { + (*L)->tag = List; + (*L)->Node.hp = NULL; + } else { + if(StrLength(hsub) == 1) { + (*L)->tag = Atom; + (*L)->Node.atom = hsub[1]; + } else { + (*L)->tag = List; + + SubString(tmp, hsub, 2, StrLength(hsub) - 2); + + CreateGList(&((*L)->Node.hp), tmp); + } + } + + // 如果不存在队尾,则退出本层递归 + if(StrEmpty(sub)) { + (*L)->tp = NULL; + } else { + // 继续递归求表尾 + CreateGList(&((*L)->tp), sub); + } + + return OK; +} + +/* + * 销毁 + * + * 释放广义表所占内存。 + */ +Status DestroyGList(GList* L) { + GList head, tail; + + if(L == NULL || *L == NULL) { + return ERROR; + } + + // 处理子表结点 + if((*L)->tag == List) { + head = (*L)->Node.hp; // 表头 + tail = (*L)->tp; // 表尾 + + free(*L); + *L = NULL; + + // 递归处理表头 + if(head != NULL) { + DestroyGList(&head); + } + + // 递归处理表尾 + if(tail != NULL) { + DestroyGList(&tail); + } + + // 处理原子结点 + } else { + tail = (*L)->tp; // 表尾 + + free(*L); + *L = NULL; + + if(tail != NULL) { + DestroyGList(&tail); + } + } + + return OK; +} + +/* + * 复制 + * + * 由广义表L复制得到广义表T。 + */ +Status CopyGList(GList* T, GList L) { + + if(L == NULL) { + return ERROR; + } + + *T = (GList) malloc(sizeof(GLNode)); + if(*T == NULL) { + exit(OVERFLOW); + } + + // 复制原子 + if(L->tag == Atom) { + (*T)->tag = Atom; + (*T)->Node.atom = L->Node.atom; + + // 复制子表 + } else { + (*T)->tag = List; + + // 复制表头 + if(L->Node.hp != NULL) { + CopyGList(&((*T)->Node.hp), L->Node.hp); + } else { + (*T)->Node.hp = NULL; + } + } + + // 复制表尾 + if(L->tp != NULL) { + CopyGList(&((*T)->tp), L->tp); + } else { + (*T)->tp = NULL; + } + + return OK; +} + +/* + * 计数 + * + * 返回广义表的长度。 + */ +int GListLength(GList L) { + int count = 0; + GList p; + + // 广义表不存在 + if(L == NULL) { + return -1; + } + + p = L->Node.hp; + + while(p != NULL) { + ++count; + p = p->tp; + } + + return count; +} + +/* + * 深度 + * + * 返回广义表的深度 + */ +int GListDepth(GList L) { + int max, deep; + GList p; + + max = 0; + + // 广义表不存在 + if(L == NULL) { + return -1; + } + + // 空表深度为1 + if(L->tag == List && !L->Node.hp) { + return 1; + } + + // 原子深度为0 + if(L->tag == Atom) { + return 0; + } + + // 递归求子表深度 + for(p = L->Node.hp; p != NULL; p = p->tp) { + // 求以p为头指针的子表深度 + deep = GListDepth(p); + if(deep > max) { + max = deep; + } + } + + return max + 1; +} + +/* + * 判空 + * + * 判断广义表是否为空。 + */ +Status GListEmpty(GList L) { + // 广义表不存在 + if(L == NULL) { + return ERROR; + } + + if(L->tag == List && L->Node.hp == NULL && L->tp == NULL) { + return TRUE; + } else { + return ERROR; + } +} + +/* + * 表头 + */ +GList GetHead(GList L) { + GList p, q; + + // 广义表不存在或广义表为空表,无法获取表头 + if(L == NULL || L->Node.hp == NULL) { + return NULL; + } + + q = L->Node.hp->tp; // 临时保存L的表尾信息 + L->Node.hp->tp = NULL; // 截去L的表尾部分 + + CopyGList(&p, L->Node.hp); // 复制表头信息(已屏蔽表尾) + + L->Node.hp->tp = q; // 恢复L的表尾信息 + + return p; +} + +/* + * 表尾 + */ +GList GetTail(GList L) { + GList p, q; + + // 广义表不存在或广义表为空表,无法获取表尾 + if(L == NULL || L->Node.hp == NULL) { + return NULL; + } + + q = L->Node.hp; // 临时保存L的表头信息 + L->Node.hp = q->tp; // 摘下L的表头部分 + + CopyGList(&p, L); // 复制表尾信息(已屏蔽表头) + + q->tp = L->Node.hp; // 恢复L的表头信息 + L->Node.hp = q; + + return p; +} + +/* + * 插入 + * + * 将元素e插入为广义表L的第一个元素。 + */ +Status InsertFirst(GList* L, GList e) { + + // 广义表不存在 + if(L == NULL || *L == NULL) { + return ERROR; + } + + if(e == NULL) { + return ERROR; + } + + e->tp = (*L)->Node.hp; + (*L)->Node.hp = e; + + return OK; +} + +/* + * 删除 + * + * 将广义表L的第一个元素删除,并用e返回。 + */ +Status DeleteFirst(GList* L, GList* e) { + GList p; + + // 广义表不存在或广义表为空表,则无法删除表头 + if(*L == NULL || (*L)->Node.hp == NULL) { + return ERROR; + } + + p = (*L)->Node.hp; + (*L)->Node.hp = p->tp; + p->tp = NULL; + + *e = p; + + return OK; +} + +/* + * 遍历 + * + * 用visit函数访问广义表L。 + */ +void Traverse(GList L, void(Visit)(AtomType)) { + if(L == NULL) { + return; + } + + if(L->tag == List) { + Traverse(L->Node.hp, Visit); + } else { + Visit(L->Node.atom); + } + + Traverse(L->tp, Visit); +} + +/* + * 图形化输出 + * + * 带括号输出广义表L。 + */ +void PrintGraph(GList L) { + Print(L); + printf("\n"); +} + +/* + * 图形化输出的内部实现。 + */ +static void Print(GList L) { + if(L == NULL) { + return; + } + + // 处理表结点 + if(L->tag == List) { + printf("("); + + if(L->Node.hp) { + Print(L->Node.hp); + } + + if(L->tp) { + printf("),"); + Print(L->tp); + } else { + printf(")"); + } + + // 处理原子结点 + } else { + printf("%c", L->Node.atom); + if(L->tp) { + printf(","); + Print(L->tp); + } + } +} + +/* + * 将非空串str分割成两部分:hsub为第一个','之前的子串,str为第一个','之后的子串。 + * + *【注】 + * 1.这里假设字符串str输入正确,其中无空白符号, + * 但str外层的括号可能脱去,也可能未脱去。 + * 2.分离完成后,str也会发生变化 + */ +static void sever(SString hstr, SString str) { + int i, k, n; + SString ch; + + n = StrLength(str); + + i = 0; // 遍历字符串时的游标 + k = 0; // 标记遇到的未配对括号数量 + + do { + ++i; + + // 截取str第一个字符 + SubString(ch, str, i, 1); + + if(ch[1] == '(') { + ++k; + } + if(ch[1] == ')') { + --k; + } + } while(i < n && (ch[1] != ',' || k != 0)); + + if(i < n) { + SubString(hstr, str, 1, i - 1); + SubString(str, str, i + 1, n - i); + } else { + StrCopy(hstr, str); + ClearString(str); + } +} diff --git a/CLion/ExerciseBook/05.31/GList-E.h b/CLion/ExerciseBook/05.31/GList-E.h new file mode 100644 index 0000000..5e5b625 --- /dev/null +++ b/CLion/ExerciseBook/05.31/GList-E.h @@ -0,0 +1,146 @@ +/*=========================== + * 广义表的扩展线性链表存储表示 + ============================*/ + +#ifndef GLIST_E_H +#define GLIST_E_H + +#include +#include // 提供 malloc、realloc、free、exit 原型 +#include "Status.h" //**▲01 绪论**// +#include "SString.h" //**▲04 串**// + +/* 原子元素类型 */ +typedef char AtomType; //原子类型 + +/* + * 广义表结点标记 + * + * Atom-0:原子结点 + * List-1:表结点 + */ +typedef enum { Atom, List } ElemTag; + +/* 广义表(扩展线性链表存储表示)类型定义 */ +typedef struct GLNode { + ElemTag tag; // 公共标记,用于区分原子结点和表结点 + + // 原子结点和表结点的联合部分 + union + { + AtomType atom; // atom是原子结点的值域,AtomType由用户定义 + struct GLNode* hp; // 指向表头 + } Node; + struct GLNode* tp; // 指向表尾 +} GLNode; + +/* 广义表类型 */ +typedef GLNode* GList; + + +/* + * 初始化 + * + * 初始化空的广义表,长度为0,深度为1。 + * + *【注】 + * 需要对每一层带上括号考察 + */ +Status InitGList(GList* L); + +/* + * 创建 + * + * 由字符串S创建广义表L。 + */ +Status CreateGList(GList* L, SString S); + +/* + * 销毁 + * + * 释放广义表所占内存。 + */ +Status DestroyGList(GList* L); + +/* + * 复制 + * + * 由广义表L复制得到广义表T。 + */ +Status CopyGList(GList* T, GList L); + +/* + * 计数 + * + * 返回广义表的长度。 + */ +int GListLength(GList L); + +/* + * 深度 + * + * 返回广义表的深度 + */ +int GListDepth(GList L); + +/* + * 判空 + * + * 判断广义表是否为空。 + */ +Status GListEmpty(GList L); + +/* + * 表头 + */ +GList GetHead(GList L); + +/* + * 表尾 + */ +GList GetTail(GList L); + +/* + * 插入 + * + * 将元素e插入为广义表L的第一个元素。 + */ +Status InsertFirst(GList* L, GList e); + +/* + * 删除 + * + * 将广义表L的第一个元素删除,并用e返回。 + */ +Status DeleteFirst(GList* L, GList* e); + +/* + * 遍历 + * + * 用visit函数访问广义表L。 + */ +void Traverse(GList L, void(Visit)(AtomType)); + +/* + * 图形化输出 + * + * 带括号输出广义表L。 + */ +void PrintGraph(GList L); + +/* + * 图形化输出的内部实现。 + */ +static void Print(GList L); + +/* + * 将非空串str分割成两部分:hsub为第一个','之前的子串,str为第一个','之后的子串。 + * + *【注】 + * 1.这里假设字符串str输入正确,其中无空白符号, + * 但str外层的括号可能脱去,也可能未脱去。 + * 2.分离完成后,str也会发生变化 + */ +static void sever(SString hstr, SString str); + +#endif diff --git a/CLion/ExerciseBook/05.31/SString.c b/CLion/ExerciseBook/05.31/SString.c new file mode 100644 index 0000000..41d9e15 --- /dev/null +++ b/CLion/ExerciseBook/05.31/SString.c @@ -0,0 +1,195 @@ +/*============================= + * 串的定长顺序存储表示(顺序串) + * + * 包含算法: 4.1、4.2、4.3、4.5 + ==============================*/ + +#include "SString.h" //**▲04 串**// + +/* + * 初始化 + * + * 构造一个值为chars的串T。 + * + *【注】 + * 该操作属于最小操作子集 + */ +Status StrAssign(SString T, const char* chars) { + int i, len; + + len = (int) strlen(chars); + + // chars过长 + if(len > MAXSTRLEN) { + return ERROR; + } + + T[0] = len; + for(i = 1; i <= len; i++) { + T[i] = chars[i - 1]; + } + + return OK; +} + +/* + * 清空 + * + * 将串S清空。 + */ +Status ClearString(SString S) { + // 只需要将长度置为0就可以 + S[0] = 0; + return OK; +} + +/* + * 判空 + * + * 判断串S中是否包含有效数据。 + * + * 返回值: + * TRUE : 串S为空 + * FALSE: 串S不为空 + */ +Status StrEmpty(SString S) { + return S[0] == 0 ? TRUE : FALSE; +} + +/* + * 计数 + * + * 返回串S中元素的个数。 + * + *【注】 + * 该操作属于最小操作子集 + */ +int StrLength(SString S) { + return S[0]; +} + +/* + * ████████ 算法4.3 ████████ + * + * 求子串 + * + * 用Sub返回S[pos, pos+len-1]。 + * 返回值指示是否截取成功。 + * + *【注】 + * 该操作属于最小操作子集 + */ +Status SubString(SString Sub, SString S, int pos, int len) { + int i; + + if(pos < 1 || pos > S[0] || len < 0 || pos + len - 1 > S[0]) { + return ERROR; + } + + // 复制元素 + for(i = 1; i <= len; i++) { + Sub[i] = S[pos + i - 1]; + } + + // 确定新长度 + Sub[0] = len; + + return OK; +} + +/* + * 删除 + * + * 删除S[pos, pos+len-1]。 + */ +Status StrDelete(SString S, int pos, int len) { + int i; + + if(pos < 1 || pos + len - 1 > S[0] || len < 0) { + return ERROR; + } + + // 如果待删除的长度为0,则提前返回 + if(len == 0) { + return OK; + } + + // 把后面的元素挪到前面,覆盖掉被删除的元素 + for(i = pos + len; i <= S[0]; i++) { + S[i - len] = S[i]; + } + + // 长度减少 + S[0] -= len; + + return OK; +} + +/* + * 比较 + * + * 比较串S和串T,返回比较结果。 + * + *【注】 + * 该操作属于最小操作子集 + */ +int StrCompare(SString S, SString T) { + int i = 1; + + while(i <= S[0] && i <= T[0]) { + // 遇到不同的字符时,比较其大小 + if(S[i] != T[i]) { + return S[i] - T[i]; + } + + i++; + } + + return S[0] - T[0]; +} + +/* + * 复制 + * + * 将串S复制到串T。 + */ +Status StrCopy(SString T, SString S) { + int i; + + // 连同长度信息一起复制 + for(i = 0; i <= S[0]; i++) { + T[i] = S[i]; + } + + return OK; +} + +/* + * 清理字符串S中的空白,包括清理不可打印字符和清理空格。 + * + *【注】 + * 该函数是在本章中新增的。 + */ +Status ClearBlank(SString S) { + int i, j; + + // 如果是空串 + if(S[0] == 0) { + return ERROR; + } + + for(i = 1, j = 0; i <= S[0]; i++) { + // 如果遇到空白,则略过 + if(S[i] == ' ' || !isprint(S[i])) { + continue; + } + + j++; + + S[j] = S[i]; + } + + S[0] = j; + + return OK; +} diff --git a/CLion/ExerciseBook/05.31/SString.h b/CLion/ExerciseBook/05.31/SString.h new file mode 100644 index 0000000..e81ca79 --- /dev/null +++ b/CLion/ExerciseBook/05.31/SString.h @@ -0,0 +1,117 @@ +/*============================= + * 串的定长顺序存储表示(顺序串) + * + * 包含算法: 4.1、4.2、4.3、4.5 + ==============================*/ + +#ifndef SSTRING_H +#define SSTRING_H + +#include +#include // 提供 strlen 原型 +#include // 提供 isprint 原型 +#include "Status.h" //**▲01 绪论**// + +/* 宏定义 */ +#define MAXSTRLEN 255 // 顺序串的最大串长 + +/* + * 串的顺序存储类型定义 + * + * 注:有效元素从SString的1号单元开始存储 + * SString的0号单元用来存储其长度 + */ +typedef unsigned char SString[MAXSTRLEN + 1]; // 0号单元存放串的长度 + + +/* + * ████ 提示 ████ + * + * 遵循教材的书写习惯,pos指示字符的位序(不是索引),从1开始计数 + */ + + +/* + * 初始化 + * + * 构造一个值为chars的串T。 + * + *【注】 + * 该操作属于最小操作子集 + */ +Status StrAssign(SString T, const char* chars); + +/* + * 清空 + * + * 将串S清空。 + */ +Status ClearString(SString S); + +/* + * 判空 + * + * 判断串S中是否包含有效数据。 + * + * 返回值: + * TRUE : 串S为空 + * FALSE: 串S不为空 + */ +Status StrEmpty(SString S); + +/* + * 计数 + * + * 返回串S中元素的个数。 + * + *【注】 + * 该操作属于最小操作子集 + */ +int StrLength(SString S); + +/* + * ████████ 算法4.3 ████████ + * + * 求子串 + * + * 用Sub返回S[pos, pos+len-1]。 + * 返回值指示是否截取成功。 + * + *【注】 + * 该操作属于最小操作子集 + */ +Status SubString(SString Sub, SString S, int pos, int len); + +/* + * 删除 + * + * 删除S[pos, pos+len-1]。 + */ +Status StrDelete(SString S, int pos, int len); + +/* + * 比较 + * + * 比较串S和串T,返回比较结果。 + * + *【注】 + * 该操作属于最小操作子集 + */ +int StrCompare(SString S, SString T); + +/* + * 复制 + * + * 将串S复制到串T。 + */ +Status StrCopy(SString T, SString S); + +/* + * 清理字符串S中的空白,包括清理不可打印字符和清理空格。 + * + *【注】 + * 该函数是在本章中新增的。 + */ +Status ClearBlank(SString S); + +#endif diff --git a/CLion/ExerciseBook/05.32.1/05.32.1.c b/CLion/ExerciseBook/05.32.1/05.32.1.c new file mode 100644 index 0000000..4f3b192 --- /dev/null +++ b/CLion/ExerciseBook/05.32.1/05.32.1.c @@ -0,0 +1,64 @@ +#include +#include "Status.h" //**▲01 绪论**// +#include "SString.h" //**▲04 串**// +#include "GList-HT.h" //**▲05 数组和广义表**// + +/* + * 判断广义表是否相等(头尾链表存储表示) + */ +Status Algo_5_32_1(GList A, GList B); + + +int main(int argc, char* argv[]) { + GList A, B; + char* a = "((),(e),(a,(b,c,d)))"; + char* b = "((),(e),(a,(b,c,f)))"; + SString Sa, Sb; + + printf("创建广义表 A、B ...\n"); + StrAssign(Sa, a); + CreateGList(&A, Sa); + StrAssign(Sb, b); + CreateGList(&B, Sb); + printf("A = "); + PrintGraph(A); + printf("B = "); + PrintGraph(B); + + Algo_5_32_1(A, B) ? printf("两广义表相等!\n") : printf("两广义表不相等!!\n"); + + return 0; +} + + +/* + * 判断广义表是否相等(头尾链表存储表示) + */ +Status Algo_5_32_1(GList A, GList B) { + if(!A && !B) { + return TRUE; // 两个空表相等 + } + + // 两个表均不为空 + if(A && B) { + // 元素类型相同 + if(A->tag == B->tag) { + // 原子结点 + if(A->tag == Atom) { + if(A->Node.atom == B->Node.atom) { + return TRUE; + } + + // 表结点 + } else { + if(Algo_5_32_1(A->Node.ptr.hp, B->Node.ptr.hp) == TRUE) { + if(Algo_5_32_1(A->Node.ptr.tp, B->Node.ptr.tp) == TRUE) { + return TRUE; + } + } + } + } + } + + return FALSE; +} diff --git a/CLion/ExerciseBook/05.32.1/CMakeLists.txt b/CLion/ExerciseBook/05.32.1/CMakeLists.txt new file mode 100644 index 0000000..9291d98 --- /dev/null +++ b/CLion/ExerciseBook/05.32.1/CMakeLists.txt @@ -0,0 +1,7 @@ +# 包含公共库 +include_directories(${CMAKE_SOURCE_DIR}/Status) + +# 生成可执行文件 +add_executable(05.32.1 SString.h SString.c GList-HT.h GList-HT.c 05.32.1.c) +# 链接公共库 +target_link_libraries(05.32.1 Scanf_lib) \ No newline at end of file diff --git a/CLion/ExerciseBook/05.32.1/GList-HT.c b/CLion/ExerciseBook/05.32.1/GList-HT.c new file mode 100644 index 0000000..ddf2766 --- /dev/null +++ b/CLion/ExerciseBook/05.32.1/GList-HT.c @@ -0,0 +1,418 @@ +/*============================ + * 广义表的头尾链表存储表示 + * + * 包含算法: 5.5、5.6、5.7、5.8 + =============================*/ + +#include "GList-HT.h" //**▲05 数组和广义表**// + +/* + * 初始化 + * + * 初始化空的广义表,长度为0,深度为1。 + * + *【注】 + * 需要对每一层去掉括号考察 + */ +Status InitGList(GList* L) { + if(L == NULL) { + return ERROR; + } + + *L = NULL; + + return OK; +} + +/* + * ████████ 算法5.7 ████████ + * + * 创建 + * + * 由字符串S创建广义表L。 + */ +Status CreateGList(GList* L, SString S) { + SString emp; // 代表空广义表的字符串 + SString hsub, sub; + GList p, q; + + if(L == NULL) { + return ERROR; + } + + // 清理字符串S中的空白,包括清理不可打印字符和清理空格 + ClearBlank(S); + + if(StrEmpty(S)) { + return ERROR; + } + + StrAssign(emp, "()"); + + /* + * 如果输入串为(),则代表需要创建空的广义表 + * + *【注】 + * 教材这里的代码是有问题的。 + * StrCompare的返回值指示的是两个字符串的大小,而不是指示两个字符串是否相等。 + * 如果给定的S与()相等,返回值应当是0。 + */ + if(!StrCompare(S, emp)) { + *L = NULL; + } else { + *L = (GList) malloc(sizeof(GLNode)); + if(*L == NULL) { + exit(OVERFLOW); + } + + // 创建原子 + if(StrLength(S) == 1) { + (*L)->tag = Atom; + (*L)->Node.atom = S[1]; + } else { + (*L)->tag = List; + + p = *L; + + // 去掉最外层括号 + SubString(sub, S, 2, StrLength(S) - 2); + + // 重复建n个子表 + do { + // 从sub中分离出表头串hsub,分离完成后,sub也会发生变化 + sever(hsub, sub); + + // 递归创建广义表 + CreateGList(&(p->Node.ptr.hp), hsub); + + q = p; + + // 如果表尾不为空,需要继续处理表尾 + if(!StrEmpty(sub)) { + p = (GList) malloc(sizeof(GLNode)); + if(p == NULL) { + exit(OVERFLOW); + } + + p->tag = List; + + q->Node.ptr.tp = p; + } + } while(!StrEmpty(sub)); + + q->Node.ptr.tp = NULL; + } + } + + return OK; +} + +/* + * 销毁 + * + * 释放广义表所占内存。 + */ +Status DestroyGList(GList* L) { + GList head, tail; + + if(L == NULL || *L == NULL) { + return ERROR; + } + + // 删除原子结点 + if((*L)->tag == Atom) { + free(*L); + *L = NULL; + + // 删除子表结点 + } else { + head = (*L)->Node.ptr.hp; + tail = (*L)->Node.ptr.tp; + free(*L); + *L = NULL; + DestroyGList(&head); + DestroyGList(&tail); + } + + return OK; +} + +/* + * ████████ 算法5.6 ████████ + * + * 复制 + * + * 由广义表L复制得到广义表T。 + */ +Status CopyGList(GList* T, GList L) { + if(T == NULL) { + return ERROR; + } + + if(L == NULL) { + *T = NULL; + } else { + // 新建广义表结点 + *T = (GList) malloc(sizeof(GLNode)); + if(*T == NULL) { + exit(OVERFLOW); + } + + (*T)->tag = L->tag; + + // 复制单原子 + if(L->tag == Atom) { + (*T)->Node.atom = L->Node.atom; + + // 复制表头和表尾 + } else { + CopyGList(&((*T)->Node.ptr.hp), L->Node.ptr.hp); + CopyGList(&((*T)->Node.ptr.tp), L->Node.ptr.tp); + } + } + + return OK; +} + +/* + * 计数 + * + * 返回广义表的长度。 + */ +int GListLength(GList L) { + int count; + + for(count = 0; L != NULL; count++, L = L->Node.ptr.tp) { + } + + return count; +} + +/* + * ████████ 算法5.5 ████████ + * + * 深度 + * + * 返回广义表的深度 + */ +int GListDepth(GList L) { + int max, deep; + GList p; + + // 空表深度为1 + if(L == NULL) { + return 1; + } + + // 原子深度为0 + if(L->tag == Atom) { + return 0; + } + + // 递归求子表深度 + for(max = 0, p = L; p != NULL; p = p->Node.ptr.tp) { + deep = GListDepth(p->Node.ptr.hp); + if(deep > max) { + max = deep; + } + } + + // 非空表的深度是各子元素最大深度加一 + return max + 1; +} + +/* + * 判空 + * + * 判断广义表是否为空。 + */ +Status GListEmpty(GList L) { + return L == NULL ? TRUE : FALSE; +} + +/* + * 表头 + */ +GList GetHead(GList L) { + GList p; + + // 空表无表头,这里不能返回NULL,不然分不清是失败了还是返回了空表 + if(L == NULL) { + exit(ERROR); + } + + CopyGList(&p, L->Node.ptr.hp); + + return p; +} + +/* + * 表尾 + */ +GList GetTail(GList L) { + GList p; + + // 空表无表尾,这里不能返回NULL,不然分不清是失败了还是返回了空表 + if(L == NULL) { + exit(ERROR); + } + + CopyGList(&p, L->Node.ptr.tp); + + return p; +} + +/* + * 插入 + * + * 将元素e插入为广义表L的第一个元素。 + */ +Status InsertFirst(GList* L, GList e) { + GList g; + + if(L == NULL) { + return ERROR; + } + + g = (GList) malloc(sizeof(GLNode)); + if(g == NULL) { + exit(OVERFLOW); + } + + g->tag = List; + g->Node.ptr.hp = e; + g->Node.ptr.tp = *L; + *L = g; + + return OK; +} + +/* + * 删除 + * + * 将广义表L的第一个元素删除,并用e返回。 + */ +Status DeleteFirst(GList* L, GList* e) { + GList p; + + // 空表无法删除 + if(L == NULL || *L == NULL) { + return ERROR; + } + + p = *L; + *L = (*L)->Node.ptr.tp; + + CopyGList(e, p->Node.ptr.hp); + + free(p); + + return OK; +} + +/* + * 遍历 + * + * 用visit函数访问广义表L。 + */ +void Traverse(GList L, void(Visit)(AtomType)) { + + if(L == NULL) { + return; + } + + if(L->tag == Atom) { + Visit(L->Node.atom); + } else { + Traverse(L->Node.ptr.hp, Visit); + Traverse(L->Node.ptr.tp, Visit); + } + +} + +/* + * 图形化输出 + * + * 带括号输出广义表L。 + */ +void PrintGraph(GList L) { + Print(L, Head); + printf("\n"); +} + +/* + * 图形化输出的内部实现,mark是图形化输出标记。 + */ +static void Print(GList L, Mark mark) { + // L为空 + if(L == NULL) { + if(mark == Head) { + printf("("); + } + + printf(")"); + + // L不为空时 + } else { + // 对于原子结点,输出原子 + if(L->tag == Atom) { + printf("%c", L->Node.atom); + + // 对于子表结点,要对表头、表尾分别讨论 + } else { + if(mark == Head) { + printf("("); + } else { + printf(","); + } + + Print(L->Node.ptr.hp, Head); + Print(L->Node.ptr.tp, Tail); + } + } +} + +/* + * ████████ 算法5.8 ████████ + * + * 将非空串str分割成两部分:hsub为第一个','之前的子串,str为第一个','之后的子串。 + * + *【注】 + * 1.这里假设字符串str输入正确,其中无空白符号,且str【已经脱去最外层括号】。 + * 2.分离完成后,str也会发生变化 + */ +static void sever(SString hstr, SString str) { + int i, k, n; + SString ch; + + n = StrLength(str); + + i = 0; // 遍历字符串时的游标 + k = 0; // 标记遇到的未配对括号数量 + + do { + ++i; + + // 截取str第一个字符 + SubString(ch, str, i, 1); + + if(ch[1] == '(') { + ++k; + } + + if(ch[1] == ')') { + --k; + } + } while(i < n && (ch[1] != ',' || k != 0)); + + // 如果存在多个广义表结点 + if(i < n) { + SubString(hstr, str, 1, i - 1); + SubString(str, str, i + 1, n - i); + + // 只有一个广义表结点 + } else { + StrCopy(hstr, str); + ClearString(str); + } +} diff --git a/CLion/ExerciseBook/05.32.1/GList-HT.h b/CLion/ExerciseBook/05.32.1/GList-HT.h new file mode 100644 index 0000000..07c0df2 --- /dev/null +++ b/CLion/ExerciseBook/05.32.1/GList-HT.h @@ -0,0 +1,164 @@ +/*============================ + * 广义表的头尾链表存储表示 + * + * 包含算法: 5.5、5.6、5.7、5.8 + =============================*/ + +#ifndef GLIST_HT_H +#define GLIST_HT_H + +#include +#include // 提供 malloc、realloc、free、exit 原型 +#include "Status.h" //**▲01 绪论**// +#include "SString.h" //**▲04 串**// + +/* 原子元素类型 */ +typedef char AtomType; + +/* + * 广义表结点标记 + * + * Atom-0:原子结点 + * List-1:表结点 + */ +typedef enum { Atom, List } ElemTag; + +/* 广义表(头尾链表存储表示)类型定义 */ +typedef struct GLNode { + ElemTag tag; // 公共标记,用于区分原子结点和表结点 + + // 原子结点和表结点的联合部分 + union { + AtomType atom; // atom是原子结点的值域,AtomType由用户定义 + struct { + struct GLNode* hp; // 指向表头 + struct GLNode* tp; // 指向表尾 + } ptr; // 表结点的指针域 + } Node; +} GLNode; + +/* 广义表类型 */ +typedef GLNode* GList; + +/* + * 图形化输出标记 + * + * Head代表广义表指针来自表头 + * Tail代表广义表指针来自表尾 + */ +typedef enum { Head, Tail } Mark; + + +/* + * 初始化 + * + * 初始化空的广义表,长度为0,深度为1。 + * + *【注】 + * 需要对每一层去掉括号考察 + */ +Status InitGList(GList* L); + +/* + * ████████ 算法5.7 ████████ + * + * 创建 + * + * 由字符串S创建广义表L。 + */ +Status CreateGList(GList* L, SString S); + +/* + * 销毁 + * + * 释放广义表所占内存。 + */ +Status DestroyGList(GList* L); + +/* + * ████████ 算法5.6 ████████ + * + * 复制 + * + * 由广义表L复制得到广义表T。 + */ +Status CopyGList(GList* T, GList L); + +/* + * 计数 + * + * 返回广义表的长度。 + */ +int GListLength(GList L); + +/* + * ████████ 算法5.5 ████████ + * + * 深度 + * + * 返回广义表的深度 + */ +int GListDepth(GList L); + +/* + * 判空 + * + * 判断广义表是否为空。 + */ +Status GListEmpty(GList L); + +/* + * 表头 + */ +GList GetHead(GList L); + +/* + * 表尾 + */ +GList GetTail(GList L); + +/* + * 插入 + * + * 将元素e插入为广义表L的第一个元素。 + */ +Status InsertFirst(GList* L, GList e); + +/* + * 删除 + * + * 将广义表L的第一个元素删除,并用e返回。 + */ +Status DeleteFirst(GList* L, GList* e); + +/* + * 遍历 + * + * 用visit函数访问广义表L。 + */ +void Traverse(GList L, void (Visit)(AtomType)); + +/* + * 图形化输出 + * + * 带括号输出广义表L。 + */ +void PrintGraph(GList L); + +/* + * 图形化输出的内部实现,mark是图形化输出标记。 + */ +static void Print(GList L, Mark mark); + +/* + * ████████ 算法5.8 ████████ + * + * 将非空串str分割成两部分:hsub为第一个','之前的子串,str为第一个','之后的子串。 + * + *【注】 + * 1.这里假设字符串str输入正确,其中无空白符号,且str【已经脱去最外层括号】。 + * 2.分离完成后,str也会发生变化 + */ +static void sever(SString hstr, SString str); + +#endif diff --git a/CLion/ExerciseBook/05.32.1/SString.c b/CLion/ExerciseBook/05.32.1/SString.c new file mode 100644 index 0000000..41d9e15 --- /dev/null +++ b/CLion/ExerciseBook/05.32.1/SString.c @@ -0,0 +1,195 @@ +/*============================= + * 串的定长顺序存储表示(顺序串) + * + * 包含算法: 4.1、4.2、4.3、4.5 + ==============================*/ + +#include "SString.h" //**▲04 串**// + +/* + * 初始化 + * + * 构造一个值为chars的串T。 + * + *【注】 + * 该操作属于最小操作子集 + */ +Status StrAssign(SString T, const char* chars) { + int i, len; + + len = (int) strlen(chars); + + // chars过长 + if(len > MAXSTRLEN) { + return ERROR; + } + + T[0] = len; + for(i = 1; i <= len; i++) { + T[i] = chars[i - 1]; + } + + return OK; +} + +/* + * 清空 + * + * 将串S清空。 + */ +Status ClearString(SString S) { + // 只需要将长度置为0就可以 + S[0] = 0; + return OK; +} + +/* + * 判空 + * + * 判断串S中是否包含有效数据。 + * + * 返回值: + * TRUE : 串S为空 + * FALSE: 串S不为空 + */ +Status StrEmpty(SString S) { + return S[0] == 0 ? TRUE : FALSE; +} + +/* + * 计数 + * + * 返回串S中元素的个数。 + * + *【注】 + * 该操作属于最小操作子集 + */ +int StrLength(SString S) { + return S[0]; +} + +/* + * ████████ 算法4.3 ████████ + * + * 求子串 + * + * 用Sub返回S[pos, pos+len-1]。 + * 返回值指示是否截取成功。 + * + *【注】 + * 该操作属于最小操作子集 + */ +Status SubString(SString Sub, SString S, int pos, int len) { + int i; + + if(pos < 1 || pos > S[0] || len < 0 || pos + len - 1 > S[0]) { + return ERROR; + } + + // 复制元素 + for(i = 1; i <= len; i++) { + Sub[i] = S[pos + i - 1]; + } + + // 确定新长度 + Sub[0] = len; + + return OK; +} + +/* + * 删除 + * + * 删除S[pos, pos+len-1]。 + */ +Status StrDelete(SString S, int pos, int len) { + int i; + + if(pos < 1 || pos + len - 1 > S[0] || len < 0) { + return ERROR; + } + + // 如果待删除的长度为0,则提前返回 + if(len == 0) { + return OK; + } + + // 把后面的元素挪到前面,覆盖掉被删除的元素 + for(i = pos + len; i <= S[0]; i++) { + S[i - len] = S[i]; + } + + // 长度减少 + S[0] -= len; + + return OK; +} + +/* + * 比较 + * + * 比较串S和串T,返回比较结果。 + * + *【注】 + * 该操作属于最小操作子集 + */ +int StrCompare(SString S, SString T) { + int i = 1; + + while(i <= S[0] && i <= T[0]) { + // 遇到不同的字符时,比较其大小 + if(S[i] != T[i]) { + return S[i] - T[i]; + } + + i++; + } + + return S[0] - T[0]; +} + +/* + * 复制 + * + * 将串S复制到串T。 + */ +Status StrCopy(SString T, SString S) { + int i; + + // 连同长度信息一起复制 + for(i = 0; i <= S[0]; i++) { + T[i] = S[i]; + } + + return OK; +} + +/* + * 清理字符串S中的空白,包括清理不可打印字符和清理空格。 + * + *【注】 + * 该函数是在本章中新增的。 + */ +Status ClearBlank(SString S) { + int i, j; + + // 如果是空串 + if(S[0] == 0) { + return ERROR; + } + + for(i = 1, j = 0; i <= S[0]; i++) { + // 如果遇到空白,则略过 + if(S[i] == ' ' || !isprint(S[i])) { + continue; + } + + j++; + + S[j] = S[i]; + } + + S[0] = j; + + return OK; +} diff --git a/CLion/ExerciseBook/05.32.1/SString.h b/CLion/ExerciseBook/05.32.1/SString.h new file mode 100644 index 0000000..e81ca79 --- /dev/null +++ b/CLion/ExerciseBook/05.32.1/SString.h @@ -0,0 +1,117 @@ +/*============================= + * 串的定长顺序存储表示(顺序串) + * + * 包含算法: 4.1、4.2、4.3、4.5 + ==============================*/ + +#ifndef SSTRING_H +#define SSTRING_H + +#include +#include // 提供 strlen 原型 +#include // 提供 isprint 原型 +#include "Status.h" //**▲01 绪论**// + +/* 宏定义 */ +#define MAXSTRLEN 255 // 顺序串的最大串长 + +/* + * 串的顺序存储类型定义 + * + * 注:有效元素从SString的1号单元开始存储 + * SString的0号单元用来存储其长度 + */ +typedef unsigned char SString[MAXSTRLEN + 1]; // 0号单元存放串的长度 + + +/* + * ████ 提示 ████ + * + * 遵循教材的书写习惯,pos指示字符的位序(不是索引),从1开始计数 + */ + + +/* + * 初始化 + * + * 构造一个值为chars的串T。 + * + *【注】 + * 该操作属于最小操作子集 + */ +Status StrAssign(SString T, const char* chars); + +/* + * 清空 + * + * 将串S清空。 + */ +Status ClearString(SString S); + +/* + * 判空 + * + * 判断串S中是否包含有效数据。 + * + * 返回值: + * TRUE : 串S为空 + * FALSE: 串S不为空 + */ +Status StrEmpty(SString S); + +/* + * 计数 + * + * 返回串S中元素的个数。 + * + *【注】 + * 该操作属于最小操作子集 + */ +int StrLength(SString S); + +/* + * ████████ 算法4.3 ████████ + * + * 求子串 + * + * 用Sub返回S[pos, pos+len-1]。 + * 返回值指示是否截取成功。 + * + *【注】 + * 该操作属于最小操作子集 + */ +Status SubString(SString Sub, SString S, int pos, int len); + +/* + * 删除 + * + * 删除S[pos, pos+len-1]。 + */ +Status StrDelete(SString S, int pos, int len); + +/* + * 比较 + * + * 比较串S和串T,返回比较结果。 + * + *【注】 + * 该操作属于最小操作子集 + */ +int StrCompare(SString S, SString T); + +/* + * 复制 + * + * 将串S复制到串T。 + */ +Status StrCopy(SString T, SString S); + +/* + * 清理字符串S中的空白,包括清理不可打印字符和清理空格。 + * + *【注】 + * 该函数是在本章中新增的。 + */ +Status ClearBlank(SString S); + +#endif diff --git a/CLion/ExerciseBook/05.32.2/05.32.2.c b/CLion/ExerciseBook/05.32.2/05.32.2.c new file mode 100644 index 0000000..8b0377b --- /dev/null +++ b/CLion/ExerciseBook/05.32.2/05.32.2.c @@ -0,0 +1,66 @@ +#include +#include "Status.h" //**▲01 绪论**// +#include "SString.h" //**▲04 串**// +#include "GList-E.h" //**▲05 数组和广义表**// + +/* + * 判断广义表是否相等(扩展线性链表存储表示) + */ +Status Algo_5_32_2(GList A, GList B); + + +int main(int argc, char* argv[]) { + GList A, B; + char* a = "((),(e),(a,(b,c,d)))"; + char* b = "((),(e),(a,(b,c,f)))"; + SString Sa, Sb; + + printf("创建广义表 A、B ...\n"); + StrAssign(Sa, a); + CreateGList(&A, Sa); + StrAssign(Sb, b); + CreateGList(&B, Sb); + printf("A = "); + PrintGraph(A); + printf("B = "); + PrintGraph(B); + + Algo_5_32_2(A, B) ? printf("两广义表相等!\n") : printf("两广义表不相等!!\n"); + + return 0; +} + + +/* + * 判断广义表是否相等(扩展线性链表存储表示) + */ +Status Algo_5_32_2(GList A, GList B) { + if(!A && !B) { + return TRUE; // 两个空表相等 + } + + // 两个表均不为空 + if(A && B) { + // 元素类型相同 + if(A->tag == B->tag) { + // 原子结点 + if(A->tag == Atom) { + if(A->Node.atom == B->Node.atom) { + if(Algo_5_32_2(A->tp, B->tp) == TRUE) { + return TRUE; + } + } + + // 表结点 + } else { + if(Algo_5_32_2(A->Node.hp, B->Node.hp) == TRUE) { + if(Algo_5_32_2(A->tp, B->tp) == TRUE) { + return TRUE; + } + } + } + } + } + + return FALSE; +} diff --git a/CLion/ExerciseBook/05.32.2/CMakeLists.txt b/CLion/ExerciseBook/05.32.2/CMakeLists.txt new file mode 100644 index 0000000..019b9b9 --- /dev/null +++ b/CLion/ExerciseBook/05.32.2/CMakeLists.txt @@ -0,0 +1,7 @@ +# 包含公共库 +include_directories(${CMAKE_SOURCE_DIR}/Status) + +# 生成可执行文件 +add_executable(05.32.2 SString.h SString.c GList-E.h GList-E.c 05.32.2.c) +# 链接公共库 +target_link_libraries(05.32.2 Scanf_lib) \ No newline at end of file diff --git a/CLion/ExerciseBook/05.32.2/GList-E.c b/CLion/ExerciseBook/05.32.2/GList-E.c new file mode 100644 index 0000000..d994024 --- /dev/null +++ b/CLion/ExerciseBook/05.32.2/GList-E.c @@ -0,0 +1,449 @@ +/*=========================== + * 广义表的扩展线性链表存储表示 + ============================*/ + +#include "GList-E.h" //**▲05 数组和广义表**// + +/* + * 初始化 + * + * 初始化空的广义表,长度为0,深度为1。 + * + *【注】 + * 需要对每一层带上括号考察 + */ +Status InitGList(GList* L) { + if(L == NULL) { + return ERROR; + } + + *L = (GList) malloc(sizeof(GLNode)); + if(!*L) { + exit(OVERFLOW); + } + + (*L)->tag = List; + (*L)->Node.hp = NULL; + (*L)->tp = NULL; + + return OK; +} + +/* + * 创建 + * + * 由字符串S创建广义表L。 + */ +Status CreateGList(GList* L, SString S) { + SString emp, hsub, sub, tmp; + + if(L == NULL) { + return ERROR; + } + + // 清理字符串S中的空白,包括清理不可打印字符和清理空格 + ClearBlank(S); + + if(StrEmpty(S)) { + return ERROR; + } + + // 复制是为了不破坏S + StrCopy(sub, S); + + /* + * 初次执行到此时,带着最外层的括号 + * 再次执行到此时,已经脱去了外层括号 + */ + sever(hsub, sub); + + *L = (GList) malloc(sizeof(GLNode)); + if(*L == NULL) { + exit(OVERFLOW); + } + + StrAssign(emp, "()"); + + if(!StrCompare(hsub, emp)) { + (*L)->tag = List; + (*L)->Node.hp = NULL; + } else { + if(StrLength(hsub) == 1) { + (*L)->tag = Atom; + (*L)->Node.atom = hsub[1]; + } else { + (*L)->tag = List; + + SubString(tmp, hsub, 2, StrLength(hsub) - 2); + + CreateGList(&((*L)->Node.hp), tmp); + } + } + + // 如果不存在队尾,则退出本层递归 + if(StrEmpty(sub)) { + (*L)->tp = NULL; + } else { + // 继续递归求表尾 + CreateGList(&((*L)->tp), sub); + } + + return OK; +} + +/* + * 销毁 + * + * 释放广义表所占内存。 + */ +Status DestroyGList(GList* L) { + GList head, tail; + + if(L == NULL || *L == NULL) { + return ERROR; + } + + // 处理子表结点 + if((*L)->tag == List) { + head = (*L)->Node.hp; // 表头 + tail = (*L)->tp; // 表尾 + + free(*L); + *L = NULL; + + // 递归处理表头 + if(head != NULL) { + DestroyGList(&head); + } + + // 递归处理表尾 + if(tail != NULL) { + DestroyGList(&tail); + } + + // 处理原子结点 + } else { + tail = (*L)->tp; // 表尾 + + free(*L); + *L = NULL; + + if(tail != NULL) { + DestroyGList(&tail); + } + } + + return OK; +} + +/* + * 复制 + * + * 由广义表L复制得到广义表T。 + */ +Status CopyGList(GList* T, GList L) { + + if(L == NULL) { + return ERROR; + } + + *T = (GList) malloc(sizeof(GLNode)); + if(*T == NULL) { + exit(OVERFLOW); + } + + // 复制原子 + if(L->tag == Atom) { + (*T)->tag = Atom; + (*T)->Node.atom = L->Node.atom; + + // 复制子表 + } else { + (*T)->tag = List; + + // 复制表头 + if(L->Node.hp != NULL) { + CopyGList(&((*T)->Node.hp), L->Node.hp); + } else { + (*T)->Node.hp = NULL; + } + } + + // 复制表尾 + if(L->tp != NULL) { + CopyGList(&((*T)->tp), L->tp); + } else { + (*T)->tp = NULL; + } + + return OK; +} + +/* + * 计数 + * + * 返回广义表的长度。 + */ +int GListLength(GList L) { + int count = 0; + GList p; + + // 广义表不存在 + if(L == NULL) { + return -1; + } + + p = L->Node.hp; + + while(p != NULL) { + ++count; + p = p->tp; + } + + return count; +} + +/* + * 深度 + * + * 返回广义表的深度 + */ +int GListDepth(GList L) { + int max, deep; + GList p; + + max = 0; + + // 广义表不存在 + if(L == NULL) { + return -1; + } + + // 空表深度为1 + if(L->tag == List && !L->Node.hp) { + return 1; + } + + // 原子深度为0 + if(L->tag == Atom) { + return 0; + } + + // 递归求子表深度 + for(p = L->Node.hp; p != NULL; p = p->tp) { + // 求以p为头指针的子表深度 + deep = GListDepth(p); + if(deep > max) { + max = deep; + } + } + + return max + 1; +} + +/* + * 判空 + * + * 判断广义表是否为空。 + */ +Status GListEmpty(GList L) { + // 广义表不存在 + if(L == NULL) { + return ERROR; + } + + if(L->tag == List && L->Node.hp == NULL && L->tp == NULL) { + return TRUE; + } else { + return ERROR; + } +} + +/* + * 表头 + */ +GList GetHead(GList L) { + GList p, q; + + // 广义表不存在或广义表为空表,无法获取表头 + if(L == NULL || L->Node.hp == NULL) { + return NULL; + } + + q = L->Node.hp->tp; // 临时保存L的表尾信息 + L->Node.hp->tp = NULL; // 截去L的表尾部分 + + CopyGList(&p, L->Node.hp); // 复制表头信息(已屏蔽表尾) + + L->Node.hp->tp = q; // 恢复L的表尾信息 + + return p; +} + +/* + * 表尾 + */ +GList GetTail(GList L) { + GList p, q; + + // 广义表不存在或广义表为空表,无法获取表尾 + if(L == NULL || L->Node.hp == NULL) { + return NULL; + } + + q = L->Node.hp; // 临时保存L的表头信息 + L->Node.hp = q->tp; // 摘下L的表头部分 + + CopyGList(&p, L); // 复制表尾信息(已屏蔽表头) + + q->tp = L->Node.hp; // 恢复L的表头信息 + L->Node.hp = q; + + return p; +} + +/* + * 插入 + * + * 将元素e插入为广义表L的第一个元素。 + */ +Status InsertFirst(GList* L, GList e) { + + // 广义表不存在 + if(L == NULL || *L == NULL) { + return ERROR; + } + + if(e == NULL) { + return ERROR; + } + + e->tp = (*L)->Node.hp; + (*L)->Node.hp = e; + + return OK; +} + +/* + * 删除 + * + * 将广义表L的第一个元素删除,并用e返回。 + */ +Status DeleteFirst(GList* L, GList* e) { + GList p; + + // 广义表不存在或广义表为空表,则无法删除表头 + if(*L == NULL || (*L)->Node.hp == NULL) { + return ERROR; + } + + p = (*L)->Node.hp; + (*L)->Node.hp = p->tp; + p->tp = NULL; + + *e = p; + + return OK; +} + +/* + * 遍历 + * + * 用visit函数访问广义表L。 + */ +void Traverse(GList L, void(Visit)(AtomType)) { + if(L == NULL) { + return; + } + + if(L->tag == List) { + Traverse(L->Node.hp, Visit); + } else { + Visit(L->Node.atom); + } + + Traverse(L->tp, Visit); +} + +/* + * 图形化输出 + * + * 带括号输出广义表L。 + */ +void PrintGraph(GList L) { + Print(L); + printf("\n"); +} + +/* + * 图形化输出的内部实现。 + */ +static void Print(GList L) { + if(L == NULL) { + return; + } + + // 处理表结点 + if(L->tag == List) { + printf("("); + + if(L->Node.hp) { + Print(L->Node.hp); + } + + if(L->tp) { + printf("),"); + Print(L->tp); + } else { + printf(")"); + } + + // 处理原子结点 + } else { + printf("%c", L->Node.atom); + if(L->tp) { + printf(","); + Print(L->tp); + } + } +} + +/* + * 将非空串str分割成两部分:hsub为第一个','之前的子串,str为第一个','之后的子串。 + * + *【注】 + * 1.这里假设字符串str输入正确,其中无空白符号, + * 但str外层的括号可能脱去,也可能未脱去。 + * 2.分离完成后,str也会发生变化 + */ +static void sever(SString hstr, SString str) { + int i, k, n; + SString ch; + + n = StrLength(str); + + i = 0; // 遍历字符串时的游标 + k = 0; // 标记遇到的未配对括号数量 + + do { + ++i; + + // 截取str第一个字符 + SubString(ch, str, i, 1); + + if(ch[1] == '(') { + ++k; + } + if(ch[1] == ')') { + --k; + } + } while(i < n && (ch[1] != ',' || k != 0)); + + if(i < n) { + SubString(hstr, str, 1, i - 1); + SubString(str, str, i + 1, n - i); + } else { + StrCopy(hstr, str); + ClearString(str); + } +} diff --git a/CLion/ExerciseBook/05.32.2/GList-E.h b/CLion/ExerciseBook/05.32.2/GList-E.h new file mode 100644 index 0000000..5e5b625 --- /dev/null +++ b/CLion/ExerciseBook/05.32.2/GList-E.h @@ -0,0 +1,146 @@ +/*=========================== + * 广义表的扩展线性链表存储表示 + ============================*/ + +#ifndef GLIST_E_H +#define GLIST_E_H + +#include +#include // 提供 malloc、realloc、free、exit 原型 +#include "Status.h" //**▲01 绪论**// +#include "SString.h" //**▲04 串**// + +/* 原子元素类型 */ +typedef char AtomType; //原子类型 + +/* + * 广义表结点标记 + * + * Atom-0:原子结点 + * List-1:表结点 + */ +typedef enum { Atom, List } ElemTag; + +/* 广义表(扩展线性链表存储表示)类型定义 */ +typedef struct GLNode { + ElemTag tag; // 公共标记,用于区分原子结点和表结点 + + // 原子结点和表结点的联合部分 + union + { + AtomType atom; // atom是原子结点的值域,AtomType由用户定义 + struct GLNode* hp; // 指向表头 + } Node; + struct GLNode* tp; // 指向表尾 +} GLNode; + +/* 广义表类型 */ +typedef GLNode* GList; + + +/* + * 初始化 + * + * 初始化空的广义表,长度为0,深度为1。 + * + *【注】 + * 需要对每一层带上括号考察 + */ +Status InitGList(GList* L); + +/* + * 创建 + * + * 由字符串S创建广义表L。 + */ +Status CreateGList(GList* L, SString S); + +/* + * 销毁 + * + * 释放广义表所占内存。 + */ +Status DestroyGList(GList* L); + +/* + * 复制 + * + * 由广义表L复制得到广义表T。 + */ +Status CopyGList(GList* T, GList L); + +/* + * 计数 + * + * 返回广义表的长度。 + */ +int GListLength(GList L); + +/* + * 深度 + * + * 返回广义表的深度 + */ +int GListDepth(GList L); + +/* + * 判空 + * + * 判断广义表是否为空。 + */ +Status GListEmpty(GList L); + +/* + * 表头 + */ +GList GetHead(GList L); + +/* + * 表尾 + */ +GList GetTail(GList L); + +/* + * 插入 + * + * 将元素e插入为广义表L的第一个元素。 + */ +Status InsertFirst(GList* L, GList e); + +/* + * 删除 + * + * 将广义表L的第一个元素删除,并用e返回。 + */ +Status DeleteFirst(GList* L, GList* e); + +/* + * 遍历 + * + * 用visit函数访问广义表L。 + */ +void Traverse(GList L, void(Visit)(AtomType)); + +/* + * 图形化输出 + * + * 带括号输出广义表L。 + */ +void PrintGraph(GList L); + +/* + * 图形化输出的内部实现。 + */ +static void Print(GList L); + +/* + * 将非空串str分割成两部分:hsub为第一个','之前的子串,str为第一个','之后的子串。 + * + *【注】 + * 1.这里假设字符串str输入正确,其中无空白符号, + * 但str外层的括号可能脱去,也可能未脱去。 + * 2.分离完成后,str也会发生变化 + */ +static void sever(SString hstr, SString str); + +#endif diff --git a/CLion/ExerciseBook/05.32.2/SString.c b/CLion/ExerciseBook/05.32.2/SString.c new file mode 100644 index 0000000..41d9e15 --- /dev/null +++ b/CLion/ExerciseBook/05.32.2/SString.c @@ -0,0 +1,195 @@ +/*============================= + * 串的定长顺序存储表示(顺序串) + * + * 包含算法: 4.1、4.2、4.3、4.5 + ==============================*/ + +#include "SString.h" //**▲04 串**// + +/* + * 初始化 + * + * 构造一个值为chars的串T。 + * + *【注】 + * 该操作属于最小操作子集 + */ +Status StrAssign(SString T, const char* chars) { + int i, len; + + len = (int) strlen(chars); + + // chars过长 + if(len > MAXSTRLEN) { + return ERROR; + } + + T[0] = len; + for(i = 1; i <= len; i++) { + T[i] = chars[i - 1]; + } + + return OK; +} + +/* + * 清空 + * + * 将串S清空。 + */ +Status ClearString(SString S) { + // 只需要将长度置为0就可以 + S[0] = 0; + return OK; +} + +/* + * 判空 + * + * 判断串S中是否包含有效数据。 + * + * 返回值: + * TRUE : 串S为空 + * FALSE: 串S不为空 + */ +Status StrEmpty(SString S) { + return S[0] == 0 ? TRUE : FALSE; +} + +/* + * 计数 + * + * 返回串S中元素的个数。 + * + *【注】 + * 该操作属于最小操作子集 + */ +int StrLength(SString S) { + return S[0]; +} + +/* + * ████████ 算法4.3 ████████ + * + * 求子串 + * + * 用Sub返回S[pos, pos+len-1]。 + * 返回值指示是否截取成功。 + * + *【注】 + * 该操作属于最小操作子集 + */ +Status SubString(SString Sub, SString S, int pos, int len) { + int i; + + if(pos < 1 || pos > S[0] || len < 0 || pos + len - 1 > S[0]) { + return ERROR; + } + + // 复制元素 + for(i = 1; i <= len; i++) { + Sub[i] = S[pos + i - 1]; + } + + // 确定新长度 + Sub[0] = len; + + return OK; +} + +/* + * 删除 + * + * 删除S[pos, pos+len-1]。 + */ +Status StrDelete(SString S, int pos, int len) { + int i; + + if(pos < 1 || pos + len - 1 > S[0] || len < 0) { + return ERROR; + } + + // 如果待删除的长度为0,则提前返回 + if(len == 0) { + return OK; + } + + // 把后面的元素挪到前面,覆盖掉被删除的元素 + for(i = pos + len; i <= S[0]; i++) { + S[i - len] = S[i]; + } + + // 长度减少 + S[0] -= len; + + return OK; +} + +/* + * 比较 + * + * 比较串S和串T,返回比较结果。 + * + *【注】 + * 该操作属于最小操作子集 + */ +int StrCompare(SString S, SString T) { + int i = 1; + + while(i <= S[0] && i <= T[0]) { + // 遇到不同的字符时,比较其大小 + if(S[i] != T[i]) { + return S[i] - T[i]; + } + + i++; + } + + return S[0] - T[0]; +} + +/* + * 复制 + * + * 将串S复制到串T。 + */ +Status StrCopy(SString T, SString S) { + int i; + + // 连同长度信息一起复制 + for(i = 0; i <= S[0]; i++) { + T[i] = S[i]; + } + + return OK; +} + +/* + * 清理字符串S中的空白,包括清理不可打印字符和清理空格。 + * + *【注】 + * 该函数是在本章中新增的。 + */ +Status ClearBlank(SString S) { + int i, j; + + // 如果是空串 + if(S[0] == 0) { + return ERROR; + } + + for(i = 1, j = 0; i <= S[0]; i++) { + // 如果遇到空白,则略过 + if(S[i] == ' ' || !isprint(S[i])) { + continue; + } + + j++; + + S[j] = S[i]; + } + + S[0] = j; + + return OK; +} diff --git a/CLion/ExerciseBook/05.32.2/SString.h b/CLion/ExerciseBook/05.32.2/SString.h new file mode 100644 index 0000000..e81ca79 --- /dev/null +++ b/CLion/ExerciseBook/05.32.2/SString.h @@ -0,0 +1,117 @@ +/*============================= + * 串的定长顺序存储表示(顺序串) + * + * 包含算法: 4.1、4.2、4.3、4.5 + ==============================*/ + +#ifndef SSTRING_H +#define SSTRING_H + +#include +#include // 提供 strlen 原型 +#include // 提供 isprint 原型 +#include "Status.h" //**▲01 绪论**// + +/* 宏定义 */ +#define MAXSTRLEN 255 // 顺序串的最大串长 + +/* + * 串的顺序存储类型定义 + * + * 注:有效元素从SString的1号单元开始存储 + * SString的0号单元用来存储其长度 + */ +typedef unsigned char SString[MAXSTRLEN + 1]; // 0号单元存放串的长度 + + +/* + * ████ 提示 ████ + * + * 遵循教材的书写习惯,pos指示字符的位序(不是索引),从1开始计数 + */ + + +/* + * 初始化 + * + * 构造一个值为chars的串T。 + * + *【注】 + * 该操作属于最小操作子集 + */ +Status StrAssign(SString T, const char* chars); + +/* + * 清空 + * + * 将串S清空。 + */ +Status ClearString(SString S); + +/* + * 判空 + * + * 判断串S中是否包含有效数据。 + * + * 返回值: + * TRUE : 串S为空 + * FALSE: 串S不为空 + */ +Status StrEmpty(SString S); + +/* + * 计数 + * + * 返回串S中元素的个数。 + * + *【注】 + * 该操作属于最小操作子集 + */ +int StrLength(SString S); + +/* + * ████████ 算法4.3 ████████ + * + * 求子串 + * + * 用Sub返回S[pos, pos+len-1]。 + * 返回值指示是否截取成功。 + * + *【注】 + * 该操作属于最小操作子集 + */ +Status SubString(SString Sub, SString S, int pos, int len); + +/* + * 删除 + * + * 删除S[pos, pos+len-1]。 + */ +Status StrDelete(SString S, int pos, int len); + +/* + * 比较 + * + * 比较串S和串T,返回比较结果。 + * + *【注】 + * 该操作属于最小操作子集 + */ +int StrCompare(SString S, SString T); + +/* + * 复制 + * + * 将串S复制到串T。 + */ +Status StrCopy(SString T, SString S); + +/* + * 清理字符串S中的空白,包括清理不可打印字符和清理空格。 + * + *【注】 + * 该函数是在本章中新增的。 + */ +Status ClearBlank(SString S); + +#endif diff --git a/CLion/ExerciseBook/05.33.1/05.33.1.c b/CLion/ExerciseBook/05.33.1/05.33.1.c new file mode 100644 index 0000000..a35f1e4 --- /dev/null +++ b/CLion/ExerciseBook/05.33.1/05.33.1.c @@ -0,0 +1,47 @@ +#include +#include "SString.h" //**▲04 串**// +#include "GList-HT.h" //**▲05 数组和广义表**// + +/* + * 输出广义表中所有原子项及其所在层次(头尾链表存储表示) + */ +void Algo_5_33_1(GList L, int d); + + +int main(int argc, char* argv[]) { + GList L; + char* s = "((),(e),(a,(b,c,d)))"; + SString S; + + printf("创建广义表 L ...\n"); + StrAssign(S, s); + CreateGList(&L, S); + printf("L = "); + PrintGraph(L); + + Algo_5_33_1(L, 0); + + return 0; +} + + +/* + * 输出广义表中所有原子项及其所在层次(头尾链表存储表示) + */ +void Algo_5_33_1(GList L, int d) { + int i = d; // d的初值赋值为0 + + if(L == NULL) { + return; + } + + if(L->tag == Atom) { + printf("%c -> 第%d层\n", L->Node.atom, i); + } + + // 表头指针指向表的话层数增一 + if(L->tag == List) { + Algo_5_33_1(L->Node.ptr.hp, i + 1); + Algo_5_33_1(L->Node.ptr.tp, i); + } +} diff --git a/CLion/ExerciseBook/05.33.1/CMakeLists.txt b/CLion/ExerciseBook/05.33.1/CMakeLists.txt new file mode 100644 index 0000000..eac9fba --- /dev/null +++ b/CLion/ExerciseBook/05.33.1/CMakeLists.txt @@ -0,0 +1,7 @@ +# 包含公共库 +include_directories(${CMAKE_SOURCE_DIR}/Status) + +# 生成可执行文件 +add_executable(05.33.1 SString.h SString.c GList-HT.h GList-HT.c 05.33.1.c) +# 链接公共库 +target_link_libraries(05.33.1 Scanf_lib) \ No newline at end of file diff --git a/CLion/ExerciseBook/05.33.1/GList-HT.c b/CLion/ExerciseBook/05.33.1/GList-HT.c new file mode 100644 index 0000000..ddf2766 --- /dev/null +++ b/CLion/ExerciseBook/05.33.1/GList-HT.c @@ -0,0 +1,418 @@ +/*============================ + * 广义表的头尾链表存储表示 + * + * 包含算法: 5.5、5.6、5.7、5.8 + =============================*/ + +#include "GList-HT.h" //**▲05 数组和广义表**// + +/* + * 初始化 + * + * 初始化空的广义表,长度为0,深度为1。 + * + *【注】 + * 需要对每一层去掉括号考察 + */ +Status InitGList(GList* L) { + if(L == NULL) { + return ERROR; + } + + *L = NULL; + + return OK; +} + +/* + * ████████ 算法5.7 ████████ + * + * 创建 + * + * 由字符串S创建广义表L。 + */ +Status CreateGList(GList* L, SString S) { + SString emp; // 代表空广义表的字符串 + SString hsub, sub; + GList p, q; + + if(L == NULL) { + return ERROR; + } + + // 清理字符串S中的空白,包括清理不可打印字符和清理空格 + ClearBlank(S); + + if(StrEmpty(S)) { + return ERROR; + } + + StrAssign(emp, "()"); + + /* + * 如果输入串为(),则代表需要创建空的广义表 + * + *【注】 + * 教材这里的代码是有问题的。 + * StrCompare的返回值指示的是两个字符串的大小,而不是指示两个字符串是否相等。 + * 如果给定的S与()相等,返回值应当是0。 + */ + if(!StrCompare(S, emp)) { + *L = NULL; + } else { + *L = (GList) malloc(sizeof(GLNode)); + if(*L == NULL) { + exit(OVERFLOW); + } + + // 创建原子 + if(StrLength(S) == 1) { + (*L)->tag = Atom; + (*L)->Node.atom = S[1]; + } else { + (*L)->tag = List; + + p = *L; + + // 去掉最外层括号 + SubString(sub, S, 2, StrLength(S) - 2); + + // 重复建n个子表 + do { + // 从sub中分离出表头串hsub,分离完成后,sub也会发生变化 + sever(hsub, sub); + + // 递归创建广义表 + CreateGList(&(p->Node.ptr.hp), hsub); + + q = p; + + // 如果表尾不为空,需要继续处理表尾 + if(!StrEmpty(sub)) { + p = (GList) malloc(sizeof(GLNode)); + if(p == NULL) { + exit(OVERFLOW); + } + + p->tag = List; + + q->Node.ptr.tp = p; + } + } while(!StrEmpty(sub)); + + q->Node.ptr.tp = NULL; + } + } + + return OK; +} + +/* + * 销毁 + * + * 释放广义表所占内存。 + */ +Status DestroyGList(GList* L) { + GList head, tail; + + if(L == NULL || *L == NULL) { + return ERROR; + } + + // 删除原子结点 + if((*L)->tag == Atom) { + free(*L); + *L = NULL; + + // 删除子表结点 + } else { + head = (*L)->Node.ptr.hp; + tail = (*L)->Node.ptr.tp; + free(*L); + *L = NULL; + DestroyGList(&head); + DestroyGList(&tail); + } + + return OK; +} + +/* + * ████████ 算法5.6 ████████ + * + * 复制 + * + * 由广义表L复制得到广义表T。 + */ +Status CopyGList(GList* T, GList L) { + if(T == NULL) { + return ERROR; + } + + if(L == NULL) { + *T = NULL; + } else { + // 新建广义表结点 + *T = (GList) malloc(sizeof(GLNode)); + if(*T == NULL) { + exit(OVERFLOW); + } + + (*T)->tag = L->tag; + + // 复制单原子 + if(L->tag == Atom) { + (*T)->Node.atom = L->Node.atom; + + // 复制表头和表尾 + } else { + CopyGList(&((*T)->Node.ptr.hp), L->Node.ptr.hp); + CopyGList(&((*T)->Node.ptr.tp), L->Node.ptr.tp); + } + } + + return OK; +} + +/* + * 计数 + * + * 返回广义表的长度。 + */ +int GListLength(GList L) { + int count; + + for(count = 0; L != NULL; count++, L = L->Node.ptr.tp) { + } + + return count; +} + +/* + * ████████ 算法5.5 ████████ + * + * 深度 + * + * 返回广义表的深度 + */ +int GListDepth(GList L) { + int max, deep; + GList p; + + // 空表深度为1 + if(L == NULL) { + return 1; + } + + // 原子深度为0 + if(L->tag == Atom) { + return 0; + } + + // 递归求子表深度 + for(max = 0, p = L; p != NULL; p = p->Node.ptr.tp) { + deep = GListDepth(p->Node.ptr.hp); + if(deep > max) { + max = deep; + } + } + + // 非空表的深度是各子元素最大深度加一 + return max + 1; +} + +/* + * 判空 + * + * 判断广义表是否为空。 + */ +Status GListEmpty(GList L) { + return L == NULL ? TRUE : FALSE; +} + +/* + * 表头 + */ +GList GetHead(GList L) { + GList p; + + // 空表无表头,这里不能返回NULL,不然分不清是失败了还是返回了空表 + if(L == NULL) { + exit(ERROR); + } + + CopyGList(&p, L->Node.ptr.hp); + + return p; +} + +/* + * 表尾 + */ +GList GetTail(GList L) { + GList p; + + // 空表无表尾,这里不能返回NULL,不然分不清是失败了还是返回了空表 + if(L == NULL) { + exit(ERROR); + } + + CopyGList(&p, L->Node.ptr.tp); + + return p; +} + +/* + * 插入 + * + * 将元素e插入为广义表L的第一个元素。 + */ +Status InsertFirst(GList* L, GList e) { + GList g; + + if(L == NULL) { + return ERROR; + } + + g = (GList) malloc(sizeof(GLNode)); + if(g == NULL) { + exit(OVERFLOW); + } + + g->tag = List; + g->Node.ptr.hp = e; + g->Node.ptr.tp = *L; + *L = g; + + return OK; +} + +/* + * 删除 + * + * 将广义表L的第一个元素删除,并用e返回。 + */ +Status DeleteFirst(GList* L, GList* e) { + GList p; + + // 空表无法删除 + if(L == NULL || *L == NULL) { + return ERROR; + } + + p = *L; + *L = (*L)->Node.ptr.tp; + + CopyGList(e, p->Node.ptr.hp); + + free(p); + + return OK; +} + +/* + * 遍历 + * + * 用visit函数访问广义表L。 + */ +void Traverse(GList L, void(Visit)(AtomType)) { + + if(L == NULL) { + return; + } + + if(L->tag == Atom) { + Visit(L->Node.atom); + } else { + Traverse(L->Node.ptr.hp, Visit); + Traverse(L->Node.ptr.tp, Visit); + } + +} + +/* + * 图形化输出 + * + * 带括号输出广义表L。 + */ +void PrintGraph(GList L) { + Print(L, Head); + printf("\n"); +} + +/* + * 图形化输出的内部实现,mark是图形化输出标记。 + */ +static void Print(GList L, Mark mark) { + // L为空 + if(L == NULL) { + if(mark == Head) { + printf("("); + } + + printf(")"); + + // L不为空时 + } else { + // 对于原子结点,输出原子 + if(L->tag == Atom) { + printf("%c", L->Node.atom); + + // 对于子表结点,要对表头、表尾分别讨论 + } else { + if(mark == Head) { + printf("("); + } else { + printf(","); + } + + Print(L->Node.ptr.hp, Head); + Print(L->Node.ptr.tp, Tail); + } + } +} + +/* + * ████████ 算法5.8 ████████ + * + * 将非空串str分割成两部分:hsub为第一个','之前的子串,str为第一个','之后的子串。 + * + *【注】 + * 1.这里假设字符串str输入正确,其中无空白符号,且str【已经脱去最外层括号】。 + * 2.分离完成后,str也会发生变化 + */ +static void sever(SString hstr, SString str) { + int i, k, n; + SString ch; + + n = StrLength(str); + + i = 0; // 遍历字符串时的游标 + k = 0; // 标记遇到的未配对括号数量 + + do { + ++i; + + // 截取str第一个字符 + SubString(ch, str, i, 1); + + if(ch[1] == '(') { + ++k; + } + + if(ch[1] == ')') { + --k; + } + } while(i < n && (ch[1] != ',' || k != 0)); + + // 如果存在多个广义表结点 + if(i < n) { + SubString(hstr, str, 1, i - 1); + SubString(str, str, i + 1, n - i); + + // 只有一个广义表结点 + } else { + StrCopy(hstr, str); + ClearString(str); + } +} diff --git a/CLion/ExerciseBook/05.33.1/GList-HT.h b/CLion/ExerciseBook/05.33.1/GList-HT.h new file mode 100644 index 0000000..07c0df2 --- /dev/null +++ b/CLion/ExerciseBook/05.33.1/GList-HT.h @@ -0,0 +1,164 @@ +/*============================ + * 广义表的头尾链表存储表示 + * + * 包含算法: 5.5、5.6、5.7、5.8 + =============================*/ + +#ifndef GLIST_HT_H +#define GLIST_HT_H + +#include +#include // 提供 malloc、realloc、free、exit 原型 +#include "Status.h" //**▲01 绪论**// +#include "SString.h" //**▲04 串**// + +/* 原子元素类型 */ +typedef char AtomType; + +/* + * 广义表结点标记 + * + * Atom-0:原子结点 + * List-1:表结点 + */ +typedef enum { Atom, List } ElemTag; + +/* 广义表(头尾链表存储表示)类型定义 */ +typedef struct GLNode { + ElemTag tag; // 公共标记,用于区分原子结点和表结点 + + // 原子结点和表结点的联合部分 + union { + AtomType atom; // atom是原子结点的值域,AtomType由用户定义 + struct { + struct GLNode* hp; // 指向表头 + struct GLNode* tp; // 指向表尾 + } ptr; // 表结点的指针域 + } Node; +} GLNode; + +/* 广义表类型 */ +typedef GLNode* GList; + +/* + * 图形化输出标记 + * + * Head代表广义表指针来自表头 + * Tail代表广义表指针来自表尾 + */ +typedef enum { Head, Tail } Mark; + + +/* + * 初始化 + * + * 初始化空的广义表,长度为0,深度为1。 + * + *【注】 + * 需要对每一层去掉括号考察 + */ +Status InitGList(GList* L); + +/* + * ████████ 算法5.7 ████████ + * + * 创建 + * + * 由字符串S创建广义表L。 + */ +Status CreateGList(GList* L, SString S); + +/* + * 销毁 + * + * 释放广义表所占内存。 + */ +Status DestroyGList(GList* L); + +/* + * ████████ 算法5.6 ████████ + * + * 复制 + * + * 由广义表L复制得到广义表T。 + */ +Status CopyGList(GList* T, GList L); + +/* + * 计数 + * + * 返回广义表的长度。 + */ +int GListLength(GList L); + +/* + * ████████ 算法5.5 ████████ + * + * 深度 + * + * 返回广义表的深度 + */ +int GListDepth(GList L); + +/* + * 判空 + * + * 判断广义表是否为空。 + */ +Status GListEmpty(GList L); + +/* + * 表头 + */ +GList GetHead(GList L); + +/* + * 表尾 + */ +GList GetTail(GList L); + +/* + * 插入 + * + * 将元素e插入为广义表L的第一个元素。 + */ +Status InsertFirst(GList* L, GList e); + +/* + * 删除 + * + * 将广义表L的第一个元素删除,并用e返回。 + */ +Status DeleteFirst(GList* L, GList* e); + +/* + * 遍历 + * + * 用visit函数访问广义表L。 + */ +void Traverse(GList L, void (Visit)(AtomType)); + +/* + * 图形化输出 + * + * 带括号输出广义表L。 + */ +void PrintGraph(GList L); + +/* + * 图形化输出的内部实现,mark是图形化输出标记。 + */ +static void Print(GList L, Mark mark); + +/* + * ████████ 算法5.8 ████████ + * + * 将非空串str分割成两部分:hsub为第一个','之前的子串,str为第一个','之后的子串。 + * + *【注】 + * 1.这里假设字符串str输入正确,其中无空白符号,且str【已经脱去最外层括号】。 + * 2.分离完成后,str也会发生变化 + */ +static void sever(SString hstr, SString str); + +#endif diff --git a/CLion/ExerciseBook/05.33.1/SString.c b/CLion/ExerciseBook/05.33.1/SString.c new file mode 100644 index 0000000..41d9e15 --- /dev/null +++ b/CLion/ExerciseBook/05.33.1/SString.c @@ -0,0 +1,195 @@ +/*============================= + * 串的定长顺序存储表示(顺序串) + * + * 包含算法: 4.1、4.2、4.3、4.5 + ==============================*/ + +#include "SString.h" //**▲04 串**// + +/* + * 初始化 + * + * 构造一个值为chars的串T。 + * + *【注】 + * 该操作属于最小操作子集 + */ +Status StrAssign(SString T, const char* chars) { + int i, len; + + len = (int) strlen(chars); + + // chars过长 + if(len > MAXSTRLEN) { + return ERROR; + } + + T[0] = len; + for(i = 1; i <= len; i++) { + T[i] = chars[i - 1]; + } + + return OK; +} + +/* + * 清空 + * + * 将串S清空。 + */ +Status ClearString(SString S) { + // 只需要将长度置为0就可以 + S[0] = 0; + return OK; +} + +/* + * 判空 + * + * 判断串S中是否包含有效数据。 + * + * 返回值: + * TRUE : 串S为空 + * FALSE: 串S不为空 + */ +Status StrEmpty(SString S) { + return S[0] == 0 ? TRUE : FALSE; +} + +/* + * 计数 + * + * 返回串S中元素的个数。 + * + *【注】 + * 该操作属于最小操作子集 + */ +int StrLength(SString S) { + return S[0]; +} + +/* + * ████████ 算法4.3 ████████ + * + * 求子串 + * + * 用Sub返回S[pos, pos+len-1]。 + * 返回值指示是否截取成功。 + * + *【注】 + * 该操作属于最小操作子集 + */ +Status SubString(SString Sub, SString S, int pos, int len) { + int i; + + if(pos < 1 || pos > S[0] || len < 0 || pos + len - 1 > S[0]) { + return ERROR; + } + + // 复制元素 + for(i = 1; i <= len; i++) { + Sub[i] = S[pos + i - 1]; + } + + // 确定新长度 + Sub[0] = len; + + return OK; +} + +/* + * 删除 + * + * 删除S[pos, pos+len-1]。 + */ +Status StrDelete(SString S, int pos, int len) { + int i; + + if(pos < 1 || pos + len - 1 > S[0] || len < 0) { + return ERROR; + } + + // 如果待删除的长度为0,则提前返回 + if(len == 0) { + return OK; + } + + // 把后面的元素挪到前面,覆盖掉被删除的元素 + for(i = pos + len; i <= S[0]; i++) { + S[i - len] = S[i]; + } + + // 长度减少 + S[0] -= len; + + return OK; +} + +/* + * 比较 + * + * 比较串S和串T,返回比较结果。 + * + *【注】 + * 该操作属于最小操作子集 + */ +int StrCompare(SString S, SString T) { + int i = 1; + + while(i <= S[0] && i <= T[0]) { + // 遇到不同的字符时,比较其大小 + if(S[i] != T[i]) { + return S[i] - T[i]; + } + + i++; + } + + return S[0] - T[0]; +} + +/* + * 复制 + * + * 将串S复制到串T。 + */ +Status StrCopy(SString T, SString S) { + int i; + + // 连同长度信息一起复制 + for(i = 0; i <= S[0]; i++) { + T[i] = S[i]; + } + + return OK; +} + +/* + * 清理字符串S中的空白,包括清理不可打印字符和清理空格。 + * + *【注】 + * 该函数是在本章中新增的。 + */ +Status ClearBlank(SString S) { + int i, j; + + // 如果是空串 + if(S[0] == 0) { + return ERROR; + } + + for(i = 1, j = 0; i <= S[0]; i++) { + // 如果遇到空白,则略过 + if(S[i] == ' ' || !isprint(S[i])) { + continue; + } + + j++; + + S[j] = S[i]; + } + + S[0] = j; + + return OK; +} diff --git a/CLion/ExerciseBook/05.33.1/SString.h b/CLion/ExerciseBook/05.33.1/SString.h new file mode 100644 index 0000000..e81ca79 --- /dev/null +++ b/CLion/ExerciseBook/05.33.1/SString.h @@ -0,0 +1,117 @@ +/*============================= + * 串的定长顺序存储表示(顺序串) + * + * 包含算法: 4.1、4.2、4.3、4.5 + ==============================*/ + +#ifndef SSTRING_H +#define SSTRING_H + +#include +#include // 提供 strlen 原型 +#include // 提供 isprint 原型 +#include "Status.h" //**▲01 绪论**// + +/* 宏定义 */ +#define MAXSTRLEN 255 // 顺序串的最大串长 + +/* + * 串的顺序存储类型定义 + * + * 注:有效元素从SString的1号单元开始存储 + * SString的0号单元用来存储其长度 + */ +typedef unsigned char SString[MAXSTRLEN + 1]; // 0号单元存放串的长度 + + +/* + * ████ 提示 ████ + * + * 遵循教材的书写习惯,pos指示字符的位序(不是索引),从1开始计数 + */ + + +/* + * 初始化 + * + * 构造一个值为chars的串T。 + * + *【注】 + * 该操作属于最小操作子集 + */ +Status StrAssign(SString T, const char* chars); + +/* + * 清空 + * + * 将串S清空。 + */ +Status ClearString(SString S); + +/* + * 判空 + * + * 判断串S中是否包含有效数据。 + * + * 返回值: + * TRUE : 串S为空 + * FALSE: 串S不为空 + */ +Status StrEmpty(SString S); + +/* + * 计数 + * + * 返回串S中元素的个数。 + * + *【注】 + * 该操作属于最小操作子集 + */ +int StrLength(SString S); + +/* + * ████████ 算法4.3 ████████ + * + * 求子串 + * + * 用Sub返回S[pos, pos+len-1]。 + * 返回值指示是否截取成功。 + * + *【注】 + * 该操作属于最小操作子集 + */ +Status SubString(SString Sub, SString S, int pos, int len); + +/* + * 删除 + * + * 删除S[pos, pos+len-1]。 + */ +Status StrDelete(SString S, int pos, int len); + +/* + * 比较 + * + * 比较串S和串T,返回比较结果。 + * + *【注】 + * 该操作属于最小操作子集 + */ +int StrCompare(SString S, SString T); + +/* + * 复制 + * + * 将串S复制到串T。 + */ +Status StrCopy(SString T, SString S); + +/* + * 清理字符串S中的空白,包括清理不可打印字符和清理空格。 + * + *【注】 + * 该函数是在本章中新增的。 + */ +Status ClearBlank(SString S); + +#endif diff --git a/CLion/ExerciseBook/05.33.2/05.33.2.c b/CLion/ExerciseBook/05.33.2/05.33.2.c new file mode 100644 index 0000000..68ceea4 --- /dev/null +++ b/CLion/ExerciseBook/05.33.2/05.33.2.c @@ -0,0 +1,48 @@ +#include +#include "SString.h" //**▲04 串**// +#include "GList-E.h" //**▲05 数组和广义表**// + +/* + * 输出广义表中所有原子项及其所在层次(扩展线性链表存储表示) + */ +void Algo_5_33_2(GList L, int d); + + +int main(int argc, char* argv[]) { + GList L; + char* s = "((),(e),(a,(b,c,d)))"; + SString S; + + printf("创建广义表 L ...\n"); + StrAssign(S, s); + CreateGList(&L, S); + printf("L = "); + PrintGraph(L); + + Algo_5_33_2(L, 0); + + return 0; +} + + +/* + * 输出广义表中所有原子项及其所在层次(扩展线性链表存储表示) + */ +void Algo_5_33_2(GList L, int d) { + int i = d; // d初值赋为0 + + if(L == NULL) { + return; + } + + if(L->tag == Atom) { + printf("%c -> 第%d层\n", L->Node.atom, i); + } + + + if(L->tag == List) { + Algo_5_33_2(L->Node.hp, i + 1); // 表头指针指向表的话层数增一 + } + + Algo_5_33_2(L->tp, i); +} diff --git a/CLion/ExerciseBook/05.33.2/CMakeLists.txt b/CLion/ExerciseBook/05.33.2/CMakeLists.txt new file mode 100644 index 0000000..36503c0 --- /dev/null +++ b/CLion/ExerciseBook/05.33.2/CMakeLists.txt @@ -0,0 +1,7 @@ +# 包含公共库 +include_directories(${CMAKE_SOURCE_DIR}/Status) + +# 生成可执行文件 +add_executable(05.33.2 SString.h SString.c GList-E.h GList-E.c 05.33.2.c) +# 链接公共库 +target_link_libraries(05.33.2 Scanf_lib) \ No newline at end of file diff --git a/CLion/ExerciseBook/05.33.2/GList-E.c b/CLion/ExerciseBook/05.33.2/GList-E.c new file mode 100644 index 0000000..d994024 --- /dev/null +++ b/CLion/ExerciseBook/05.33.2/GList-E.c @@ -0,0 +1,449 @@ +/*=========================== + * 广义表的扩展线性链表存储表示 + ============================*/ + +#include "GList-E.h" //**▲05 数组和广义表**// + +/* + * 初始化 + * + * 初始化空的广义表,长度为0,深度为1。 + * + *【注】 + * 需要对每一层带上括号考察 + */ +Status InitGList(GList* L) { + if(L == NULL) { + return ERROR; + } + + *L = (GList) malloc(sizeof(GLNode)); + if(!*L) { + exit(OVERFLOW); + } + + (*L)->tag = List; + (*L)->Node.hp = NULL; + (*L)->tp = NULL; + + return OK; +} + +/* + * 创建 + * + * 由字符串S创建广义表L。 + */ +Status CreateGList(GList* L, SString S) { + SString emp, hsub, sub, tmp; + + if(L == NULL) { + return ERROR; + } + + // 清理字符串S中的空白,包括清理不可打印字符和清理空格 + ClearBlank(S); + + if(StrEmpty(S)) { + return ERROR; + } + + // 复制是为了不破坏S + StrCopy(sub, S); + + /* + * 初次执行到此时,带着最外层的括号 + * 再次执行到此时,已经脱去了外层括号 + */ + sever(hsub, sub); + + *L = (GList) malloc(sizeof(GLNode)); + if(*L == NULL) { + exit(OVERFLOW); + } + + StrAssign(emp, "()"); + + if(!StrCompare(hsub, emp)) { + (*L)->tag = List; + (*L)->Node.hp = NULL; + } else { + if(StrLength(hsub) == 1) { + (*L)->tag = Atom; + (*L)->Node.atom = hsub[1]; + } else { + (*L)->tag = List; + + SubString(tmp, hsub, 2, StrLength(hsub) - 2); + + CreateGList(&((*L)->Node.hp), tmp); + } + } + + // 如果不存在队尾,则退出本层递归 + if(StrEmpty(sub)) { + (*L)->tp = NULL; + } else { + // 继续递归求表尾 + CreateGList(&((*L)->tp), sub); + } + + return OK; +} + +/* + * 销毁 + * + * 释放广义表所占内存。 + */ +Status DestroyGList(GList* L) { + GList head, tail; + + if(L == NULL || *L == NULL) { + return ERROR; + } + + // 处理子表结点 + if((*L)->tag == List) { + head = (*L)->Node.hp; // 表头 + tail = (*L)->tp; // 表尾 + + free(*L); + *L = NULL; + + // 递归处理表头 + if(head != NULL) { + DestroyGList(&head); + } + + // 递归处理表尾 + if(tail != NULL) { + DestroyGList(&tail); + } + + // 处理原子结点 + } else { + tail = (*L)->tp; // 表尾 + + free(*L); + *L = NULL; + + if(tail != NULL) { + DestroyGList(&tail); + } + } + + return OK; +} + +/* + * 复制 + * + * 由广义表L复制得到广义表T。 + */ +Status CopyGList(GList* T, GList L) { + + if(L == NULL) { + return ERROR; + } + + *T = (GList) malloc(sizeof(GLNode)); + if(*T == NULL) { + exit(OVERFLOW); + } + + // 复制原子 + if(L->tag == Atom) { + (*T)->tag = Atom; + (*T)->Node.atom = L->Node.atom; + + // 复制子表 + } else { + (*T)->tag = List; + + // 复制表头 + if(L->Node.hp != NULL) { + CopyGList(&((*T)->Node.hp), L->Node.hp); + } else { + (*T)->Node.hp = NULL; + } + } + + // 复制表尾 + if(L->tp != NULL) { + CopyGList(&((*T)->tp), L->tp); + } else { + (*T)->tp = NULL; + } + + return OK; +} + +/* + * 计数 + * + * 返回广义表的长度。 + */ +int GListLength(GList L) { + int count = 0; + GList p; + + // 广义表不存在 + if(L == NULL) { + return -1; + } + + p = L->Node.hp; + + while(p != NULL) { + ++count; + p = p->tp; + } + + return count; +} + +/* + * 深度 + * + * 返回广义表的深度 + */ +int GListDepth(GList L) { + int max, deep; + GList p; + + max = 0; + + // 广义表不存在 + if(L == NULL) { + return -1; + } + + // 空表深度为1 + if(L->tag == List && !L->Node.hp) { + return 1; + } + + // 原子深度为0 + if(L->tag == Atom) { + return 0; + } + + // 递归求子表深度 + for(p = L->Node.hp; p != NULL; p = p->tp) { + // 求以p为头指针的子表深度 + deep = GListDepth(p); + if(deep > max) { + max = deep; + } + } + + return max + 1; +} + +/* + * 判空 + * + * 判断广义表是否为空。 + */ +Status GListEmpty(GList L) { + // 广义表不存在 + if(L == NULL) { + return ERROR; + } + + if(L->tag == List && L->Node.hp == NULL && L->tp == NULL) { + return TRUE; + } else { + return ERROR; + } +} + +/* + * 表头 + */ +GList GetHead(GList L) { + GList p, q; + + // 广义表不存在或广义表为空表,无法获取表头 + if(L == NULL || L->Node.hp == NULL) { + return NULL; + } + + q = L->Node.hp->tp; // 临时保存L的表尾信息 + L->Node.hp->tp = NULL; // 截去L的表尾部分 + + CopyGList(&p, L->Node.hp); // 复制表头信息(已屏蔽表尾) + + L->Node.hp->tp = q; // 恢复L的表尾信息 + + return p; +} + +/* + * 表尾 + */ +GList GetTail(GList L) { + GList p, q; + + // 广义表不存在或广义表为空表,无法获取表尾 + if(L == NULL || L->Node.hp == NULL) { + return NULL; + } + + q = L->Node.hp; // 临时保存L的表头信息 + L->Node.hp = q->tp; // 摘下L的表头部分 + + CopyGList(&p, L); // 复制表尾信息(已屏蔽表头) + + q->tp = L->Node.hp; // 恢复L的表头信息 + L->Node.hp = q; + + return p; +} + +/* + * 插入 + * + * 将元素e插入为广义表L的第一个元素。 + */ +Status InsertFirst(GList* L, GList e) { + + // 广义表不存在 + if(L == NULL || *L == NULL) { + return ERROR; + } + + if(e == NULL) { + return ERROR; + } + + e->tp = (*L)->Node.hp; + (*L)->Node.hp = e; + + return OK; +} + +/* + * 删除 + * + * 将广义表L的第一个元素删除,并用e返回。 + */ +Status DeleteFirst(GList* L, GList* e) { + GList p; + + // 广义表不存在或广义表为空表,则无法删除表头 + if(*L == NULL || (*L)->Node.hp == NULL) { + return ERROR; + } + + p = (*L)->Node.hp; + (*L)->Node.hp = p->tp; + p->tp = NULL; + + *e = p; + + return OK; +} + +/* + * 遍历 + * + * 用visit函数访问广义表L。 + */ +void Traverse(GList L, void(Visit)(AtomType)) { + if(L == NULL) { + return; + } + + if(L->tag == List) { + Traverse(L->Node.hp, Visit); + } else { + Visit(L->Node.atom); + } + + Traverse(L->tp, Visit); +} + +/* + * 图形化输出 + * + * 带括号输出广义表L。 + */ +void PrintGraph(GList L) { + Print(L); + printf("\n"); +} + +/* + * 图形化输出的内部实现。 + */ +static void Print(GList L) { + if(L == NULL) { + return; + } + + // 处理表结点 + if(L->tag == List) { + printf("("); + + if(L->Node.hp) { + Print(L->Node.hp); + } + + if(L->tp) { + printf("),"); + Print(L->tp); + } else { + printf(")"); + } + + // 处理原子结点 + } else { + printf("%c", L->Node.atom); + if(L->tp) { + printf(","); + Print(L->tp); + } + } +} + +/* + * 将非空串str分割成两部分:hsub为第一个','之前的子串,str为第一个','之后的子串。 + * + *【注】 + * 1.这里假设字符串str输入正确,其中无空白符号, + * 但str外层的括号可能脱去,也可能未脱去。 + * 2.分离完成后,str也会发生变化 + */ +static void sever(SString hstr, SString str) { + int i, k, n; + SString ch; + + n = StrLength(str); + + i = 0; // 遍历字符串时的游标 + k = 0; // 标记遇到的未配对括号数量 + + do { + ++i; + + // 截取str第一个字符 + SubString(ch, str, i, 1); + + if(ch[1] == '(') { + ++k; + } + if(ch[1] == ')') { + --k; + } + } while(i < n && (ch[1] != ',' || k != 0)); + + if(i < n) { + SubString(hstr, str, 1, i - 1); + SubString(str, str, i + 1, n - i); + } else { + StrCopy(hstr, str); + ClearString(str); + } +} diff --git a/CLion/ExerciseBook/05.33.2/GList-E.h b/CLion/ExerciseBook/05.33.2/GList-E.h new file mode 100644 index 0000000..5e5b625 --- /dev/null +++ b/CLion/ExerciseBook/05.33.2/GList-E.h @@ -0,0 +1,146 @@ +/*=========================== + * 广义表的扩展线性链表存储表示 + ============================*/ + +#ifndef GLIST_E_H +#define GLIST_E_H + +#include +#include // 提供 malloc、realloc、free、exit 原型 +#include "Status.h" //**▲01 绪论**// +#include "SString.h" //**▲04 串**// + +/* 原子元素类型 */ +typedef char AtomType; //原子类型 + +/* + * 广义表结点标记 + * + * Atom-0:原子结点 + * List-1:表结点 + */ +typedef enum { Atom, List } ElemTag; + +/* 广义表(扩展线性链表存储表示)类型定义 */ +typedef struct GLNode { + ElemTag tag; // 公共标记,用于区分原子结点和表结点 + + // 原子结点和表结点的联合部分 + union + { + AtomType atom; // atom是原子结点的值域,AtomType由用户定义 + struct GLNode* hp; // 指向表头 + } Node; + struct GLNode* tp; // 指向表尾 +} GLNode; + +/* 广义表类型 */ +typedef GLNode* GList; + + +/* + * 初始化 + * + * 初始化空的广义表,长度为0,深度为1。 + * + *【注】 + * 需要对每一层带上括号考察 + */ +Status InitGList(GList* L); + +/* + * 创建 + * + * 由字符串S创建广义表L。 + */ +Status CreateGList(GList* L, SString S); + +/* + * 销毁 + * + * 释放广义表所占内存。 + */ +Status DestroyGList(GList* L); + +/* + * 复制 + * + * 由广义表L复制得到广义表T。 + */ +Status CopyGList(GList* T, GList L); + +/* + * 计数 + * + * 返回广义表的长度。 + */ +int GListLength(GList L); + +/* + * 深度 + * + * 返回广义表的深度 + */ +int GListDepth(GList L); + +/* + * 判空 + * + * 判断广义表是否为空。 + */ +Status GListEmpty(GList L); + +/* + * 表头 + */ +GList GetHead(GList L); + +/* + * 表尾 + */ +GList GetTail(GList L); + +/* + * 插入 + * + * 将元素e插入为广义表L的第一个元素。 + */ +Status InsertFirst(GList* L, GList e); + +/* + * 删除 + * + * 将广义表L的第一个元素删除,并用e返回。 + */ +Status DeleteFirst(GList* L, GList* e); + +/* + * 遍历 + * + * 用visit函数访问广义表L。 + */ +void Traverse(GList L, void(Visit)(AtomType)); + +/* + * 图形化输出 + * + * 带括号输出广义表L。 + */ +void PrintGraph(GList L); + +/* + * 图形化输出的内部实现。 + */ +static void Print(GList L); + +/* + * 将非空串str分割成两部分:hsub为第一个','之前的子串,str为第一个','之后的子串。 + * + *【注】 + * 1.这里假设字符串str输入正确,其中无空白符号, + * 但str外层的括号可能脱去,也可能未脱去。 + * 2.分离完成后,str也会发生变化 + */ +static void sever(SString hstr, SString str); + +#endif diff --git a/CLion/ExerciseBook/05.33.2/SString.c b/CLion/ExerciseBook/05.33.2/SString.c new file mode 100644 index 0000000..41d9e15 --- /dev/null +++ b/CLion/ExerciseBook/05.33.2/SString.c @@ -0,0 +1,195 @@ +/*============================= + * 串的定长顺序存储表示(顺序串) + * + * 包含算法: 4.1、4.2、4.3、4.5 + ==============================*/ + +#include "SString.h" //**▲04 串**// + +/* + * 初始化 + * + * 构造一个值为chars的串T。 + * + *【注】 + * 该操作属于最小操作子集 + */ +Status StrAssign(SString T, const char* chars) { + int i, len; + + len = (int) strlen(chars); + + // chars过长 + if(len > MAXSTRLEN) { + return ERROR; + } + + T[0] = len; + for(i = 1; i <= len; i++) { + T[i] = chars[i - 1]; + } + + return OK; +} + +/* + * 清空 + * + * 将串S清空。 + */ +Status ClearString(SString S) { + // 只需要将长度置为0就可以 + S[0] = 0; + return OK; +} + +/* + * 判空 + * + * 判断串S中是否包含有效数据。 + * + * 返回值: + * TRUE : 串S为空 + * FALSE: 串S不为空 + */ +Status StrEmpty(SString S) { + return S[0] == 0 ? TRUE : FALSE; +} + +/* + * 计数 + * + * 返回串S中元素的个数。 + * + *【注】 + * 该操作属于最小操作子集 + */ +int StrLength(SString S) { + return S[0]; +} + +/* + * ████████ 算法4.3 ████████ + * + * 求子串 + * + * 用Sub返回S[pos, pos+len-1]。 + * 返回值指示是否截取成功。 + * + *【注】 + * 该操作属于最小操作子集 + */ +Status SubString(SString Sub, SString S, int pos, int len) { + int i; + + if(pos < 1 || pos > S[0] || len < 0 || pos + len - 1 > S[0]) { + return ERROR; + } + + // 复制元素 + for(i = 1; i <= len; i++) { + Sub[i] = S[pos + i - 1]; + } + + // 确定新长度 + Sub[0] = len; + + return OK; +} + +/* + * 删除 + * + * 删除S[pos, pos+len-1]。 + */ +Status StrDelete(SString S, int pos, int len) { + int i; + + if(pos < 1 || pos + len - 1 > S[0] || len < 0) { + return ERROR; + } + + // 如果待删除的长度为0,则提前返回 + if(len == 0) { + return OK; + } + + // 把后面的元素挪到前面,覆盖掉被删除的元素 + for(i = pos + len; i <= S[0]; i++) { + S[i - len] = S[i]; + } + + // 长度减少 + S[0] -= len; + + return OK; +} + +/* + * 比较 + * + * 比较串S和串T,返回比较结果。 + * + *【注】 + * 该操作属于最小操作子集 + */ +int StrCompare(SString S, SString T) { + int i = 1; + + while(i <= S[0] && i <= T[0]) { + // 遇到不同的字符时,比较其大小 + if(S[i] != T[i]) { + return S[i] - T[i]; + } + + i++; + } + + return S[0] - T[0]; +} + +/* + * 复制 + * + * 将串S复制到串T。 + */ +Status StrCopy(SString T, SString S) { + int i; + + // 连同长度信息一起复制 + for(i = 0; i <= S[0]; i++) { + T[i] = S[i]; + } + + return OK; +} + +/* + * 清理字符串S中的空白,包括清理不可打印字符和清理空格。 + * + *【注】 + * 该函数是在本章中新增的。 + */ +Status ClearBlank(SString S) { + int i, j; + + // 如果是空串 + if(S[0] == 0) { + return ERROR; + } + + for(i = 1, j = 0; i <= S[0]; i++) { + // 如果遇到空白,则略过 + if(S[i] == ' ' || !isprint(S[i])) { + continue; + } + + j++; + + S[j] = S[i]; + } + + S[0] = j; + + return OK; +} diff --git a/CLion/ExerciseBook/05.33.2/SString.h b/CLion/ExerciseBook/05.33.2/SString.h new file mode 100644 index 0000000..e81ca79 --- /dev/null +++ b/CLion/ExerciseBook/05.33.2/SString.h @@ -0,0 +1,117 @@ +/*============================= + * 串的定长顺序存储表示(顺序串) + * + * 包含算法: 4.1、4.2、4.3、4.5 + ==============================*/ + +#ifndef SSTRING_H +#define SSTRING_H + +#include +#include // 提供 strlen 原型 +#include // 提供 isprint 原型 +#include "Status.h" //**▲01 绪论**// + +/* 宏定义 */ +#define MAXSTRLEN 255 // 顺序串的最大串长 + +/* + * 串的顺序存储类型定义 + * + * 注:有效元素从SString的1号单元开始存储 + * SString的0号单元用来存储其长度 + */ +typedef unsigned char SString[MAXSTRLEN + 1]; // 0号单元存放串的长度 + + +/* + * ████ 提示 ████ + * + * 遵循教材的书写习惯,pos指示字符的位序(不是索引),从1开始计数 + */ + + +/* + * 初始化 + * + * 构造一个值为chars的串T。 + * + *【注】 + * 该操作属于最小操作子集 + */ +Status StrAssign(SString T, const char* chars); + +/* + * 清空 + * + * 将串S清空。 + */ +Status ClearString(SString S); + +/* + * 判空 + * + * 判断串S中是否包含有效数据。 + * + * 返回值: + * TRUE : 串S为空 + * FALSE: 串S不为空 + */ +Status StrEmpty(SString S); + +/* + * 计数 + * + * 返回串S中元素的个数。 + * + *【注】 + * 该操作属于最小操作子集 + */ +int StrLength(SString S); + +/* + * ████████ 算法4.3 ████████ + * + * 求子串 + * + * 用Sub返回S[pos, pos+len-1]。 + * 返回值指示是否截取成功。 + * + *【注】 + * 该操作属于最小操作子集 + */ +Status SubString(SString Sub, SString S, int pos, int len); + +/* + * 删除 + * + * 删除S[pos, pos+len-1]。 + */ +Status StrDelete(SString S, int pos, int len); + +/* + * 比较 + * + * 比较串S和串T,返回比较结果。 + * + *【注】 + * 该操作属于最小操作子集 + */ +int StrCompare(SString S, SString T); + +/* + * 复制 + * + * 将串S复制到串T。 + */ +Status StrCopy(SString T, SString S); + +/* + * 清理字符串S中的空白,包括清理不可打印字符和清理空格。 + * + *【注】 + * 该函数是在本章中新增的。 + */ +Status ClearBlank(SString S); + +#endif diff --git a/CLion/ExerciseBook/05.34.1/05.34.1.c b/CLion/ExerciseBook/05.34.1/05.34.1.c new file mode 100644 index 0000000..af342c8 --- /dev/null +++ b/CLion/ExerciseBook/05.34.1/05.34.1.c @@ -0,0 +1,62 @@ +#include +#include "Status.h" //**▲01 绪论**// +#include "SString.h" //**▲04 串**// +#include "GList-HT.h" //**▲05 数组和广义表**// + +/* + * 逆置广义表(头尾链表存储表示) + */ +Status Algo_5_34_1(GList* L); + + +int main(int argc, char* argv[]) { + GList L; + char* s = "(a,((b,c),()),(((d),e),f))"; + SString S; + + printf("创建广义表 L ...\n"); + StrAssign(S, s); + CreateGList(&L, S); + printf("L = "); + PrintGraph(L); + + printf("逆置广义表...\n"); + Algo_5_34_1(&L); + printf("L = "); + PrintGraph(L); + + return 0; +} + + +/* + * 逆置广义表(头尾链表存储表示) + */ +Status Algo_5_34_1(GList* L) { + GList head, tail; + + if(L == NULL || *L == NULL) { + return ERROR; + } + + // 从后向前,从里到外逆置 + head = *L; + tail = (*L)->Node.ptr.tp; + + // 对表头进行逆置 + if(head->Node.ptr.hp != NULL && head->Node.ptr.hp->tag == List) { + Algo_5_34_1(&(head->Node.ptr.hp)); + } + + // 对表尾进行逆置 + if(tail != NULL) { + Algo_5_34_1(&((*L)->Node.ptr.tp)); + + // 头尾交换 + *L = (*L)->Node.ptr.tp; + tail->Node.ptr.tp = head; + head->Node.ptr.tp = NULL; + } + + return OK; +} diff --git a/CLion/ExerciseBook/05.34.1/CMakeLists.txt b/CLion/ExerciseBook/05.34.1/CMakeLists.txt new file mode 100644 index 0000000..d4ae017 --- /dev/null +++ b/CLion/ExerciseBook/05.34.1/CMakeLists.txt @@ -0,0 +1,7 @@ +# 包含公共库 +include_directories(${CMAKE_SOURCE_DIR}/Status) + +# 生成可执行文件 +add_executable(05.34.1 SString.h SString.c GList-HT.h GList-HT.c 05.34.1.c) +# 链接公共库 +target_link_libraries(05.34.1 Scanf_lib) \ No newline at end of file diff --git a/CLion/ExerciseBook/05.34.1/GList-HT.c b/CLion/ExerciseBook/05.34.1/GList-HT.c new file mode 100644 index 0000000..ddf2766 --- /dev/null +++ b/CLion/ExerciseBook/05.34.1/GList-HT.c @@ -0,0 +1,418 @@ +/*============================ + * 广义表的头尾链表存储表示 + * + * 包含算法: 5.5、5.6、5.7、5.8 + =============================*/ + +#include "GList-HT.h" //**▲05 数组和广义表**// + +/* + * 初始化 + * + * 初始化空的广义表,长度为0,深度为1。 + * + *【注】 + * 需要对每一层去掉括号考察 + */ +Status InitGList(GList* L) { + if(L == NULL) { + return ERROR; + } + + *L = NULL; + + return OK; +} + +/* + * ████████ 算法5.7 ████████ + * + * 创建 + * + * 由字符串S创建广义表L。 + */ +Status CreateGList(GList* L, SString S) { + SString emp; // 代表空广义表的字符串 + SString hsub, sub; + GList p, q; + + if(L == NULL) { + return ERROR; + } + + // 清理字符串S中的空白,包括清理不可打印字符和清理空格 + ClearBlank(S); + + if(StrEmpty(S)) { + return ERROR; + } + + StrAssign(emp, "()"); + + /* + * 如果输入串为(),则代表需要创建空的广义表 + * + *【注】 + * 教材这里的代码是有问题的。 + * StrCompare的返回值指示的是两个字符串的大小,而不是指示两个字符串是否相等。 + * 如果给定的S与()相等,返回值应当是0。 + */ + if(!StrCompare(S, emp)) { + *L = NULL; + } else { + *L = (GList) malloc(sizeof(GLNode)); + if(*L == NULL) { + exit(OVERFLOW); + } + + // 创建原子 + if(StrLength(S) == 1) { + (*L)->tag = Atom; + (*L)->Node.atom = S[1]; + } else { + (*L)->tag = List; + + p = *L; + + // 去掉最外层括号 + SubString(sub, S, 2, StrLength(S) - 2); + + // 重复建n个子表 + do { + // 从sub中分离出表头串hsub,分离完成后,sub也会发生变化 + sever(hsub, sub); + + // 递归创建广义表 + CreateGList(&(p->Node.ptr.hp), hsub); + + q = p; + + // 如果表尾不为空,需要继续处理表尾 + if(!StrEmpty(sub)) { + p = (GList) malloc(sizeof(GLNode)); + if(p == NULL) { + exit(OVERFLOW); + } + + p->tag = List; + + q->Node.ptr.tp = p; + } + } while(!StrEmpty(sub)); + + q->Node.ptr.tp = NULL; + } + } + + return OK; +} + +/* + * 销毁 + * + * 释放广义表所占内存。 + */ +Status DestroyGList(GList* L) { + GList head, tail; + + if(L == NULL || *L == NULL) { + return ERROR; + } + + // 删除原子结点 + if((*L)->tag == Atom) { + free(*L); + *L = NULL; + + // 删除子表结点 + } else { + head = (*L)->Node.ptr.hp; + tail = (*L)->Node.ptr.tp; + free(*L); + *L = NULL; + DestroyGList(&head); + DestroyGList(&tail); + } + + return OK; +} + +/* + * ████████ 算法5.6 ████████ + * + * 复制 + * + * 由广义表L复制得到广义表T。 + */ +Status CopyGList(GList* T, GList L) { + if(T == NULL) { + return ERROR; + } + + if(L == NULL) { + *T = NULL; + } else { + // 新建广义表结点 + *T = (GList) malloc(sizeof(GLNode)); + if(*T == NULL) { + exit(OVERFLOW); + } + + (*T)->tag = L->tag; + + // 复制单原子 + if(L->tag == Atom) { + (*T)->Node.atom = L->Node.atom; + + // 复制表头和表尾 + } else { + CopyGList(&((*T)->Node.ptr.hp), L->Node.ptr.hp); + CopyGList(&((*T)->Node.ptr.tp), L->Node.ptr.tp); + } + } + + return OK; +} + +/* + * 计数 + * + * 返回广义表的长度。 + */ +int GListLength(GList L) { + int count; + + for(count = 0; L != NULL; count++, L = L->Node.ptr.tp) { + } + + return count; +} + +/* + * ████████ 算法5.5 ████████ + * + * 深度 + * + * 返回广义表的深度 + */ +int GListDepth(GList L) { + int max, deep; + GList p; + + // 空表深度为1 + if(L == NULL) { + return 1; + } + + // 原子深度为0 + if(L->tag == Atom) { + return 0; + } + + // 递归求子表深度 + for(max = 0, p = L; p != NULL; p = p->Node.ptr.tp) { + deep = GListDepth(p->Node.ptr.hp); + if(deep > max) { + max = deep; + } + } + + // 非空表的深度是各子元素最大深度加一 + return max + 1; +} + +/* + * 判空 + * + * 判断广义表是否为空。 + */ +Status GListEmpty(GList L) { + return L == NULL ? TRUE : FALSE; +} + +/* + * 表头 + */ +GList GetHead(GList L) { + GList p; + + // 空表无表头,这里不能返回NULL,不然分不清是失败了还是返回了空表 + if(L == NULL) { + exit(ERROR); + } + + CopyGList(&p, L->Node.ptr.hp); + + return p; +} + +/* + * 表尾 + */ +GList GetTail(GList L) { + GList p; + + // 空表无表尾,这里不能返回NULL,不然分不清是失败了还是返回了空表 + if(L == NULL) { + exit(ERROR); + } + + CopyGList(&p, L->Node.ptr.tp); + + return p; +} + +/* + * 插入 + * + * 将元素e插入为广义表L的第一个元素。 + */ +Status InsertFirst(GList* L, GList e) { + GList g; + + if(L == NULL) { + return ERROR; + } + + g = (GList) malloc(sizeof(GLNode)); + if(g == NULL) { + exit(OVERFLOW); + } + + g->tag = List; + g->Node.ptr.hp = e; + g->Node.ptr.tp = *L; + *L = g; + + return OK; +} + +/* + * 删除 + * + * 将广义表L的第一个元素删除,并用e返回。 + */ +Status DeleteFirst(GList* L, GList* e) { + GList p; + + // 空表无法删除 + if(L == NULL || *L == NULL) { + return ERROR; + } + + p = *L; + *L = (*L)->Node.ptr.tp; + + CopyGList(e, p->Node.ptr.hp); + + free(p); + + return OK; +} + +/* + * 遍历 + * + * 用visit函数访问广义表L。 + */ +void Traverse(GList L, void(Visit)(AtomType)) { + + if(L == NULL) { + return; + } + + if(L->tag == Atom) { + Visit(L->Node.atom); + } else { + Traverse(L->Node.ptr.hp, Visit); + Traverse(L->Node.ptr.tp, Visit); + } + +} + +/* + * 图形化输出 + * + * 带括号输出广义表L。 + */ +void PrintGraph(GList L) { + Print(L, Head); + printf("\n"); +} + +/* + * 图形化输出的内部实现,mark是图形化输出标记。 + */ +static void Print(GList L, Mark mark) { + // L为空 + if(L == NULL) { + if(mark == Head) { + printf("("); + } + + printf(")"); + + // L不为空时 + } else { + // 对于原子结点,输出原子 + if(L->tag == Atom) { + printf("%c", L->Node.atom); + + // 对于子表结点,要对表头、表尾分别讨论 + } else { + if(mark == Head) { + printf("("); + } else { + printf(","); + } + + Print(L->Node.ptr.hp, Head); + Print(L->Node.ptr.tp, Tail); + } + } +} + +/* + * ████████ 算法5.8 ████████ + * + * 将非空串str分割成两部分:hsub为第一个','之前的子串,str为第一个','之后的子串。 + * + *【注】 + * 1.这里假设字符串str输入正确,其中无空白符号,且str【已经脱去最外层括号】。 + * 2.分离完成后,str也会发生变化 + */ +static void sever(SString hstr, SString str) { + int i, k, n; + SString ch; + + n = StrLength(str); + + i = 0; // 遍历字符串时的游标 + k = 0; // 标记遇到的未配对括号数量 + + do { + ++i; + + // 截取str第一个字符 + SubString(ch, str, i, 1); + + if(ch[1] == '(') { + ++k; + } + + if(ch[1] == ')') { + --k; + } + } while(i < n && (ch[1] != ',' || k != 0)); + + // 如果存在多个广义表结点 + if(i < n) { + SubString(hstr, str, 1, i - 1); + SubString(str, str, i + 1, n - i); + + // 只有一个广义表结点 + } else { + StrCopy(hstr, str); + ClearString(str); + } +} diff --git a/CLion/ExerciseBook/05.34.1/GList-HT.h b/CLion/ExerciseBook/05.34.1/GList-HT.h new file mode 100644 index 0000000..07c0df2 --- /dev/null +++ b/CLion/ExerciseBook/05.34.1/GList-HT.h @@ -0,0 +1,164 @@ +/*============================ + * 广义表的头尾链表存储表示 + * + * 包含算法: 5.5、5.6、5.7、5.8 + =============================*/ + +#ifndef GLIST_HT_H +#define GLIST_HT_H + +#include +#include // 提供 malloc、realloc、free、exit 原型 +#include "Status.h" //**▲01 绪论**// +#include "SString.h" //**▲04 串**// + +/* 原子元素类型 */ +typedef char AtomType; + +/* + * 广义表结点标记 + * + * Atom-0:原子结点 + * List-1:表结点 + */ +typedef enum { Atom, List } ElemTag; + +/* 广义表(头尾链表存储表示)类型定义 */ +typedef struct GLNode { + ElemTag tag; // 公共标记,用于区分原子结点和表结点 + + // 原子结点和表结点的联合部分 + union { + AtomType atom; // atom是原子结点的值域,AtomType由用户定义 + struct { + struct GLNode* hp; // 指向表头 + struct GLNode* tp; // 指向表尾 + } ptr; // 表结点的指针域 + } Node; +} GLNode; + +/* 广义表类型 */ +typedef GLNode* GList; + +/* + * 图形化输出标记 + * + * Head代表广义表指针来自表头 + * Tail代表广义表指针来自表尾 + */ +typedef enum { Head, Tail } Mark; + + +/* + * 初始化 + * + * 初始化空的广义表,长度为0,深度为1。 + * + *【注】 + * 需要对每一层去掉括号考察 + */ +Status InitGList(GList* L); + +/* + * ████████ 算法5.7 ████████ + * + * 创建 + * + * 由字符串S创建广义表L。 + */ +Status CreateGList(GList* L, SString S); + +/* + * 销毁 + * + * 释放广义表所占内存。 + */ +Status DestroyGList(GList* L); + +/* + * ████████ 算法5.6 ████████ + * + * 复制 + * + * 由广义表L复制得到广义表T。 + */ +Status CopyGList(GList* T, GList L); + +/* + * 计数 + * + * 返回广义表的长度。 + */ +int GListLength(GList L); + +/* + * ████████ 算法5.5 ████████ + * + * 深度 + * + * 返回广义表的深度 + */ +int GListDepth(GList L); + +/* + * 判空 + * + * 判断广义表是否为空。 + */ +Status GListEmpty(GList L); + +/* + * 表头 + */ +GList GetHead(GList L); + +/* + * 表尾 + */ +GList GetTail(GList L); + +/* + * 插入 + * + * 将元素e插入为广义表L的第一个元素。 + */ +Status InsertFirst(GList* L, GList e); + +/* + * 删除 + * + * 将广义表L的第一个元素删除,并用e返回。 + */ +Status DeleteFirst(GList* L, GList* e); + +/* + * 遍历 + * + * 用visit函数访问广义表L。 + */ +void Traverse(GList L, void (Visit)(AtomType)); + +/* + * 图形化输出 + * + * 带括号输出广义表L。 + */ +void PrintGraph(GList L); + +/* + * 图形化输出的内部实现,mark是图形化输出标记。 + */ +static void Print(GList L, Mark mark); + +/* + * ████████ 算法5.8 ████████ + * + * 将非空串str分割成两部分:hsub为第一个','之前的子串,str为第一个','之后的子串。 + * + *【注】 + * 1.这里假设字符串str输入正确,其中无空白符号,且str【已经脱去最外层括号】。 + * 2.分离完成后,str也会发生变化 + */ +static void sever(SString hstr, SString str); + +#endif diff --git a/CLion/ExerciseBook/05.34.1/SString.c b/CLion/ExerciseBook/05.34.1/SString.c new file mode 100644 index 0000000..41d9e15 --- /dev/null +++ b/CLion/ExerciseBook/05.34.1/SString.c @@ -0,0 +1,195 @@ +/*============================= + * 串的定长顺序存储表示(顺序串) + * + * 包含算法: 4.1、4.2、4.3、4.5 + ==============================*/ + +#include "SString.h" //**▲04 串**// + +/* + * 初始化 + * + * 构造一个值为chars的串T。 + * + *【注】 + * 该操作属于最小操作子集 + */ +Status StrAssign(SString T, const char* chars) { + int i, len; + + len = (int) strlen(chars); + + // chars过长 + if(len > MAXSTRLEN) { + return ERROR; + } + + T[0] = len; + for(i = 1; i <= len; i++) { + T[i] = chars[i - 1]; + } + + return OK; +} + +/* + * 清空 + * + * 将串S清空。 + */ +Status ClearString(SString S) { + // 只需要将长度置为0就可以 + S[0] = 0; + return OK; +} + +/* + * 判空 + * + * 判断串S中是否包含有效数据。 + * + * 返回值: + * TRUE : 串S为空 + * FALSE: 串S不为空 + */ +Status StrEmpty(SString S) { + return S[0] == 0 ? TRUE : FALSE; +} + +/* + * 计数 + * + * 返回串S中元素的个数。 + * + *【注】 + * 该操作属于最小操作子集 + */ +int StrLength(SString S) { + return S[0]; +} + +/* + * ████████ 算法4.3 ████████ + * + * 求子串 + * + * 用Sub返回S[pos, pos+len-1]。 + * 返回值指示是否截取成功。 + * + *【注】 + * 该操作属于最小操作子集 + */ +Status SubString(SString Sub, SString S, int pos, int len) { + int i; + + if(pos < 1 || pos > S[0] || len < 0 || pos + len - 1 > S[0]) { + return ERROR; + } + + // 复制元素 + for(i = 1; i <= len; i++) { + Sub[i] = S[pos + i - 1]; + } + + // 确定新长度 + Sub[0] = len; + + return OK; +} + +/* + * 删除 + * + * 删除S[pos, pos+len-1]。 + */ +Status StrDelete(SString S, int pos, int len) { + int i; + + if(pos < 1 || pos + len - 1 > S[0] || len < 0) { + return ERROR; + } + + // 如果待删除的长度为0,则提前返回 + if(len == 0) { + return OK; + } + + // 把后面的元素挪到前面,覆盖掉被删除的元素 + for(i = pos + len; i <= S[0]; i++) { + S[i - len] = S[i]; + } + + // 长度减少 + S[0] -= len; + + return OK; +} + +/* + * 比较 + * + * 比较串S和串T,返回比较结果。 + * + *【注】 + * 该操作属于最小操作子集 + */ +int StrCompare(SString S, SString T) { + int i = 1; + + while(i <= S[0] && i <= T[0]) { + // 遇到不同的字符时,比较其大小 + if(S[i] != T[i]) { + return S[i] - T[i]; + } + + i++; + } + + return S[0] - T[0]; +} + +/* + * 复制 + * + * 将串S复制到串T。 + */ +Status StrCopy(SString T, SString S) { + int i; + + // 连同长度信息一起复制 + for(i = 0; i <= S[0]; i++) { + T[i] = S[i]; + } + + return OK; +} + +/* + * 清理字符串S中的空白,包括清理不可打印字符和清理空格。 + * + *【注】 + * 该函数是在本章中新增的。 + */ +Status ClearBlank(SString S) { + int i, j; + + // 如果是空串 + if(S[0] == 0) { + return ERROR; + } + + for(i = 1, j = 0; i <= S[0]; i++) { + // 如果遇到空白,则略过 + if(S[i] == ' ' || !isprint(S[i])) { + continue; + } + + j++; + + S[j] = S[i]; + } + + S[0] = j; + + return OK; +} diff --git a/CLion/ExerciseBook/05.34.1/SString.h b/CLion/ExerciseBook/05.34.1/SString.h new file mode 100644 index 0000000..e81ca79 --- /dev/null +++ b/CLion/ExerciseBook/05.34.1/SString.h @@ -0,0 +1,117 @@ +/*============================= + * 串的定长顺序存储表示(顺序串) + * + * 包含算法: 4.1、4.2、4.3、4.5 + ==============================*/ + +#ifndef SSTRING_H +#define SSTRING_H + +#include +#include // 提供 strlen 原型 +#include // 提供 isprint 原型 +#include "Status.h" //**▲01 绪论**// + +/* 宏定义 */ +#define MAXSTRLEN 255 // 顺序串的最大串长 + +/* + * 串的顺序存储类型定义 + * + * 注:有效元素从SString的1号单元开始存储 + * SString的0号单元用来存储其长度 + */ +typedef unsigned char SString[MAXSTRLEN + 1]; // 0号单元存放串的长度 + + +/* + * ████ 提示 ████ + * + * 遵循教材的书写习惯,pos指示字符的位序(不是索引),从1开始计数 + */ + + +/* + * 初始化 + * + * 构造一个值为chars的串T。 + * + *【注】 + * 该操作属于最小操作子集 + */ +Status StrAssign(SString T, const char* chars); + +/* + * 清空 + * + * 将串S清空。 + */ +Status ClearString(SString S); + +/* + * 判空 + * + * 判断串S中是否包含有效数据。 + * + * 返回值: + * TRUE : 串S为空 + * FALSE: 串S不为空 + */ +Status StrEmpty(SString S); + +/* + * 计数 + * + * 返回串S中元素的个数。 + * + *【注】 + * 该操作属于最小操作子集 + */ +int StrLength(SString S); + +/* + * ████████ 算法4.3 ████████ + * + * 求子串 + * + * 用Sub返回S[pos, pos+len-1]。 + * 返回值指示是否截取成功。 + * + *【注】 + * 该操作属于最小操作子集 + */ +Status SubString(SString Sub, SString S, int pos, int len); + +/* + * 删除 + * + * 删除S[pos, pos+len-1]。 + */ +Status StrDelete(SString S, int pos, int len); + +/* + * 比较 + * + * 比较串S和串T,返回比较结果。 + * + *【注】 + * 该操作属于最小操作子集 + */ +int StrCompare(SString S, SString T); + +/* + * 复制 + * + * 将串S复制到串T。 + */ +Status StrCopy(SString T, SString S); + +/* + * 清理字符串S中的空白,包括清理不可打印字符和清理空格。 + * + *【注】 + * 该函数是在本章中新增的。 + */ +Status ClearBlank(SString S); + +#endif diff --git a/CLion/ExerciseBook/05.34.2/05.34.2.c b/CLion/ExerciseBook/05.34.2/05.34.2.c new file mode 100644 index 0000000..0dfdf8e --- /dev/null +++ b/CLion/ExerciseBook/05.34.2/05.34.2.c @@ -0,0 +1,61 @@ +#include +#include "Status.h" //**▲01 绪论**// +#include "SString.h" //**▲04 串**// +#include "GList-E.h" //**▲05 数组和广义表**// + +/* + * 逆置广义表(扩展线性链表存储表示) + */ +Status Algo_5_34_2(GList* L); + + +int main(int argc, char* argv[]) { + GList L; + char* s = "(a,((b,c),()),(((d),e),f))"; + SString S; + + printf("创建广义表 L ...\n"); + StrAssign(S, s); + CreateGList(&L, S); + printf("L = "); + PrintGraph(L); + + printf("逆置广义表...\n"); + Algo_5_34_2(&L); + printf("L = "); + PrintGraph(L); + + return 0; +} + + +/* + * 逆置广义表(扩展线性链表存储表示) + */ +Status Algo_5_34_2(GList* L) { + GList head, tail; + + if(L == NULL || *L == NULL) { + return ERROR; + } + + // 从后向前,从里到外逆置 + head = *L; + tail = (*L)->tp; + + if(head->tag == List && head->Node.hp != NULL) { + Algo_5_34_2(&(head->Node.hp)); + } + + // 对表尾进行逆置 + if(tail != NULL) { + Algo_5_34_2(&((*L)->tp)); + + // 头尾交换 + *L = (*L)->tp; + tail->tp = head; + head->tp = NULL; + } + + return OK; +} diff --git a/CLion/ExerciseBook/05.34.2/CMakeLists.txt b/CLion/ExerciseBook/05.34.2/CMakeLists.txt new file mode 100644 index 0000000..0b78e90 --- /dev/null +++ b/CLion/ExerciseBook/05.34.2/CMakeLists.txt @@ -0,0 +1,7 @@ +# 包含公共库 +include_directories(${CMAKE_SOURCE_DIR}/Status) + +# 生成可执行文件 +add_executable(05.34.2 SString.h SString.c GList-E.h GList-E.c 05.34.2.c) +# 链接公共库 +target_link_libraries(05.34.2 Scanf_lib) \ No newline at end of file diff --git a/CLion/ExerciseBook/05.34.2/GList-E.c b/CLion/ExerciseBook/05.34.2/GList-E.c new file mode 100644 index 0000000..d994024 --- /dev/null +++ b/CLion/ExerciseBook/05.34.2/GList-E.c @@ -0,0 +1,449 @@ +/*=========================== + * 广义表的扩展线性链表存储表示 + ============================*/ + +#include "GList-E.h" //**▲05 数组和广义表**// + +/* + * 初始化 + * + * 初始化空的广义表,长度为0,深度为1。 + * + *【注】 + * 需要对每一层带上括号考察 + */ +Status InitGList(GList* L) { + if(L == NULL) { + return ERROR; + } + + *L = (GList) malloc(sizeof(GLNode)); + if(!*L) { + exit(OVERFLOW); + } + + (*L)->tag = List; + (*L)->Node.hp = NULL; + (*L)->tp = NULL; + + return OK; +} + +/* + * 创建 + * + * 由字符串S创建广义表L。 + */ +Status CreateGList(GList* L, SString S) { + SString emp, hsub, sub, tmp; + + if(L == NULL) { + return ERROR; + } + + // 清理字符串S中的空白,包括清理不可打印字符和清理空格 + ClearBlank(S); + + if(StrEmpty(S)) { + return ERROR; + } + + // 复制是为了不破坏S + StrCopy(sub, S); + + /* + * 初次执行到此时,带着最外层的括号 + * 再次执行到此时,已经脱去了外层括号 + */ + sever(hsub, sub); + + *L = (GList) malloc(sizeof(GLNode)); + if(*L == NULL) { + exit(OVERFLOW); + } + + StrAssign(emp, "()"); + + if(!StrCompare(hsub, emp)) { + (*L)->tag = List; + (*L)->Node.hp = NULL; + } else { + if(StrLength(hsub) == 1) { + (*L)->tag = Atom; + (*L)->Node.atom = hsub[1]; + } else { + (*L)->tag = List; + + SubString(tmp, hsub, 2, StrLength(hsub) - 2); + + CreateGList(&((*L)->Node.hp), tmp); + } + } + + // 如果不存在队尾,则退出本层递归 + if(StrEmpty(sub)) { + (*L)->tp = NULL; + } else { + // 继续递归求表尾 + CreateGList(&((*L)->tp), sub); + } + + return OK; +} + +/* + * 销毁 + * + * 释放广义表所占内存。 + */ +Status DestroyGList(GList* L) { + GList head, tail; + + if(L == NULL || *L == NULL) { + return ERROR; + } + + // 处理子表结点 + if((*L)->tag == List) { + head = (*L)->Node.hp; // 表头 + tail = (*L)->tp; // 表尾 + + free(*L); + *L = NULL; + + // 递归处理表头 + if(head != NULL) { + DestroyGList(&head); + } + + // 递归处理表尾 + if(tail != NULL) { + DestroyGList(&tail); + } + + // 处理原子结点 + } else { + tail = (*L)->tp; // 表尾 + + free(*L); + *L = NULL; + + if(tail != NULL) { + DestroyGList(&tail); + } + } + + return OK; +} + +/* + * 复制 + * + * 由广义表L复制得到广义表T。 + */ +Status CopyGList(GList* T, GList L) { + + if(L == NULL) { + return ERROR; + } + + *T = (GList) malloc(sizeof(GLNode)); + if(*T == NULL) { + exit(OVERFLOW); + } + + // 复制原子 + if(L->tag == Atom) { + (*T)->tag = Atom; + (*T)->Node.atom = L->Node.atom; + + // 复制子表 + } else { + (*T)->tag = List; + + // 复制表头 + if(L->Node.hp != NULL) { + CopyGList(&((*T)->Node.hp), L->Node.hp); + } else { + (*T)->Node.hp = NULL; + } + } + + // 复制表尾 + if(L->tp != NULL) { + CopyGList(&((*T)->tp), L->tp); + } else { + (*T)->tp = NULL; + } + + return OK; +} + +/* + * 计数 + * + * 返回广义表的长度。 + */ +int GListLength(GList L) { + int count = 0; + GList p; + + // 广义表不存在 + if(L == NULL) { + return -1; + } + + p = L->Node.hp; + + while(p != NULL) { + ++count; + p = p->tp; + } + + return count; +} + +/* + * 深度 + * + * 返回广义表的深度 + */ +int GListDepth(GList L) { + int max, deep; + GList p; + + max = 0; + + // 广义表不存在 + if(L == NULL) { + return -1; + } + + // 空表深度为1 + if(L->tag == List && !L->Node.hp) { + return 1; + } + + // 原子深度为0 + if(L->tag == Atom) { + return 0; + } + + // 递归求子表深度 + for(p = L->Node.hp; p != NULL; p = p->tp) { + // 求以p为头指针的子表深度 + deep = GListDepth(p); + if(deep > max) { + max = deep; + } + } + + return max + 1; +} + +/* + * 判空 + * + * 判断广义表是否为空。 + */ +Status GListEmpty(GList L) { + // 广义表不存在 + if(L == NULL) { + return ERROR; + } + + if(L->tag == List && L->Node.hp == NULL && L->tp == NULL) { + return TRUE; + } else { + return ERROR; + } +} + +/* + * 表头 + */ +GList GetHead(GList L) { + GList p, q; + + // 广义表不存在或广义表为空表,无法获取表头 + if(L == NULL || L->Node.hp == NULL) { + return NULL; + } + + q = L->Node.hp->tp; // 临时保存L的表尾信息 + L->Node.hp->tp = NULL; // 截去L的表尾部分 + + CopyGList(&p, L->Node.hp); // 复制表头信息(已屏蔽表尾) + + L->Node.hp->tp = q; // 恢复L的表尾信息 + + return p; +} + +/* + * 表尾 + */ +GList GetTail(GList L) { + GList p, q; + + // 广义表不存在或广义表为空表,无法获取表尾 + if(L == NULL || L->Node.hp == NULL) { + return NULL; + } + + q = L->Node.hp; // 临时保存L的表头信息 + L->Node.hp = q->tp; // 摘下L的表头部分 + + CopyGList(&p, L); // 复制表尾信息(已屏蔽表头) + + q->tp = L->Node.hp; // 恢复L的表头信息 + L->Node.hp = q; + + return p; +} + +/* + * 插入 + * + * 将元素e插入为广义表L的第一个元素。 + */ +Status InsertFirst(GList* L, GList e) { + + // 广义表不存在 + if(L == NULL || *L == NULL) { + return ERROR; + } + + if(e == NULL) { + return ERROR; + } + + e->tp = (*L)->Node.hp; + (*L)->Node.hp = e; + + return OK; +} + +/* + * 删除 + * + * 将广义表L的第一个元素删除,并用e返回。 + */ +Status DeleteFirst(GList* L, GList* e) { + GList p; + + // 广义表不存在或广义表为空表,则无法删除表头 + if(*L == NULL || (*L)->Node.hp == NULL) { + return ERROR; + } + + p = (*L)->Node.hp; + (*L)->Node.hp = p->tp; + p->tp = NULL; + + *e = p; + + return OK; +} + +/* + * 遍历 + * + * 用visit函数访问广义表L。 + */ +void Traverse(GList L, void(Visit)(AtomType)) { + if(L == NULL) { + return; + } + + if(L->tag == List) { + Traverse(L->Node.hp, Visit); + } else { + Visit(L->Node.atom); + } + + Traverse(L->tp, Visit); +} + +/* + * 图形化输出 + * + * 带括号输出广义表L。 + */ +void PrintGraph(GList L) { + Print(L); + printf("\n"); +} + +/* + * 图形化输出的内部实现。 + */ +static void Print(GList L) { + if(L == NULL) { + return; + } + + // 处理表结点 + if(L->tag == List) { + printf("("); + + if(L->Node.hp) { + Print(L->Node.hp); + } + + if(L->tp) { + printf("),"); + Print(L->tp); + } else { + printf(")"); + } + + // 处理原子结点 + } else { + printf("%c", L->Node.atom); + if(L->tp) { + printf(","); + Print(L->tp); + } + } +} + +/* + * 将非空串str分割成两部分:hsub为第一个','之前的子串,str为第一个','之后的子串。 + * + *【注】 + * 1.这里假设字符串str输入正确,其中无空白符号, + * 但str外层的括号可能脱去,也可能未脱去。 + * 2.分离完成后,str也会发生变化 + */ +static void sever(SString hstr, SString str) { + int i, k, n; + SString ch; + + n = StrLength(str); + + i = 0; // 遍历字符串时的游标 + k = 0; // 标记遇到的未配对括号数量 + + do { + ++i; + + // 截取str第一个字符 + SubString(ch, str, i, 1); + + if(ch[1] == '(') { + ++k; + } + if(ch[1] == ')') { + --k; + } + } while(i < n && (ch[1] != ',' || k != 0)); + + if(i < n) { + SubString(hstr, str, 1, i - 1); + SubString(str, str, i + 1, n - i); + } else { + StrCopy(hstr, str); + ClearString(str); + } +} diff --git a/CLion/ExerciseBook/05.34.2/GList-E.h b/CLion/ExerciseBook/05.34.2/GList-E.h new file mode 100644 index 0000000..5e5b625 --- /dev/null +++ b/CLion/ExerciseBook/05.34.2/GList-E.h @@ -0,0 +1,146 @@ +/*=========================== + * 广义表的扩展线性链表存储表示 + ============================*/ + +#ifndef GLIST_E_H +#define GLIST_E_H + +#include +#include // 提供 malloc、realloc、free、exit 原型 +#include "Status.h" //**▲01 绪论**// +#include "SString.h" //**▲04 串**// + +/* 原子元素类型 */ +typedef char AtomType; //原子类型 + +/* + * 广义表结点标记 + * + * Atom-0:原子结点 + * List-1:表结点 + */ +typedef enum { Atom, List } ElemTag; + +/* 广义表(扩展线性链表存储表示)类型定义 */ +typedef struct GLNode { + ElemTag tag; // 公共标记,用于区分原子结点和表结点 + + // 原子结点和表结点的联合部分 + union + { + AtomType atom; // atom是原子结点的值域,AtomType由用户定义 + struct GLNode* hp; // 指向表头 + } Node; + struct GLNode* tp; // 指向表尾 +} GLNode; + +/* 广义表类型 */ +typedef GLNode* GList; + + +/* + * 初始化 + * + * 初始化空的广义表,长度为0,深度为1。 + * + *【注】 + * 需要对每一层带上括号考察 + */ +Status InitGList(GList* L); + +/* + * 创建 + * + * 由字符串S创建广义表L。 + */ +Status CreateGList(GList* L, SString S); + +/* + * 销毁 + * + * 释放广义表所占内存。 + */ +Status DestroyGList(GList* L); + +/* + * 复制 + * + * 由广义表L复制得到广义表T。 + */ +Status CopyGList(GList* T, GList L); + +/* + * 计数 + * + * 返回广义表的长度。 + */ +int GListLength(GList L); + +/* + * 深度 + * + * 返回广义表的深度 + */ +int GListDepth(GList L); + +/* + * 判空 + * + * 判断广义表是否为空。 + */ +Status GListEmpty(GList L); + +/* + * 表头 + */ +GList GetHead(GList L); + +/* + * 表尾 + */ +GList GetTail(GList L); + +/* + * 插入 + * + * 将元素e插入为广义表L的第一个元素。 + */ +Status InsertFirst(GList* L, GList e); + +/* + * 删除 + * + * 将广义表L的第一个元素删除,并用e返回。 + */ +Status DeleteFirst(GList* L, GList* e); + +/* + * 遍历 + * + * 用visit函数访问广义表L。 + */ +void Traverse(GList L, void(Visit)(AtomType)); + +/* + * 图形化输出 + * + * 带括号输出广义表L。 + */ +void PrintGraph(GList L); + +/* + * 图形化输出的内部实现。 + */ +static void Print(GList L); + +/* + * 将非空串str分割成两部分:hsub为第一个','之前的子串,str为第一个','之后的子串。 + * + *【注】 + * 1.这里假设字符串str输入正确,其中无空白符号, + * 但str外层的括号可能脱去,也可能未脱去。 + * 2.分离完成后,str也会发生变化 + */ +static void sever(SString hstr, SString str); + +#endif diff --git a/CLion/ExerciseBook/05.34.2/SString.c b/CLion/ExerciseBook/05.34.2/SString.c new file mode 100644 index 0000000..41d9e15 --- /dev/null +++ b/CLion/ExerciseBook/05.34.2/SString.c @@ -0,0 +1,195 @@ +/*============================= + * 串的定长顺序存储表示(顺序串) + * + * 包含算法: 4.1、4.2、4.3、4.5 + ==============================*/ + +#include "SString.h" //**▲04 串**// + +/* + * 初始化 + * + * 构造一个值为chars的串T。 + * + *【注】 + * 该操作属于最小操作子集 + */ +Status StrAssign(SString T, const char* chars) { + int i, len; + + len = (int) strlen(chars); + + // chars过长 + if(len > MAXSTRLEN) { + return ERROR; + } + + T[0] = len; + for(i = 1; i <= len; i++) { + T[i] = chars[i - 1]; + } + + return OK; +} + +/* + * 清空 + * + * 将串S清空。 + */ +Status ClearString(SString S) { + // 只需要将长度置为0就可以 + S[0] = 0; + return OK; +} + +/* + * 判空 + * + * 判断串S中是否包含有效数据。 + * + * 返回值: + * TRUE : 串S为空 + * FALSE: 串S不为空 + */ +Status StrEmpty(SString S) { + return S[0] == 0 ? TRUE : FALSE; +} + +/* + * 计数 + * + * 返回串S中元素的个数。 + * + *【注】 + * 该操作属于最小操作子集 + */ +int StrLength(SString S) { + return S[0]; +} + +/* + * ████████ 算法4.3 ████████ + * + * 求子串 + * + * 用Sub返回S[pos, pos+len-1]。 + * 返回值指示是否截取成功。 + * + *【注】 + * 该操作属于最小操作子集 + */ +Status SubString(SString Sub, SString S, int pos, int len) { + int i; + + if(pos < 1 || pos > S[0] || len < 0 || pos + len - 1 > S[0]) { + return ERROR; + } + + // 复制元素 + for(i = 1; i <= len; i++) { + Sub[i] = S[pos + i - 1]; + } + + // 确定新长度 + Sub[0] = len; + + return OK; +} + +/* + * 删除 + * + * 删除S[pos, pos+len-1]。 + */ +Status StrDelete(SString S, int pos, int len) { + int i; + + if(pos < 1 || pos + len - 1 > S[0] || len < 0) { + return ERROR; + } + + // 如果待删除的长度为0,则提前返回 + if(len == 0) { + return OK; + } + + // 把后面的元素挪到前面,覆盖掉被删除的元素 + for(i = pos + len; i <= S[0]; i++) { + S[i - len] = S[i]; + } + + // 长度减少 + S[0] -= len; + + return OK; +} + +/* + * 比较 + * + * 比较串S和串T,返回比较结果。 + * + *【注】 + * 该操作属于最小操作子集 + */ +int StrCompare(SString S, SString T) { + int i = 1; + + while(i <= S[0] && i <= T[0]) { + // 遇到不同的字符时,比较其大小 + if(S[i] != T[i]) { + return S[i] - T[i]; + } + + i++; + } + + return S[0] - T[0]; +} + +/* + * 复制 + * + * 将串S复制到串T。 + */ +Status StrCopy(SString T, SString S) { + int i; + + // 连同长度信息一起复制 + for(i = 0; i <= S[0]; i++) { + T[i] = S[i]; + } + + return OK; +} + +/* + * 清理字符串S中的空白,包括清理不可打印字符和清理空格。 + * + *【注】 + * 该函数是在本章中新增的。 + */ +Status ClearBlank(SString S) { + int i, j; + + // 如果是空串 + if(S[0] == 0) { + return ERROR; + } + + for(i = 1, j = 0; i <= S[0]; i++) { + // 如果遇到空白,则略过 + if(S[i] == ' ' || !isprint(S[i])) { + continue; + } + + j++; + + S[j] = S[i]; + } + + S[0] = j; + + return OK; +} diff --git a/CLion/ExerciseBook/05.34.2/SString.h b/CLion/ExerciseBook/05.34.2/SString.h new file mode 100644 index 0000000..e81ca79 --- /dev/null +++ b/CLion/ExerciseBook/05.34.2/SString.h @@ -0,0 +1,117 @@ +/*============================= + * 串的定长顺序存储表示(顺序串) + * + * 包含算法: 4.1、4.2、4.3、4.5 + ==============================*/ + +#ifndef SSTRING_H +#define SSTRING_H + +#include +#include // 提供 strlen 原型 +#include // 提供 isprint 原型 +#include "Status.h" //**▲01 绪论**// + +/* 宏定义 */ +#define MAXSTRLEN 255 // 顺序串的最大串长 + +/* + * 串的顺序存储类型定义 + * + * 注:有效元素从SString的1号单元开始存储 + * SString的0号单元用来存储其长度 + */ +typedef unsigned char SString[MAXSTRLEN + 1]; // 0号单元存放串的长度 + + +/* + * ████ 提示 ████ + * + * 遵循教材的书写习惯,pos指示字符的位序(不是索引),从1开始计数 + */ + + +/* + * 初始化 + * + * 构造一个值为chars的串T。 + * + *【注】 + * 该操作属于最小操作子集 + */ +Status StrAssign(SString T, const char* chars); + +/* + * 清空 + * + * 将串S清空。 + */ +Status ClearString(SString S); + +/* + * 判空 + * + * 判断串S中是否包含有效数据。 + * + * 返回值: + * TRUE : 串S为空 + * FALSE: 串S不为空 + */ +Status StrEmpty(SString S); + +/* + * 计数 + * + * 返回串S中元素的个数。 + * + *【注】 + * 该操作属于最小操作子集 + */ +int StrLength(SString S); + +/* + * ████████ 算法4.3 ████████ + * + * 求子串 + * + * 用Sub返回S[pos, pos+len-1]。 + * 返回值指示是否截取成功。 + * + *【注】 + * 该操作属于最小操作子集 + */ +Status SubString(SString Sub, SString S, int pos, int len); + +/* + * 删除 + * + * 删除S[pos, pos+len-1]。 + */ +Status StrDelete(SString S, int pos, int len); + +/* + * 比较 + * + * 比较串S和串T,返回比较结果。 + * + *【注】 + * 该操作属于最小操作子集 + */ +int StrCompare(SString S, SString T); + +/* + * 复制 + * + * 将串S复制到串T。 + */ +Status StrCopy(SString T, SString S); + +/* + * 清理字符串S中的空白,包括清理不可打印字符和清理空格。 + * + *【注】 + * 该函数是在本章中新增的。 + */ +Status ClearBlank(SString S); + +#endif diff --git a/CLion/ExerciseBook/05.35-05.36/05.35-05.36.c b/CLion/ExerciseBook/05.35-05.36/05.35-05.36.c new file mode 100644 index 0000000..313ba72 --- /dev/null +++ b/CLion/ExerciseBook/05.35-05.36/05.35-05.36.c @@ -0,0 +1,45 @@ +#include +#include "Status.h" //**▲01 绪论**// +#include "SString.h" //**▲04 串**// +#include "GList.h" //**▲05 数组和广义表**// + +/* + * 创建广义表L,这里将"( )"定义为广义表为空的状态。 + */ +Status Algo_5_35(GList* L, SString S); + +/* + * 带括号输出广义表L,这里将"( )"定义为广义表为空的状态。 + */ +void Algo_5_36(GList L); + + +int main(int argc, char* argv[]) { + GList L; + char* s = "(( ),(e),(a,(b,c,d)))"; + SString S; + + printf("创建广义表 L ...\n"); + StrAssign(S, s); + Algo_5_35(&L, S); + + printf("L = "); + Algo_5_36(L); + + return 0; +} + + +/* + * 创建广义表L,这里将"( )"定义为广义表为空的状态。 + */ +Status Algo_5_35(GList* L, SString S) { + return CreateGList(L, S); +} + +/* + * 带括号输出广义表L,这里将"( )"定义为广义表为空的状态。 + */ +void Algo_5_36(GList L) { + PrintGraph(L); +} diff --git a/CLion/ExerciseBook/05.35-05.36/CMakeLists.txt b/CLion/ExerciseBook/05.35-05.36/CMakeLists.txt new file mode 100644 index 0000000..2667f03 --- /dev/null +++ b/CLion/ExerciseBook/05.35-05.36/CMakeLists.txt @@ -0,0 +1,7 @@ +# 包含公共库 +include_directories(${CMAKE_SOURCE_DIR}/Status) + +# 生成可执行文件 +add_executable(05.35-05.36 SString.h SString.c GList.h GList.c 05.35-05.36.c) +# 链接公共库 +target_link_libraries(05.35-05.36 Scanf_lib) \ No newline at end of file diff --git a/CLion/ExerciseBook/05.35-05.36/GList.c b/CLion/ExerciseBook/05.35-05.36/GList.c new file mode 100644 index 0000000..967762f --- /dev/null +++ b/CLion/ExerciseBook/05.35-05.36/GList.c @@ -0,0 +1,179 @@ +/*============================ + * 广义表的头尾链表存储表示 + =============================*/ + +#include "GList.h" + +/* + * 创建 + * + * 由字符串S创建广义表L。 + * + *【注】 + * 这里将"( )"定义为广义表为空的状态。 + */ +Status CreateGList(GList* L, SString S) { + SString emp; // 代表空广义表的字符串 + SString hsub, sub; + GList p, q; + + if(L == NULL) { + return ERROR; + } + + // 清理字符串S中的空白,包括清理不可打印字符和清理空格 + ClearBlank(S); + + if(StrEmpty(S)) { + return ERROR; + } + + StrAssign(emp, "( )"); + + /* + * 如果输入串为(),则代表需要创建空的广义表 + * + *【注】 + * 教材这里的代码是有问题的。 + * StrCompare的返回值指示的是两个字符串的大小,而不是指示两个字符串是否相等。 + * 如果给定的S与()相等,返回值应当是0。 + */ + if(!StrCompare(S, emp)) { + *L = NULL; + } else { + *L = (GList) malloc(sizeof(GLNode)); + if(*L == NULL) { + exit(OVERFLOW); + } + + // 创建原子 + if(StrLength(S) == 1) { + (*L)->tag = Atom; + (*L)->Node.atom = S[1]; + } else { + (*L)->tag = List; + + p = *L; + + // 去掉最外层括号 + SubString(sub, S, 2, StrLength(S) - 2); + + // 重复建n个子表 + do { + // 从sub中分离出表头串hsub,分离完成后,sub也会发生变化 + sever(hsub, sub); + + // 递归创建广义表 + CreateGList(&(p->Node.ptr.hp), hsub); + + q = p; + + // 如果表尾不为空,需要继续处理表尾 + if(!StrEmpty(sub)) { + p = (GList) malloc(sizeof(GLNode)); + if(p == NULL) { + exit(OVERFLOW); + } + + p->tag = List; + + q->Node.ptr.tp = p; + } + } while(!StrEmpty(sub)); + + q->Node.ptr.tp = NULL; + } + } + + return OK; +} + +/* + * 图形化输出 + * + * 带括号输出广义表L。 + * + *【注】 + * 这里将"( )"定义为广义表为空的状态。 + */ +void PrintGraph(GList L) { + Print(L, Head); + printf("\n"); +} + +/* + * 图形化输出的内部实现,mark是图形化输出标记。 + */ +static void Print(GList L, Mark mark) { + // L为空 + if(L == NULL) { + if(mark == Head) { + printf("( "); + } + + printf(")"); + + // L不为空时 + } else { + // 对于原子结点,输出原子 + if(L->tag == Atom) { + printf("%c", L->Node.atom); + + // 对于子表结点,要对表头、表尾分别讨论 + } else { + if(mark == Head) { + printf("("); + } else { + printf(","); + } + + Print(L->Node.ptr.hp, Head); + Print(L->Node.ptr.tp, Tail); + } + } +} + +/* + * ████████ 算法5.8 ████████ + * + * 将非空串str分割成两部分:hsub为第一个','之前的子串,str为第一个','之后的子串。 + * + *【注】 + * 1.这里假设字符串str输入正确,其中无空白符号,且str【已经脱去最外层括号】。 + * 2.分离完成后,str也会发生变化 + */ +static void sever(SString hstr, SString str) { + int i, k, n; + SString ch; + + n = StrLength(str); + + i = 0; // 遍历字符串时的游标 + k = 0; // 标记遇到的未配对括号数量 + + do { + ++i; + + // 截取str第一个字符 + SubString(ch, str, i, 1); + + if(ch[1] == '(') { + ++k; + } + + if(ch[1] == ')') { + --k; + } + } while(i < n && (ch[1] != ',' || k != 0)); + + // 如果存在多个广义表结点 + if(i < n) { + SubString(hstr, str, 1, i - 1); + SubString(str, str, i + 1, n - i); + + // 只有一个广义表结点 + } else { + StrCopy(hstr, str); + ClearString(str); + } +} diff --git a/CLion/ExerciseBook/05.35-05.36/GList.h b/CLion/ExerciseBook/05.35-05.36/GList.h new file mode 100644 index 0000000..68e960a --- /dev/null +++ b/CLion/ExerciseBook/05.35-05.36/GList.h @@ -0,0 +1,82 @@ +/*============================ + * 广义表的头尾链表存储表示 + =============================*/ + +#ifndef GLIST_H +#define GLIST_H + +#include +#include // 提供 malloc、realloc、free、exit 原型 +#include "Status.h" //**▲01 绪论**// +#include "SString.h" //**▲04 串**// + +/* 原子元素类型 */ +typedef char AtomType; + +/* + * 广义表结点标记 + * + * Atom-0:原子结点 + * List-1:表结点 + */ +typedef enum { Atom, List } ElemTag; + +/* 广义表(头尾链表存储表示)类型定义 */ +typedef struct GLNode { + ElemTag tag; // 公共标记,用于区分原子结点和表结点 + + // 原子结点和表结点的联合部分 + union { + AtomType atom; // atom是原子结点的值域,AtomType由用户定义 + struct { + struct GLNode* hp; // 指向表头 + struct GLNode* tp; // 指向表尾 + } ptr; // 表结点的指针域 + } Node; +} GLNode; + +/* 广义表类型 */ +typedef GLNode* GList; + +/* + * 图形化输出标记 + * + * Head代表广义表指针来自表头 + * Tail代表广义表指针来自表尾 + */ +typedef enum { Head, Tail } Mark; + + +/* + * ████████ 算法5.7 ████████ + * + * 创建 + * + * 由字符串S创建广义表L。 + */ +Status CreateGList(GList* L, SString S); + +/* + * 图形化输出 + * + * 带括号输出广义表L。 + */ +void PrintGraph(GList L); + +/* + * 图形化输出的内部实现,mark是图形化输出标记。 + */ +static void Print(GList L, Mark mark); + +/* + * ████████ 算法5.8 ████████ + * + * 将非空串str分割成两部分:hsub为第一个','之前的子串,str为第一个','之后的子串。 + * + *【注】 + * 1.这里假设字符串str输入正确,其中无空白符号,且str【已经脱去最外层括号】。 + * 2.分离完成后,str也会发生变化 + */ +static void sever(SString hstr, SString str); + +#endif diff --git a/CLion/ExerciseBook/05.35-05.36/SString.c b/CLion/ExerciseBook/05.35-05.36/SString.c new file mode 100644 index 0000000..35e5267 --- /dev/null +++ b/CLion/ExerciseBook/05.35-05.36/SString.c @@ -0,0 +1,195 @@ +/*============================= + * 串的定长顺序存储表示(顺序串) + * + * 包含算法: 4.1、4.2、4.3、4.5 + ==============================*/ + +#include "SString.h" //**▲04 串**// + +/* + * 初始化 + * + * 构造一个值为chars的串T。 + * + *【注】 + * 该操作属于最小操作子集 + */ +Status StrAssign(SString T, const char* chars) { + int i, len; + + len = (int) strlen(chars); + + // chars过长 + if(len > MAXSTRLEN) { + return ERROR; + } + + T[0] = len; + for(i = 1; i <= len; i++) { + T[i] = chars[i - 1]; + } + + return OK; +} + +/* + * 清空 + * + * 将串S清空。 + */ +Status ClearString(SString S) { + // 只需要将长度置为0就可以 + S[0] = 0; + return OK; +} + +/* + * 判空 + * + * 判断串S中是否包含有效数据。 + * + * 返回值: + * TRUE : 串S为空 + * FALSE: 串S不为空 + */ +Status StrEmpty(SString S) { + return S[0] == 0 ? TRUE : FALSE; +} + +/* + * 计数 + * + * 返回串S中元素的个数。 + * + *【注】 + * 该操作属于最小操作子集 + */ +int StrLength(SString S) { + return S[0]; +} + +/* + * ████████ 算法4.3 ████████ + * + * 求子串 + * + * 用Sub返回S[pos, pos+len-1]。 + * 返回值指示是否截取成功。 + * + *【注】 + * 该操作属于最小操作子集 + */ +Status SubString(SString Sub, SString S, int pos, int len) { + int i; + + if(pos < 1 || pos > S[0] || len < 0 || pos + len - 1 > S[0]) { + return ERROR; + } + + // 复制元素 + for(i = 1; i <= len; i++) { + Sub[i] = S[pos + i - 1]; + } + + // 确定新长度 + Sub[0] = len; + + return OK; +} + +/* + * 删除 + * + * 删除S[pos, pos+len-1]。 + */ +Status StrDelete(SString S, int pos, int len) { + int i; + + if(pos < 1 || pos + len - 1 > S[0] || len < 0) { + return ERROR; + } + + // 如果待删除的长度为0,则提前返回 + if(len == 0) { + return OK; + } + + // 把后面的元素挪到前面,覆盖掉被删除的元素 + for(i = pos + len; i <= S[0]; i++) { + S[i - len] = S[i]; + } + + // 长度减少 + S[0] -= len; + + return OK; +} + +/* + * 比较 + * + * 比较串S和串T,返回比较结果。 + * + *【注】 + * 该操作属于最小操作子集 + */ +int StrCompare(SString S, SString T) { + int i = 1; + + while(i <= S[0] && i <= T[0]) { + // 遇到不同的字符时,比较其大小 + if(S[i] != T[i]) { + return S[i] - T[i]; + } + + i++; + } + + return S[0] - T[0]; +} + +/* + * 复制 + * + * 将串S复制到串T。 + */ +Status StrCopy(SString T, SString S) { + int i; + + // 连同长度信息一起复制 + for(i = 0; i <= S[0]; i++) { + T[i] = S[i]; + } + + return OK; +} + +/* + * 清理字符串S中的不可打印字符,【不清理】空格 + * + *【注】 + * 该函数是在本章中新增的。 + */ +Status ClearBlank(SString S) { + int i, j; + + // 如果是空串 + if(S[0] == 0) { + return ERROR; + } + + for(i = 1, j = 0; i <= S[0]; i++) { + // 如果遇到空白,则略过 + if(!isprint(S[i])) { + continue; + } + + j++; + + S[j] = S[i]; + } + + S[0] = j; + + return OK; +} diff --git a/CLion/ExerciseBook/05.35-05.36/SString.h b/CLion/ExerciseBook/05.35-05.36/SString.h new file mode 100644 index 0000000..629be89 --- /dev/null +++ b/CLion/ExerciseBook/05.35-05.36/SString.h @@ -0,0 +1,117 @@ +/*============================= + * 串的定长顺序存储表示(顺序串) + * + * 包含算法: 4.1、4.2、4.3、4.5 + ==============================*/ + +#ifndef SSTRING_H +#define SSTRING_H + +#include +#include // 提供 strlen 原型 +#include // 提供 isprint 原型 +#include "Status.h" //**▲01 绪论**// + +/* 宏定义 */ +#define MAXSTRLEN 255 // 顺序串的最大串长 + +/* + * 串的顺序存储类型定义 + * + * 注:有效元素从SString的1号单元开始存储 + * SString的0号单元用来存储其长度 + */ +typedef unsigned char SString[MAXSTRLEN + 1]; // 0号单元存放串的长度 + + +/* + * ████ 提示 ████ + * + * 遵循教材的书写习惯,pos指示字符的位序(不是索引),从1开始计数 + */ + + +/* + * 初始化 + * + * 构造一个值为chars的串T。 + * + *【注】 + * 该操作属于最小操作子集 + */ +Status StrAssign(SString T, const char* chars); + +/* + * 清空 + * + * 将串S清空。 + */ +Status ClearString(SString S); + +/* + * 判空 + * + * 判断串S中是否包含有效数据。 + * + * 返回值: + * TRUE : 串S为空 + * FALSE: 串S不为空 + */ +Status StrEmpty(SString S); + +/* + * 计数 + * + * 返回串S中元素的个数。 + * + *【注】 + * 该操作属于最小操作子集 + */ +int StrLength(SString S); + +/* + * ████████ 算法4.3 ████████ + * + * 求子串 + * + * 用Sub返回S[pos, pos+len-1]。 + * 返回值指示是否截取成功。 + * + *【注】 + * 该操作属于最小操作子集 + */ +Status SubString(SString Sub, SString S, int pos, int len); + +/* + * 删除 + * + * 删除S[pos, pos+len-1]。 + */ +Status StrDelete(SString S, int pos, int len); + +/* + * 比较 + * + * 比较串S和串T,返回比较结果。 + * + *【注】 + * 该操作属于最小操作子集 + */ +int StrCompare(SString S, SString T); + +/* + * 复制 + * + * 将串S复制到串T。 + */ +Status StrCopy(SString T, SString S); + +/* + * 清理字符串S中的不可打印字符,【不清理】空格 + * + *【注】 + * 该函数是在本章中新增的。 + */ +Status ClearBlank(SString S); + +#endif diff --git a/CLion/ExerciseBook/05.37.1/05.37.1.c b/CLion/ExerciseBook/05.37.1/05.37.1.c new file mode 100644 index 0000000..e1a14d1 --- /dev/null +++ b/CLion/ExerciseBook/05.37.1/05.37.1.c @@ -0,0 +1,63 @@ +#include +#include "SString.h" //**▲04 串**// +#include "GList-HT.h" //**▲05 数组和广义表**// + +/* + * 删除广义表中值为x的原子项(头尾链表存储表示) + */ +void Algo_5_37_1(GList* L, AtomType x); + + +int main(int argc, char* argv[]) { + GList L; + char* s = "((b),(e),(a,(b,c,d)),(b,((b),b)),x,b,(y))"; + SString S; + + printf("创建广义表 L ...\n"); + StrAssign(S, s); + CreateGList(&L, S); + printf("L = "); + PrintGraph(L); + + printf("删除 L 中的元素 'b' ...\n"); + Algo_5_37_1(&L, 'b'); + printf("L = "); + PrintGraph(L); + + return 0; +} + + +/* + * 删除广义表中值为x的原子项(头尾链表存储表示) + */ +void Algo_5_37_1(GList* L, AtomType x) { + GList h, p; + + if(L == NULL || *L == NULL || (*L)->tag == Atom) { + return; + } + + h = (*L)->Node.ptr.hp; + + if(h != NULL) { + if(h->tag == List) { + Algo_5_37_1(&((*L)->Node.ptr.hp), x); + Algo_5_37_1(&((*L)->Node.ptr.tp), x); + } else { + if(h->Node.atom == x) { + p = *L; + *L = (*L)->Node.ptr.tp; + p->Node.ptr.tp = NULL; + DestroyGList(&p); + Algo_5_37_1(L, x); + } else { + Algo_5_37_1(&((*L)->Node.ptr.tp), x); + } + } + } else { + if((*L)->Node.ptr.tp != NULL) { + Algo_5_37_1(&((*L)->Node.ptr.tp), x); + } + } +} diff --git a/CLion/ExerciseBook/05.37.1/CMakeLists.txt b/CLion/ExerciseBook/05.37.1/CMakeLists.txt new file mode 100644 index 0000000..05647e0 --- /dev/null +++ b/CLion/ExerciseBook/05.37.1/CMakeLists.txt @@ -0,0 +1,7 @@ +# 包含公共库 +include_directories(${CMAKE_SOURCE_DIR}/Status) + +# 生成可执行文件 +add_executable(05.37.1 SString.h SString.c GList-HT.h GList-HT.c 05.37.1.c) +# 链接公共库 +target_link_libraries(05.37.1 Scanf_lib) \ No newline at end of file diff --git a/CLion/ExerciseBook/05.37.1/GList-HT.c b/CLion/ExerciseBook/05.37.1/GList-HT.c new file mode 100644 index 0000000..ddf2766 --- /dev/null +++ b/CLion/ExerciseBook/05.37.1/GList-HT.c @@ -0,0 +1,418 @@ +/*============================ + * 广义表的头尾链表存储表示 + * + * 包含算法: 5.5、5.6、5.7、5.8 + =============================*/ + +#include "GList-HT.h" //**▲05 数组和广义表**// + +/* + * 初始化 + * + * 初始化空的广义表,长度为0,深度为1。 + * + *【注】 + * 需要对每一层去掉括号考察 + */ +Status InitGList(GList* L) { + if(L == NULL) { + return ERROR; + } + + *L = NULL; + + return OK; +} + +/* + * ████████ 算法5.7 ████████ + * + * 创建 + * + * 由字符串S创建广义表L。 + */ +Status CreateGList(GList* L, SString S) { + SString emp; // 代表空广义表的字符串 + SString hsub, sub; + GList p, q; + + if(L == NULL) { + return ERROR; + } + + // 清理字符串S中的空白,包括清理不可打印字符和清理空格 + ClearBlank(S); + + if(StrEmpty(S)) { + return ERROR; + } + + StrAssign(emp, "()"); + + /* + * 如果输入串为(),则代表需要创建空的广义表 + * + *【注】 + * 教材这里的代码是有问题的。 + * StrCompare的返回值指示的是两个字符串的大小,而不是指示两个字符串是否相等。 + * 如果给定的S与()相等,返回值应当是0。 + */ + if(!StrCompare(S, emp)) { + *L = NULL; + } else { + *L = (GList) malloc(sizeof(GLNode)); + if(*L == NULL) { + exit(OVERFLOW); + } + + // 创建原子 + if(StrLength(S) == 1) { + (*L)->tag = Atom; + (*L)->Node.atom = S[1]; + } else { + (*L)->tag = List; + + p = *L; + + // 去掉最外层括号 + SubString(sub, S, 2, StrLength(S) - 2); + + // 重复建n个子表 + do { + // 从sub中分离出表头串hsub,分离完成后,sub也会发生变化 + sever(hsub, sub); + + // 递归创建广义表 + CreateGList(&(p->Node.ptr.hp), hsub); + + q = p; + + // 如果表尾不为空,需要继续处理表尾 + if(!StrEmpty(sub)) { + p = (GList) malloc(sizeof(GLNode)); + if(p == NULL) { + exit(OVERFLOW); + } + + p->tag = List; + + q->Node.ptr.tp = p; + } + } while(!StrEmpty(sub)); + + q->Node.ptr.tp = NULL; + } + } + + return OK; +} + +/* + * 销毁 + * + * 释放广义表所占内存。 + */ +Status DestroyGList(GList* L) { + GList head, tail; + + if(L == NULL || *L == NULL) { + return ERROR; + } + + // 删除原子结点 + if((*L)->tag == Atom) { + free(*L); + *L = NULL; + + // 删除子表结点 + } else { + head = (*L)->Node.ptr.hp; + tail = (*L)->Node.ptr.tp; + free(*L); + *L = NULL; + DestroyGList(&head); + DestroyGList(&tail); + } + + return OK; +} + +/* + * ████████ 算法5.6 ████████ + * + * 复制 + * + * 由广义表L复制得到广义表T。 + */ +Status CopyGList(GList* T, GList L) { + if(T == NULL) { + return ERROR; + } + + if(L == NULL) { + *T = NULL; + } else { + // 新建广义表结点 + *T = (GList) malloc(sizeof(GLNode)); + if(*T == NULL) { + exit(OVERFLOW); + } + + (*T)->tag = L->tag; + + // 复制单原子 + if(L->tag == Atom) { + (*T)->Node.atom = L->Node.atom; + + // 复制表头和表尾 + } else { + CopyGList(&((*T)->Node.ptr.hp), L->Node.ptr.hp); + CopyGList(&((*T)->Node.ptr.tp), L->Node.ptr.tp); + } + } + + return OK; +} + +/* + * 计数 + * + * 返回广义表的长度。 + */ +int GListLength(GList L) { + int count; + + for(count = 0; L != NULL; count++, L = L->Node.ptr.tp) { + } + + return count; +} + +/* + * ████████ 算法5.5 ████████ + * + * 深度 + * + * 返回广义表的深度 + */ +int GListDepth(GList L) { + int max, deep; + GList p; + + // 空表深度为1 + if(L == NULL) { + return 1; + } + + // 原子深度为0 + if(L->tag == Atom) { + return 0; + } + + // 递归求子表深度 + for(max = 0, p = L; p != NULL; p = p->Node.ptr.tp) { + deep = GListDepth(p->Node.ptr.hp); + if(deep > max) { + max = deep; + } + } + + // 非空表的深度是各子元素最大深度加一 + return max + 1; +} + +/* + * 判空 + * + * 判断广义表是否为空。 + */ +Status GListEmpty(GList L) { + return L == NULL ? TRUE : FALSE; +} + +/* + * 表头 + */ +GList GetHead(GList L) { + GList p; + + // 空表无表头,这里不能返回NULL,不然分不清是失败了还是返回了空表 + if(L == NULL) { + exit(ERROR); + } + + CopyGList(&p, L->Node.ptr.hp); + + return p; +} + +/* + * 表尾 + */ +GList GetTail(GList L) { + GList p; + + // 空表无表尾,这里不能返回NULL,不然分不清是失败了还是返回了空表 + if(L == NULL) { + exit(ERROR); + } + + CopyGList(&p, L->Node.ptr.tp); + + return p; +} + +/* + * 插入 + * + * 将元素e插入为广义表L的第一个元素。 + */ +Status InsertFirst(GList* L, GList e) { + GList g; + + if(L == NULL) { + return ERROR; + } + + g = (GList) malloc(sizeof(GLNode)); + if(g == NULL) { + exit(OVERFLOW); + } + + g->tag = List; + g->Node.ptr.hp = e; + g->Node.ptr.tp = *L; + *L = g; + + return OK; +} + +/* + * 删除 + * + * 将广义表L的第一个元素删除,并用e返回。 + */ +Status DeleteFirst(GList* L, GList* e) { + GList p; + + // 空表无法删除 + if(L == NULL || *L == NULL) { + return ERROR; + } + + p = *L; + *L = (*L)->Node.ptr.tp; + + CopyGList(e, p->Node.ptr.hp); + + free(p); + + return OK; +} + +/* + * 遍历 + * + * 用visit函数访问广义表L。 + */ +void Traverse(GList L, void(Visit)(AtomType)) { + + if(L == NULL) { + return; + } + + if(L->tag == Atom) { + Visit(L->Node.atom); + } else { + Traverse(L->Node.ptr.hp, Visit); + Traverse(L->Node.ptr.tp, Visit); + } + +} + +/* + * 图形化输出 + * + * 带括号输出广义表L。 + */ +void PrintGraph(GList L) { + Print(L, Head); + printf("\n"); +} + +/* + * 图形化输出的内部实现,mark是图形化输出标记。 + */ +static void Print(GList L, Mark mark) { + // L为空 + if(L == NULL) { + if(mark == Head) { + printf("("); + } + + printf(")"); + + // L不为空时 + } else { + // 对于原子结点,输出原子 + if(L->tag == Atom) { + printf("%c", L->Node.atom); + + // 对于子表结点,要对表头、表尾分别讨论 + } else { + if(mark == Head) { + printf("("); + } else { + printf(","); + } + + Print(L->Node.ptr.hp, Head); + Print(L->Node.ptr.tp, Tail); + } + } +} + +/* + * ████████ 算法5.8 ████████ + * + * 将非空串str分割成两部分:hsub为第一个','之前的子串,str为第一个','之后的子串。 + * + *【注】 + * 1.这里假设字符串str输入正确,其中无空白符号,且str【已经脱去最外层括号】。 + * 2.分离完成后,str也会发生变化 + */ +static void sever(SString hstr, SString str) { + int i, k, n; + SString ch; + + n = StrLength(str); + + i = 0; // 遍历字符串时的游标 + k = 0; // 标记遇到的未配对括号数量 + + do { + ++i; + + // 截取str第一个字符 + SubString(ch, str, i, 1); + + if(ch[1] == '(') { + ++k; + } + + if(ch[1] == ')') { + --k; + } + } while(i < n && (ch[1] != ',' || k != 0)); + + // 如果存在多个广义表结点 + if(i < n) { + SubString(hstr, str, 1, i - 1); + SubString(str, str, i + 1, n - i); + + // 只有一个广义表结点 + } else { + StrCopy(hstr, str); + ClearString(str); + } +} diff --git a/CLion/ExerciseBook/05.37.1/GList-HT.h b/CLion/ExerciseBook/05.37.1/GList-HT.h new file mode 100644 index 0000000..07c0df2 --- /dev/null +++ b/CLion/ExerciseBook/05.37.1/GList-HT.h @@ -0,0 +1,164 @@ +/*============================ + * 广义表的头尾链表存储表示 + * + * 包含算法: 5.5、5.6、5.7、5.8 + =============================*/ + +#ifndef GLIST_HT_H +#define GLIST_HT_H + +#include +#include // 提供 malloc、realloc、free、exit 原型 +#include "Status.h" //**▲01 绪论**// +#include "SString.h" //**▲04 串**// + +/* 原子元素类型 */ +typedef char AtomType; + +/* + * 广义表结点标记 + * + * Atom-0:原子结点 + * List-1:表结点 + */ +typedef enum { Atom, List } ElemTag; + +/* 广义表(头尾链表存储表示)类型定义 */ +typedef struct GLNode { + ElemTag tag; // 公共标记,用于区分原子结点和表结点 + + // 原子结点和表结点的联合部分 + union { + AtomType atom; // atom是原子结点的值域,AtomType由用户定义 + struct { + struct GLNode* hp; // 指向表头 + struct GLNode* tp; // 指向表尾 + } ptr; // 表结点的指针域 + } Node; +} GLNode; + +/* 广义表类型 */ +typedef GLNode* GList; + +/* + * 图形化输出标记 + * + * Head代表广义表指针来自表头 + * Tail代表广义表指针来自表尾 + */ +typedef enum { Head, Tail } Mark; + + +/* + * 初始化 + * + * 初始化空的广义表,长度为0,深度为1。 + * + *【注】 + * 需要对每一层去掉括号考察 + */ +Status InitGList(GList* L); + +/* + * ████████ 算法5.7 ████████ + * + * 创建 + * + * 由字符串S创建广义表L。 + */ +Status CreateGList(GList* L, SString S); + +/* + * 销毁 + * + * 释放广义表所占内存。 + */ +Status DestroyGList(GList* L); + +/* + * ████████ 算法5.6 ████████ + * + * 复制 + * + * 由广义表L复制得到广义表T。 + */ +Status CopyGList(GList* T, GList L); + +/* + * 计数 + * + * 返回广义表的长度。 + */ +int GListLength(GList L); + +/* + * ████████ 算法5.5 ████████ + * + * 深度 + * + * 返回广义表的深度 + */ +int GListDepth(GList L); + +/* + * 判空 + * + * 判断广义表是否为空。 + */ +Status GListEmpty(GList L); + +/* + * 表头 + */ +GList GetHead(GList L); + +/* + * 表尾 + */ +GList GetTail(GList L); + +/* + * 插入 + * + * 将元素e插入为广义表L的第一个元素。 + */ +Status InsertFirst(GList* L, GList e); + +/* + * 删除 + * + * 将广义表L的第一个元素删除,并用e返回。 + */ +Status DeleteFirst(GList* L, GList* e); + +/* + * 遍历 + * + * 用visit函数访问广义表L。 + */ +void Traverse(GList L, void (Visit)(AtomType)); + +/* + * 图形化输出 + * + * 带括号输出广义表L。 + */ +void PrintGraph(GList L); + +/* + * 图形化输出的内部实现,mark是图形化输出标记。 + */ +static void Print(GList L, Mark mark); + +/* + * ████████ 算法5.8 ████████ + * + * 将非空串str分割成两部分:hsub为第一个','之前的子串,str为第一个','之后的子串。 + * + *【注】 + * 1.这里假设字符串str输入正确,其中无空白符号,且str【已经脱去最外层括号】。 + * 2.分离完成后,str也会发生变化 + */ +static void sever(SString hstr, SString str); + +#endif diff --git a/CLion/ExerciseBook/05.37.1/SString.c b/CLion/ExerciseBook/05.37.1/SString.c new file mode 100644 index 0000000..41d9e15 --- /dev/null +++ b/CLion/ExerciseBook/05.37.1/SString.c @@ -0,0 +1,195 @@ +/*============================= + * 串的定长顺序存储表示(顺序串) + * + * 包含算法: 4.1、4.2、4.3、4.5 + ==============================*/ + +#include "SString.h" //**▲04 串**// + +/* + * 初始化 + * + * 构造一个值为chars的串T。 + * + *【注】 + * 该操作属于最小操作子集 + */ +Status StrAssign(SString T, const char* chars) { + int i, len; + + len = (int) strlen(chars); + + // chars过长 + if(len > MAXSTRLEN) { + return ERROR; + } + + T[0] = len; + for(i = 1; i <= len; i++) { + T[i] = chars[i - 1]; + } + + return OK; +} + +/* + * 清空 + * + * 将串S清空。 + */ +Status ClearString(SString S) { + // 只需要将长度置为0就可以 + S[0] = 0; + return OK; +} + +/* + * 判空 + * + * 判断串S中是否包含有效数据。 + * + * 返回值: + * TRUE : 串S为空 + * FALSE: 串S不为空 + */ +Status StrEmpty(SString S) { + return S[0] == 0 ? TRUE : FALSE; +} + +/* + * 计数 + * + * 返回串S中元素的个数。 + * + *【注】 + * 该操作属于最小操作子集 + */ +int StrLength(SString S) { + return S[0]; +} + +/* + * ████████ 算法4.3 ████████ + * + * 求子串 + * + * 用Sub返回S[pos, pos+len-1]。 + * 返回值指示是否截取成功。 + * + *【注】 + * 该操作属于最小操作子集 + */ +Status SubString(SString Sub, SString S, int pos, int len) { + int i; + + if(pos < 1 || pos > S[0] || len < 0 || pos + len - 1 > S[0]) { + return ERROR; + } + + // 复制元素 + for(i = 1; i <= len; i++) { + Sub[i] = S[pos + i - 1]; + } + + // 确定新长度 + Sub[0] = len; + + return OK; +} + +/* + * 删除 + * + * 删除S[pos, pos+len-1]。 + */ +Status StrDelete(SString S, int pos, int len) { + int i; + + if(pos < 1 || pos + len - 1 > S[0] || len < 0) { + return ERROR; + } + + // 如果待删除的长度为0,则提前返回 + if(len == 0) { + return OK; + } + + // 把后面的元素挪到前面,覆盖掉被删除的元素 + for(i = pos + len; i <= S[0]; i++) { + S[i - len] = S[i]; + } + + // 长度减少 + S[0] -= len; + + return OK; +} + +/* + * 比较 + * + * 比较串S和串T,返回比较结果。 + * + *【注】 + * 该操作属于最小操作子集 + */ +int StrCompare(SString S, SString T) { + int i = 1; + + while(i <= S[0] && i <= T[0]) { + // 遇到不同的字符时,比较其大小 + if(S[i] != T[i]) { + return S[i] - T[i]; + } + + i++; + } + + return S[0] - T[0]; +} + +/* + * 复制 + * + * 将串S复制到串T。 + */ +Status StrCopy(SString T, SString S) { + int i; + + // 连同长度信息一起复制 + for(i = 0; i <= S[0]; i++) { + T[i] = S[i]; + } + + return OK; +} + +/* + * 清理字符串S中的空白,包括清理不可打印字符和清理空格。 + * + *【注】 + * 该函数是在本章中新增的。 + */ +Status ClearBlank(SString S) { + int i, j; + + // 如果是空串 + if(S[0] == 0) { + return ERROR; + } + + for(i = 1, j = 0; i <= S[0]; i++) { + // 如果遇到空白,则略过 + if(S[i] == ' ' || !isprint(S[i])) { + continue; + } + + j++; + + S[j] = S[i]; + } + + S[0] = j; + + return OK; +} diff --git a/CLion/ExerciseBook/05.37.1/SString.h b/CLion/ExerciseBook/05.37.1/SString.h new file mode 100644 index 0000000..e81ca79 --- /dev/null +++ b/CLion/ExerciseBook/05.37.1/SString.h @@ -0,0 +1,117 @@ +/*============================= + * 串的定长顺序存储表示(顺序串) + * + * 包含算法: 4.1、4.2、4.3、4.5 + ==============================*/ + +#ifndef SSTRING_H +#define SSTRING_H + +#include +#include // 提供 strlen 原型 +#include // 提供 isprint 原型 +#include "Status.h" //**▲01 绪论**// + +/* 宏定义 */ +#define MAXSTRLEN 255 // 顺序串的最大串长 + +/* + * 串的顺序存储类型定义 + * + * 注:有效元素从SString的1号单元开始存储 + * SString的0号单元用来存储其长度 + */ +typedef unsigned char SString[MAXSTRLEN + 1]; // 0号单元存放串的长度 + + +/* + * ████ 提示 ████ + * + * 遵循教材的书写习惯,pos指示字符的位序(不是索引),从1开始计数 + */ + + +/* + * 初始化 + * + * 构造一个值为chars的串T。 + * + *【注】 + * 该操作属于最小操作子集 + */ +Status StrAssign(SString T, const char* chars); + +/* + * 清空 + * + * 将串S清空。 + */ +Status ClearString(SString S); + +/* + * 判空 + * + * 判断串S中是否包含有效数据。 + * + * 返回值: + * TRUE : 串S为空 + * FALSE: 串S不为空 + */ +Status StrEmpty(SString S); + +/* + * 计数 + * + * 返回串S中元素的个数。 + * + *【注】 + * 该操作属于最小操作子集 + */ +int StrLength(SString S); + +/* + * ████████ 算法4.3 ████████ + * + * 求子串 + * + * 用Sub返回S[pos, pos+len-1]。 + * 返回值指示是否截取成功。 + * + *【注】 + * 该操作属于最小操作子集 + */ +Status SubString(SString Sub, SString S, int pos, int len); + +/* + * 删除 + * + * 删除S[pos, pos+len-1]。 + */ +Status StrDelete(SString S, int pos, int len); + +/* + * 比较 + * + * 比较串S和串T,返回比较结果。 + * + *【注】 + * 该操作属于最小操作子集 + */ +int StrCompare(SString S, SString T); + +/* + * 复制 + * + * 将串S复制到串T。 + */ +Status StrCopy(SString T, SString S); + +/* + * 清理字符串S中的空白,包括清理不可打印字符和清理空格。 + * + *【注】 + * 该函数是在本章中新增的。 + */ +Status ClearBlank(SString S); + +#endif diff --git a/CLion/ExerciseBook/05.37.2/05.37.2.c b/CLion/ExerciseBook/05.37.2/05.37.2.c new file mode 100644 index 0000000..9fb53fd --- /dev/null +++ b/CLion/ExerciseBook/05.37.2/05.37.2.c @@ -0,0 +1,56 @@ +#include +#include // 提供malloc、realloc、free、exit原型 +#include "SString.h" //**▲04 串**// +#include "GList-E.h" //**▲05 数组和广义表**// + +/* + * 删除广义表中值为x的原子项(扩展线性链表存储表示) + */ +void Algo_5_37_2(GList* L, AtomType x); + + +int main(int argc, char* argv[]) { + GList L; + char* s = "((b),(e),(a,(b,c,d)),(b,((b),b)),x,b,(y))"; + SString S; + + printf("创建广义表 L ...\n"); + StrAssign(S, s); + CreateGList(&L, S); + printf("L = "); + PrintGraph(L); + + printf("删除 L 中的元素 'b' ...\n"); + Algo_5_37_2(&L, 'b'); + printf("L = "); + PrintGraph(L); + + return 0; +} + + +/* + * 删除广义表中值为x的原子项(扩展线性链表存储表示) + */ +void Algo_5_37_2(GList* L, AtomType x) { + GList p; + + if(L == NULL || *L == NULL) { + return; + } + + if((*L)->tag == List) { + Algo_5_37_2(&((*L)->Node.hp), x); + Algo_5_37_2(&((*L)->tp), x); + } else { + if((*L)->Node.atom == x) { + p = *L; + *L = (*L)->tp; + free(p); + + Algo_5_37_2(L, x); + } else { + Algo_5_37_2(&((*L)->tp), x); + } + } +} diff --git a/CLion/ExerciseBook/05.37.2/CMakeLists.txt b/CLion/ExerciseBook/05.37.2/CMakeLists.txt new file mode 100644 index 0000000..5408a99 --- /dev/null +++ b/CLion/ExerciseBook/05.37.2/CMakeLists.txt @@ -0,0 +1,7 @@ +# 包含公共库 +include_directories(${CMAKE_SOURCE_DIR}/Status) + +# 生成可执行文件 +add_executable(05.37.2 SString.h SString.c GList-E.h GList-E.c 05.37.2.c) +# 链接公共库 +target_link_libraries(05.37.2 Scanf_lib) \ No newline at end of file diff --git a/CLion/ExerciseBook/05.37.2/GList-E.c b/CLion/ExerciseBook/05.37.2/GList-E.c new file mode 100644 index 0000000..d994024 --- /dev/null +++ b/CLion/ExerciseBook/05.37.2/GList-E.c @@ -0,0 +1,449 @@ +/*=========================== + * 广义表的扩展线性链表存储表示 + ============================*/ + +#include "GList-E.h" //**▲05 数组和广义表**// + +/* + * 初始化 + * + * 初始化空的广义表,长度为0,深度为1。 + * + *【注】 + * 需要对每一层带上括号考察 + */ +Status InitGList(GList* L) { + if(L == NULL) { + return ERROR; + } + + *L = (GList) malloc(sizeof(GLNode)); + if(!*L) { + exit(OVERFLOW); + } + + (*L)->tag = List; + (*L)->Node.hp = NULL; + (*L)->tp = NULL; + + return OK; +} + +/* + * 创建 + * + * 由字符串S创建广义表L。 + */ +Status CreateGList(GList* L, SString S) { + SString emp, hsub, sub, tmp; + + if(L == NULL) { + return ERROR; + } + + // 清理字符串S中的空白,包括清理不可打印字符和清理空格 + ClearBlank(S); + + if(StrEmpty(S)) { + return ERROR; + } + + // 复制是为了不破坏S + StrCopy(sub, S); + + /* + * 初次执行到此时,带着最外层的括号 + * 再次执行到此时,已经脱去了外层括号 + */ + sever(hsub, sub); + + *L = (GList) malloc(sizeof(GLNode)); + if(*L == NULL) { + exit(OVERFLOW); + } + + StrAssign(emp, "()"); + + if(!StrCompare(hsub, emp)) { + (*L)->tag = List; + (*L)->Node.hp = NULL; + } else { + if(StrLength(hsub) == 1) { + (*L)->tag = Atom; + (*L)->Node.atom = hsub[1]; + } else { + (*L)->tag = List; + + SubString(tmp, hsub, 2, StrLength(hsub) - 2); + + CreateGList(&((*L)->Node.hp), tmp); + } + } + + // 如果不存在队尾,则退出本层递归 + if(StrEmpty(sub)) { + (*L)->tp = NULL; + } else { + // 继续递归求表尾 + CreateGList(&((*L)->tp), sub); + } + + return OK; +} + +/* + * 销毁 + * + * 释放广义表所占内存。 + */ +Status DestroyGList(GList* L) { + GList head, tail; + + if(L == NULL || *L == NULL) { + return ERROR; + } + + // 处理子表结点 + if((*L)->tag == List) { + head = (*L)->Node.hp; // 表头 + tail = (*L)->tp; // 表尾 + + free(*L); + *L = NULL; + + // 递归处理表头 + if(head != NULL) { + DestroyGList(&head); + } + + // 递归处理表尾 + if(tail != NULL) { + DestroyGList(&tail); + } + + // 处理原子结点 + } else { + tail = (*L)->tp; // 表尾 + + free(*L); + *L = NULL; + + if(tail != NULL) { + DestroyGList(&tail); + } + } + + return OK; +} + +/* + * 复制 + * + * 由广义表L复制得到广义表T。 + */ +Status CopyGList(GList* T, GList L) { + + if(L == NULL) { + return ERROR; + } + + *T = (GList) malloc(sizeof(GLNode)); + if(*T == NULL) { + exit(OVERFLOW); + } + + // 复制原子 + if(L->tag == Atom) { + (*T)->tag = Atom; + (*T)->Node.atom = L->Node.atom; + + // 复制子表 + } else { + (*T)->tag = List; + + // 复制表头 + if(L->Node.hp != NULL) { + CopyGList(&((*T)->Node.hp), L->Node.hp); + } else { + (*T)->Node.hp = NULL; + } + } + + // 复制表尾 + if(L->tp != NULL) { + CopyGList(&((*T)->tp), L->tp); + } else { + (*T)->tp = NULL; + } + + return OK; +} + +/* + * 计数 + * + * 返回广义表的长度。 + */ +int GListLength(GList L) { + int count = 0; + GList p; + + // 广义表不存在 + if(L == NULL) { + return -1; + } + + p = L->Node.hp; + + while(p != NULL) { + ++count; + p = p->tp; + } + + return count; +} + +/* + * 深度 + * + * 返回广义表的深度 + */ +int GListDepth(GList L) { + int max, deep; + GList p; + + max = 0; + + // 广义表不存在 + if(L == NULL) { + return -1; + } + + // 空表深度为1 + if(L->tag == List && !L->Node.hp) { + return 1; + } + + // 原子深度为0 + if(L->tag == Atom) { + return 0; + } + + // 递归求子表深度 + for(p = L->Node.hp; p != NULL; p = p->tp) { + // 求以p为头指针的子表深度 + deep = GListDepth(p); + if(deep > max) { + max = deep; + } + } + + return max + 1; +} + +/* + * 判空 + * + * 判断广义表是否为空。 + */ +Status GListEmpty(GList L) { + // 广义表不存在 + if(L == NULL) { + return ERROR; + } + + if(L->tag == List && L->Node.hp == NULL && L->tp == NULL) { + return TRUE; + } else { + return ERROR; + } +} + +/* + * 表头 + */ +GList GetHead(GList L) { + GList p, q; + + // 广义表不存在或广义表为空表,无法获取表头 + if(L == NULL || L->Node.hp == NULL) { + return NULL; + } + + q = L->Node.hp->tp; // 临时保存L的表尾信息 + L->Node.hp->tp = NULL; // 截去L的表尾部分 + + CopyGList(&p, L->Node.hp); // 复制表头信息(已屏蔽表尾) + + L->Node.hp->tp = q; // 恢复L的表尾信息 + + return p; +} + +/* + * 表尾 + */ +GList GetTail(GList L) { + GList p, q; + + // 广义表不存在或广义表为空表,无法获取表尾 + if(L == NULL || L->Node.hp == NULL) { + return NULL; + } + + q = L->Node.hp; // 临时保存L的表头信息 + L->Node.hp = q->tp; // 摘下L的表头部分 + + CopyGList(&p, L); // 复制表尾信息(已屏蔽表头) + + q->tp = L->Node.hp; // 恢复L的表头信息 + L->Node.hp = q; + + return p; +} + +/* + * 插入 + * + * 将元素e插入为广义表L的第一个元素。 + */ +Status InsertFirst(GList* L, GList e) { + + // 广义表不存在 + if(L == NULL || *L == NULL) { + return ERROR; + } + + if(e == NULL) { + return ERROR; + } + + e->tp = (*L)->Node.hp; + (*L)->Node.hp = e; + + return OK; +} + +/* + * 删除 + * + * 将广义表L的第一个元素删除,并用e返回。 + */ +Status DeleteFirst(GList* L, GList* e) { + GList p; + + // 广义表不存在或广义表为空表,则无法删除表头 + if(*L == NULL || (*L)->Node.hp == NULL) { + return ERROR; + } + + p = (*L)->Node.hp; + (*L)->Node.hp = p->tp; + p->tp = NULL; + + *e = p; + + return OK; +} + +/* + * 遍历 + * + * 用visit函数访问广义表L。 + */ +void Traverse(GList L, void(Visit)(AtomType)) { + if(L == NULL) { + return; + } + + if(L->tag == List) { + Traverse(L->Node.hp, Visit); + } else { + Visit(L->Node.atom); + } + + Traverse(L->tp, Visit); +} + +/* + * 图形化输出 + * + * 带括号输出广义表L。 + */ +void PrintGraph(GList L) { + Print(L); + printf("\n"); +} + +/* + * 图形化输出的内部实现。 + */ +static void Print(GList L) { + if(L == NULL) { + return; + } + + // 处理表结点 + if(L->tag == List) { + printf("("); + + if(L->Node.hp) { + Print(L->Node.hp); + } + + if(L->tp) { + printf("),"); + Print(L->tp); + } else { + printf(")"); + } + + // 处理原子结点 + } else { + printf("%c", L->Node.atom); + if(L->tp) { + printf(","); + Print(L->tp); + } + } +} + +/* + * 将非空串str分割成两部分:hsub为第一个','之前的子串,str为第一个','之后的子串。 + * + *【注】 + * 1.这里假设字符串str输入正确,其中无空白符号, + * 但str外层的括号可能脱去,也可能未脱去。 + * 2.分离完成后,str也会发生变化 + */ +static void sever(SString hstr, SString str) { + int i, k, n; + SString ch; + + n = StrLength(str); + + i = 0; // 遍历字符串时的游标 + k = 0; // 标记遇到的未配对括号数量 + + do { + ++i; + + // 截取str第一个字符 + SubString(ch, str, i, 1); + + if(ch[1] == '(') { + ++k; + } + if(ch[1] == ')') { + --k; + } + } while(i < n && (ch[1] != ',' || k != 0)); + + if(i < n) { + SubString(hstr, str, 1, i - 1); + SubString(str, str, i + 1, n - i); + } else { + StrCopy(hstr, str); + ClearString(str); + } +} diff --git a/CLion/ExerciseBook/05.37.2/GList-E.h b/CLion/ExerciseBook/05.37.2/GList-E.h new file mode 100644 index 0000000..5e5b625 --- /dev/null +++ b/CLion/ExerciseBook/05.37.2/GList-E.h @@ -0,0 +1,146 @@ +/*=========================== + * 广义表的扩展线性链表存储表示 + ============================*/ + +#ifndef GLIST_E_H +#define GLIST_E_H + +#include +#include // 提供 malloc、realloc、free、exit 原型 +#include "Status.h" //**▲01 绪论**// +#include "SString.h" //**▲04 串**// + +/* 原子元素类型 */ +typedef char AtomType; //原子类型 + +/* + * 广义表结点标记 + * + * Atom-0:原子结点 + * List-1:表结点 + */ +typedef enum { Atom, List } ElemTag; + +/* 广义表(扩展线性链表存储表示)类型定义 */ +typedef struct GLNode { + ElemTag tag; // 公共标记,用于区分原子结点和表结点 + + // 原子结点和表结点的联合部分 + union + { + AtomType atom; // atom是原子结点的值域,AtomType由用户定义 + struct GLNode* hp; // 指向表头 + } Node; + struct GLNode* tp; // 指向表尾 +} GLNode; + +/* 广义表类型 */ +typedef GLNode* GList; + + +/* + * 初始化 + * + * 初始化空的广义表,长度为0,深度为1。 + * + *【注】 + * 需要对每一层带上括号考察 + */ +Status InitGList(GList* L); + +/* + * 创建 + * + * 由字符串S创建广义表L。 + */ +Status CreateGList(GList* L, SString S); + +/* + * 销毁 + * + * 释放广义表所占内存。 + */ +Status DestroyGList(GList* L); + +/* + * 复制 + * + * 由广义表L复制得到广义表T。 + */ +Status CopyGList(GList* T, GList L); + +/* + * 计数 + * + * 返回广义表的长度。 + */ +int GListLength(GList L); + +/* + * 深度 + * + * 返回广义表的深度 + */ +int GListDepth(GList L); + +/* + * 判空 + * + * 判断广义表是否为空。 + */ +Status GListEmpty(GList L); + +/* + * 表头 + */ +GList GetHead(GList L); + +/* + * 表尾 + */ +GList GetTail(GList L); + +/* + * 插入 + * + * 将元素e插入为广义表L的第一个元素。 + */ +Status InsertFirst(GList* L, GList e); + +/* + * 删除 + * + * 将广义表L的第一个元素删除,并用e返回。 + */ +Status DeleteFirst(GList* L, GList* e); + +/* + * 遍历 + * + * 用visit函数访问广义表L。 + */ +void Traverse(GList L, void(Visit)(AtomType)); + +/* + * 图形化输出 + * + * 带括号输出广义表L。 + */ +void PrintGraph(GList L); + +/* + * 图形化输出的内部实现。 + */ +static void Print(GList L); + +/* + * 将非空串str分割成两部分:hsub为第一个','之前的子串,str为第一个','之后的子串。 + * + *【注】 + * 1.这里假设字符串str输入正确,其中无空白符号, + * 但str外层的括号可能脱去,也可能未脱去。 + * 2.分离完成后,str也会发生变化 + */ +static void sever(SString hstr, SString str); + +#endif diff --git a/CLion/ExerciseBook/05.37.2/SString.c b/CLion/ExerciseBook/05.37.2/SString.c new file mode 100644 index 0000000..41d9e15 --- /dev/null +++ b/CLion/ExerciseBook/05.37.2/SString.c @@ -0,0 +1,195 @@ +/*============================= + * 串的定长顺序存储表示(顺序串) + * + * 包含算法: 4.1、4.2、4.3、4.5 + ==============================*/ + +#include "SString.h" //**▲04 串**// + +/* + * 初始化 + * + * 构造一个值为chars的串T。 + * + *【注】 + * 该操作属于最小操作子集 + */ +Status StrAssign(SString T, const char* chars) { + int i, len; + + len = (int) strlen(chars); + + // chars过长 + if(len > MAXSTRLEN) { + return ERROR; + } + + T[0] = len; + for(i = 1; i <= len; i++) { + T[i] = chars[i - 1]; + } + + return OK; +} + +/* + * 清空 + * + * 将串S清空。 + */ +Status ClearString(SString S) { + // 只需要将长度置为0就可以 + S[0] = 0; + return OK; +} + +/* + * 判空 + * + * 判断串S中是否包含有效数据。 + * + * 返回值: + * TRUE : 串S为空 + * FALSE: 串S不为空 + */ +Status StrEmpty(SString S) { + return S[0] == 0 ? TRUE : FALSE; +} + +/* + * 计数 + * + * 返回串S中元素的个数。 + * + *【注】 + * 该操作属于最小操作子集 + */ +int StrLength(SString S) { + return S[0]; +} + +/* + * ████████ 算法4.3 ████████ + * + * 求子串 + * + * 用Sub返回S[pos, pos+len-1]。 + * 返回值指示是否截取成功。 + * + *【注】 + * 该操作属于最小操作子集 + */ +Status SubString(SString Sub, SString S, int pos, int len) { + int i; + + if(pos < 1 || pos > S[0] || len < 0 || pos + len - 1 > S[0]) { + return ERROR; + } + + // 复制元素 + for(i = 1; i <= len; i++) { + Sub[i] = S[pos + i - 1]; + } + + // 确定新长度 + Sub[0] = len; + + return OK; +} + +/* + * 删除 + * + * 删除S[pos, pos+len-1]。 + */ +Status StrDelete(SString S, int pos, int len) { + int i; + + if(pos < 1 || pos + len - 1 > S[0] || len < 0) { + return ERROR; + } + + // 如果待删除的长度为0,则提前返回 + if(len == 0) { + return OK; + } + + // 把后面的元素挪到前面,覆盖掉被删除的元素 + for(i = pos + len; i <= S[0]; i++) { + S[i - len] = S[i]; + } + + // 长度减少 + S[0] -= len; + + return OK; +} + +/* + * 比较 + * + * 比较串S和串T,返回比较结果。 + * + *【注】 + * 该操作属于最小操作子集 + */ +int StrCompare(SString S, SString T) { + int i = 1; + + while(i <= S[0] && i <= T[0]) { + // 遇到不同的字符时,比较其大小 + if(S[i] != T[i]) { + return S[i] - T[i]; + } + + i++; + } + + return S[0] - T[0]; +} + +/* + * 复制 + * + * 将串S复制到串T。 + */ +Status StrCopy(SString T, SString S) { + int i; + + // 连同长度信息一起复制 + for(i = 0; i <= S[0]; i++) { + T[i] = S[i]; + } + + return OK; +} + +/* + * 清理字符串S中的空白,包括清理不可打印字符和清理空格。 + * + *【注】 + * 该函数是在本章中新增的。 + */ +Status ClearBlank(SString S) { + int i, j; + + // 如果是空串 + if(S[0] == 0) { + return ERROR; + } + + for(i = 1, j = 0; i <= S[0]; i++) { + // 如果遇到空白,则略过 + if(S[i] == ' ' || !isprint(S[i])) { + continue; + } + + j++; + + S[j] = S[i]; + } + + S[0] = j; + + return OK; +} diff --git a/CLion/ExerciseBook/05.37.2/SString.h b/CLion/ExerciseBook/05.37.2/SString.h new file mode 100644 index 0000000..e81ca79 --- /dev/null +++ b/CLion/ExerciseBook/05.37.2/SString.h @@ -0,0 +1,117 @@ +/*============================= + * 串的定长顺序存储表示(顺序串) + * + * 包含算法: 4.1、4.2、4.3、4.5 + ==============================*/ + +#ifndef SSTRING_H +#define SSTRING_H + +#include +#include // 提供 strlen 原型 +#include // 提供 isprint 原型 +#include "Status.h" //**▲01 绪论**// + +/* 宏定义 */ +#define MAXSTRLEN 255 // 顺序串的最大串长 + +/* + * 串的顺序存储类型定义 + * + * 注:有效元素从SString的1号单元开始存储 + * SString的0号单元用来存储其长度 + */ +typedef unsigned char SString[MAXSTRLEN + 1]; // 0号单元存放串的长度 + + +/* + * ████ 提示 ████ + * + * 遵循教材的书写习惯,pos指示字符的位序(不是索引),从1开始计数 + */ + + +/* + * 初始化 + * + * 构造一个值为chars的串T。 + * + *【注】 + * 该操作属于最小操作子集 + */ +Status StrAssign(SString T, const char* chars); + +/* + * 清空 + * + * 将串S清空。 + */ +Status ClearString(SString S); + +/* + * 判空 + * + * 判断串S中是否包含有效数据。 + * + * 返回值: + * TRUE : 串S为空 + * FALSE: 串S不为空 + */ +Status StrEmpty(SString S); + +/* + * 计数 + * + * 返回串S中元素的个数。 + * + *【注】 + * 该操作属于最小操作子集 + */ +int StrLength(SString S); + +/* + * ████████ 算法4.3 ████████ + * + * 求子串 + * + * 用Sub返回S[pos, pos+len-1]。 + * 返回值指示是否截取成功。 + * + *【注】 + * 该操作属于最小操作子集 + */ +Status SubString(SString Sub, SString S, int pos, int len); + +/* + * 删除 + * + * 删除S[pos, pos+len-1]。 + */ +Status StrDelete(SString S, int pos, int len); + +/* + * 比较 + * + * 比较串S和串T,返回比较结果。 + * + *【注】 + * 该操作属于最小操作子集 + */ +int StrCompare(SString S, SString T); + +/* + * 复制 + * + * 将串S复制到串T。 + */ +Status StrCopy(SString T, SString S); + +/* + * 清理字符串S中的空白,包括清理不可打印字符和清理空格。 + * + *【注】 + * 该函数是在本章中新增的。 + */ +Status ClearBlank(SString S); + +#endif diff --git a/CLion/ExerciseBook/05.38.1/05.38.1.c b/CLion/ExerciseBook/05.38.1/05.38.1.c new file mode 100644 index 0000000..b6eb09e --- /dev/null +++ b/CLion/ExerciseBook/05.38.1/05.38.1.c @@ -0,0 +1,47 @@ +#include +#include "SString.h" //**▲04 串**// +#include "GList-HT.h" //**▲05 数组和广义表**// + +/* + * 输出广义表中第l层的原子项(头尾链表存储表示) + */ +void Algo_5_38_1(GList L, int d, int l); + + +int main(int argc, char* argv[]) { + GList L; + char* s = "((a),(b),(c,(d,e,f)),(g,((h),i)))"; + SString S; + + printf("创建广义表 L ...\n"); + StrAssign(S, s); + CreateGList(&L, S); + printf("L = "); + PrintGraph(L); + + printf("广义表第 2 层的原子项为:"); + Algo_5_38_1(L, 0, 2); + printf("\n"); + + return 0; +} + + +/* + * 输出广义表中第l层的原子项(头尾链表存储表示) + */ +void Algo_5_38_1(GList L, int d, int l) { + int i = d; // d的初值赋值为0 + + if(L && l >= i) { + if(L->tag == Atom) { + // 层数符合 + if(l == i) { + printf("%c ", L->Node.atom); + } + } else { + Algo_5_38_1(L->Node.ptr.hp, i + 1, l); // 表头指针指向表的话层数增一 + Algo_5_38_1(L->Node.ptr.tp, i, l); + } + } +} diff --git a/CLion/ExerciseBook/05.38.1/CMakeLists.txt b/CLion/ExerciseBook/05.38.1/CMakeLists.txt new file mode 100644 index 0000000..06ff49f --- /dev/null +++ b/CLion/ExerciseBook/05.38.1/CMakeLists.txt @@ -0,0 +1,7 @@ +# 包含公共库 +include_directories(${CMAKE_SOURCE_DIR}/Status) + +# 生成可执行文件 +add_executable(05.38.1 SString.h SString.c GList-HT.h GList-HT.c 05.38.1.c) +# 链接公共库 +target_link_libraries(05.38.1 Scanf_lib) \ No newline at end of file diff --git a/CLion/ExerciseBook/05.38.1/GList-HT.c b/CLion/ExerciseBook/05.38.1/GList-HT.c new file mode 100644 index 0000000..ddf2766 --- /dev/null +++ b/CLion/ExerciseBook/05.38.1/GList-HT.c @@ -0,0 +1,418 @@ +/*============================ + * 广义表的头尾链表存储表示 + * + * 包含算法: 5.5、5.6、5.7、5.8 + =============================*/ + +#include "GList-HT.h" //**▲05 数组和广义表**// + +/* + * 初始化 + * + * 初始化空的广义表,长度为0,深度为1。 + * + *【注】 + * 需要对每一层去掉括号考察 + */ +Status InitGList(GList* L) { + if(L == NULL) { + return ERROR; + } + + *L = NULL; + + return OK; +} + +/* + * ████████ 算法5.7 ████████ + * + * 创建 + * + * 由字符串S创建广义表L。 + */ +Status CreateGList(GList* L, SString S) { + SString emp; // 代表空广义表的字符串 + SString hsub, sub; + GList p, q; + + if(L == NULL) { + return ERROR; + } + + // 清理字符串S中的空白,包括清理不可打印字符和清理空格 + ClearBlank(S); + + if(StrEmpty(S)) { + return ERROR; + } + + StrAssign(emp, "()"); + + /* + * 如果输入串为(),则代表需要创建空的广义表 + * + *【注】 + * 教材这里的代码是有问题的。 + * StrCompare的返回值指示的是两个字符串的大小,而不是指示两个字符串是否相等。 + * 如果给定的S与()相等,返回值应当是0。 + */ + if(!StrCompare(S, emp)) { + *L = NULL; + } else { + *L = (GList) malloc(sizeof(GLNode)); + if(*L == NULL) { + exit(OVERFLOW); + } + + // 创建原子 + if(StrLength(S) == 1) { + (*L)->tag = Atom; + (*L)->Node.atom = S[1]; + } else { + (*L)->tag = List; + + p = *L; + + // 去掉最外层括号 + SubString(sub, S, 2, StrLength(S) - 2); + + // 重复建n个子表 + do { + // 从sub中分离出表头串hsub,分离完成后,sub也会发生变化 + sever(hsub, sub); + + // 递归创建广义表 + CreateGList(&(p->Node.ptr.hp), hsub); + + q = p; + + // 如果表尾不为空,需要继续处理表尾 + if(!StrEmpty(sub)) { + p = (GList) malloc(sizeof(GLNode)); + if(p == NULL) { + exit(OVERFLOW); + } + + p->tag = List; + + q->Node.ptr.tp = p; + } + } while(!StrEmpty(sub)); + + q->Node.ptr.tp = NULL; + } + } + + return OK; +} + +/* + * 销毁 + * + * 释放广义表所占内存。 + */ +Status DestroyGList(GList* L) { + GList head, tail; + + if(L == NULL || *L == NULL) { + return ERROR; + } + + // 删除原子结点 + if((*L)->tag == Atom) { + free(*L); + *L = NULL; + + // 删除子表结点 + } else { + head = (*L)->Node.ptr.hp; + tail = (*L)->Node.ptr.tp; + free(*L); + *L = NULL; + DestroyGList(&head); + DestroyGList(&tail); + } + + return OK; +} + +/* + * ████████ 算法5.6 ████████ + * + * 复制 + * + * 由广义表L复制得到广义表T。 + */ +Status CopyGList(GList* T, GList L) { + if(T == NULL) { + return ERROR; + } + + if(L == NULL) { + *T = NULL; + } else { + // 新建广义表结点 + *T = (GList) malloc(sizeof(GLNode)); + if(*T == NULL) { + exit(OVERFLOW); + } + + (*T)->tag = L->tag; + + // 复制单原子 + if(L->tag == Atom) { + (*T)->Node.atom = L->Node.atom; + + // 复制表头和表尾 + } else { + CopyGList(&((*T)->Node.ptr.hp), L->Node.ptr.hp); + CopyGList(&((*T)->Node.ptr.tp), L->Node.ptr.tp); + } + } + + return OK; +} + +/* + * 计数 + * + * 返回广义表的长度。 + */ +int GListLength(GList L) { + int count; + + for(count = 0; L != NULL; count++, L = L->Node.ptr.tp) { + } + + return count; +} + +/* + * ████████ 算法5.5 ████████ + * + * 深度 + * + * 返回广义表的深度 + */ +int GListDepth(GList L) { + int max, deep; + GList p; + + // 空表深度为1 + if(L == NULL) { + return 1; + } + + // 原子深度为0 + if(L->tag == Atom) { + return 0; + } + + // 递归求子表深度 + for(max = 0, p = L; p != NULL; p = p->Node.ptr.tp) { + deep = GListDepth(p->Node.ptr.hp); + if(deep > max) { + max = deep; + } + } + + // 非空表的深度是各子元素最大深度加一 + return max + 1; +} + +/* + * 判空 + * + * 判断广义表是否为空。 + */ +Status GListEmpty(GList L) { + return L == NULL ? TRUE : FALSE; +} + +/* + * 表头 + */ +GList GetHead(GList L) { + GList p; + + // 空表无表头,这里不能返回NULL,不然分不清是失败了还是返回了空表 + if(L == NULL) { + exit(ERROR); + } + + CopyGList(&p, L->Node.ptr.hp); + + return p; +} + +/* + * 表尾 + */ +GList GetTail(GList L) { + GList p; + + // 空表无表尾,这里不能返回NULL,不然分不清是失败了还是返回了空表 + if(L == NULL) { + exit(ERROR); + } + + CopyGList(&p, L->Node.ptr.tp); + + return p; +} + +/* + * 插入 + * + * 将元素e插入为广义表L的第一个元素。 + */ +Status InsertFirst(GList* L, GList e) { + GList g; + + if(L == NULL) { + return ERROR; + } + + g = (GList) malloc(sizeof(GLNode)); + if(g == NULL) { + exit(OVERFLOW); + } + + g->tag = List; + g->Node.ptr.hp = e; + g->Node.ptr.tp = *L; + *L = g; + + return OK; +} + +/* + * 删除 + * + * 将广义表L的第一个元素删除,并用e返回。 + */ +Status DeleteFirst(GList* L, GList* e) { + GList p; + + // 空表无法删除 + if(L == NULL || *L == NULL) { + return ERROR; + } + + p = *L; + *L = (*L)->Node.ptr.tp; + + CopyGList(e, p->Node.ptr.hp); + + free(p); + + return OK; +} + +/* + * 遍历 + * + * 用visit函数访问广义表L。 + */ +void Traverse(GList L, void(Visit)(AtomType)) { + + if(L == NULL) { + return; + } + + if(L->tag == Atom) { + Visit(L->Node.atom); + } else { + Traverse(L->Node.ptr.hp, Visit); + Traverse(L->Node.ptr.tp, Visit); + } + +} + +/* + * 图形化输出 + * + * 带括号输出广义表L。 + */ +void PrintGraph(GList L) { + Print(L, Head); + printf("\n"); +} + +/* + * 图形化输出的内部实现,mark是图形化输出标记。 + */ +static void Print(GList L, Mark mark) { + // L为空 + if(L == NULL) { + if(mark == Head) { + printf("("); + } + + printf(")"); + + // L不为空时 + } else { + // 对于原子结点,输出原子 + if(L->tag == Atom) { + printf("%c", L->Node.atom); + + // 对于子表结点,要对表头、表尾分别讨论 + } else { + if(mark == Head) { + printf("("); + } else { + printf(","); + } + + Print(L->Node.ptr.hp, Head); + Print(L->Node.ptr.tp, Tail); + } + } +} + +/* + * ████████ 算法5.8 ████████ + * + * 将非空串str分割成两部分:hsub为第一个','之前的子串,str为第一个','之后的子串。 + * + *【注】 + * 1.这里假设字符串str输入正确,其中无空白符号,且str【已经脱去最外层括号】。 + * 2.分离完成后,str也会发生变化 + */ +static void sever(SString hstr, SString str) { + int i, k, n; + SString ch; + + n = StrLength(str); + + i = 0; // 遍历字符串时的游标 + k = 0; // 标记遇到的未配对括号数量 + + do { + ++i; + + // 截取str第一个字符 + SubString(ch, str, i, 1); + + if(ch[1] == '(') { + ++k; + } + + if(ch[1] == ')') { + --k; + } + } while(i < n && (ch[1] != ',' || k != 0)); + + // 如果存在多个广义表结点 + if(i < n) { + SubString(hstr, str, 1, i - 1); + SubString(str, str, i + 1, n - i); + + // 只有一个广义表结点 + } else { + StrCopy(hstr, str); + ClearString(str); + } +} diff --git a/CLion/ExerciseBook/05.38.1/GList-HT.h b/CLion/ExerciseBook/05.38.1/GList-HT.h new file mode 100644 index 0000000..07c0df2 --- /dev/null +++ b/CLion/ExerciseBook/05.38.1/GList-HT.h @@ -0,0 +1,164 @@ +/*============================ + * 广义表的头尾链表存储表示 + * + * 包含算法: 5.5、5.6、5.7、5.8 + =============================*/ + +#ifndef GLIST_HT_H +#define GLIST_HT_H + +#include +#include // 提供 malloc、realloc、free、exit 原型 +#include "Status.h" //**▲01 绪论**// +#include "SString.h" //**▲04 串**// + +/* 原子元素类型 */ +typedef char AtomType; + +/* + * 广义表结点标记 + * + * Atom-0:原子结点 + * List-1:表结点 + */ +typedef enum { Atom, List } ElemTag; + +/* 广义表(头尾链表存储表示)类型定义 */ +typedef struct GLNode { + ElemTag tag; // 公共标记,用于区分原子结点和表结点 + + // 原子结点和表结点的联合部分 + union { + AtomType atom; // atom是原子结点的值域,AtomType由用户定义 + struct { + struct GLNode* hp; // 指向表头 + struct GLNode* tp; // 指向表尾 + } ptr; // 表结点的指针域 + } Node; +} GLNode; + +/* 广义表类型 */ +typedef GLNode* GList; + +/* + * 图形化输出标记 + * + * Head代表广义表指针来自表头 + * Tail代表广义表指针来自表尾 + */ +typedef enum { Head, Tail } Mark; + + +/* + * 初始化 + * + * 初始化空的广义表,长度为0,深度为1。 + * + *【注】 + * 需要对每一层去掉括号考察 + */ +Status InitGList(GList* L); + +/* + * ████████ 算法5.7 ████████ + * + * 创建 + * + * 由字符串S创建广义表L。 + */ +Status CreateGList(GList* L, SString S); + +/* + * 销毁 + * + * 释放广义表所占内存。 + */ +Status DestroyGList(GList* L); + +/* + * ████████ 算法5.6 ████████ + * + * 复制 + * + * 由广义表L复制得到广义表T。 + */ +Status CopyGList(GList* T, GList L); + +/* + * 计数 + * + * 返回广义表的长度。 + */ +int GListLength(GList L); + +/* + * ████████ 算法5.5 ████████ + * + * 深度 + * + * 返回广义表的深度 + */ +int GListDepth(GList L); + +/* + * 判空 + * + * 判断广义表是否为空。 + */ +Status GListEmpty(GList L); + +/* + * 表头 + */ +GList GetHead(GList L); + +/* + * 表尾 + */ +GList GetTail(GList L); + +/* + * 插入 + * + * 将元素e插入为广义表L的第一个元素。 + */ +Status InsertFirst(GList* L, GList e); + +/* + * 删除 + * + * 将广义表L的第一个元素删除,并用e返回。 + */ +Status DeleteFirst(GList* L, GList* e); + +/* + * 遍历 + * + * 用visit函数访问广义表L。 + */ +void Traverse(GList L, void (Visit)(AtomType)); + +/* + * 图形化输出 + * + * 带括号输出广义表L。 + */ +void PrintGraph(GList L); + +/* + * 图形化输出的内部实现,mark是图形化输出标记。 + */ +static void Print(GList L, Mark mark); + +/* + * ████████ 算法5.8 ████████ + * + * 将非空串str分割成两部分:hsub为第一个','之前的子串,str为第一个','之后的子串。 + * + *【注】 + * 1.这里假设字符串str输入正确,其中无空白符号,且str【已经脱去最外层括号】。 + * 2.分离完成后,str也会发生变化 + */ +static void sever(SString hstr, SString str); + +#endif diff --git a/CLion/ExerciseBook/05.38.1/SString.c b/CLion/ExerciseBook/05.38.1/SString.c new file mode 100644 index 0000000..41d9e15 --- /dev/null +++ b/CLion/ExerciseBook/05.38.1/SString.c @@ -0,0 +1,195 @@ +/*============================= + * 串的定长顺序存储表示(顺序串) + * + * 包含算法: 4.1、4.2、4.3、4.5 + ==============================*/ + +#include "SString.h" //**▲04 串**// + +/* + * 初始化 + * + * 构造一个值为chars的串T。 + * + *【注】 + * 该操作属于最小操作子集 + */ +Status StrAssign(SString T, const char* chars) { + int i, len; + + len = (int) strlen(chars); + + // chars过长 + if(len > MAXSTRLEN) { + return ERROR; + } + + T[0] = len; + for(i = 1; i <= len; i++) { + T[i] = chars[i - 1]; + } + + return OK; +} + +/* + * 清空 + * + * 将串S清空。 + */ +Status ClearString(SString S) { + // 只需要将长度置为0就可以 + S[0] = 0; + return OK; +} + +/* + * 判空 + * + * 判断串S中是否包含有效数据。 + * + * 返回值: + * TRUE : 串S为空 + * FALSE: 串S不为空 + */ +Status StrEmpty(SString S) { + return S[0] == 0 ? TRUE : FALSE; +} + +/* + * 计数 + * + * 返回串S中元素的个数。 + * + *【注】 + * 该操作属于最小操作子集 + */ +int StrLength(SString S) { + return S[0]; +} + +/* + * ████████ 算法4.3 ████████ + * + * 求子串 + * + * 用Sub返回S[pos, pos+len-1]。 + * 返回值指示是否截取成功。 + * + *【注】 + * 该操作属于最小操作子集 + */ +Status SubString(SString Sub, SString S, int pos, int len) { + int i; + + if(pos < 1 || pos > S[0] || len < 0 || pos + len - 1 > S[0]) { + return ERROR; + } + + // 复制元素 + for(i = 1; i <= len; i++) { + Sub[i] = S[pos + i - 1]; + } + + // 确定新长度 + Sub[0] = len; + + return OK; +} + +/* + * 删除 + * + * 删除S[pos, pos+len-1]。 + */ +Status StrDelete(SString S, int pos, int len) { + int i; + + if(pos < 1 || pos + len - 1 > S[0] || len < 0) { + return ERROR; + } + + // 如果待删除的长度为0,则提前返回 + if(len == 0) { + return OK; + } + + // 把后面的元素挪到前面,覆盖掉被删除的元素 + for(i = pos + len; i <= S[0]; i++) { + S[i - len] = S[i]; + } + + // 长度减少 + S[0] -= len; + + return OK; +} + +/* + * 比较 + * + * 比较串S和串T,返回比较结果。 + * + *【注】 + * 该操作属于最小操作子集 + */ +int StrCompare(SString S, SString T) { + int i = 1; + + while(i <= S[0] && i <= T[0]) { + // 遇到不同的字符时,比较其大小 + if(S[i] != T[i]) { + return S[i] - T[i]; + } + + i++; + } + + return S[0] - T[0]; +} + +/* + * 复制 + * + * 将串S复制到串T。 + */ +Status StrCopy(SString T, SString S) { + int i; + + // 连同长度信息一起复制 + for(i = 0; i <= S[0]; i++) { + T[i] = S[i]; + } + + return OK; +} + +/* + * 清理字符串S中的空白,包括清理不可打印字符和清理空格。 + * + *【注】 + * 该函数是在本章中新增的。 + */ +Status ClearBlank(SString S) { + int i, j; + + // 如果是空串 + if(S[0] == 0) { + return ERROR; + } + + for(i = 1, j = 0; i <= S[0]; i++) { + // 如果遇到空白,则略过 + if(S[i] == ' ' || !isprint(S[i])) { + continue; + } + + j++; + + S[j] = S[i]; + } + + S[0] = j; + + return OK; +} diff --git a/CLion/ExerciseBook/05.38.1/SString.h b/CLion/ExerciseBook/05.38.1/SString.h new file mode 100644 index 0000000..e81ca79 --- /dev/null +++ b/CLion/ExerciseBook/05.38.1/SString.h @@ -0,0 +1,117 @@ +/*============================= + * 串的定长顺序存储表示(顺序串) + * + * 包含算法: 4.1、4.2、4.3、4.5 + ==============================*/ + +#ifndef SSTRING_H +#define SSTRING_H + +#include +#include // 提供 strlen 原型 +#include // 提供 isprint 原型 +#include "Status.h" //**▲01 绪论**// + +/* 宏定义 */ +#define MAXSTRLEN 255 // 顺序串的最大串长 + +/* + * 串的顺序存储类型定义 + * + * 注:有效元素从SString的1号单元开始存储 + * SString的0号单元用来存储其长度 + */ +typedef unsigned char SString[MAXSTRLEN + 1]; // 0号单元存放串的长度 + + +/* + * ████ 提示 ████ + * + * 遵循教材的书写习惯,pos指示字符的位序(不是索引),从1开始计数 + */ + + +/* + * 初始化 + * + * 构造一个值为chars的串T。 + * + *【注】 + * 该操作属于最小操作子集 + */ +Status StrAssign(SString T, const char* chars); + +/* + * 清空 + * + * 将串S清空。 + */ +Status ClearString(SString S); + +/* + * 判空 + * + * 判断串S中是否包含有效数据。 + * + * 返回值: + * TRUE : 串S为空 + * FALSE: 串S不为空 + */ +Status StrEmpty(SString S); + +/* + * 计数 + * + * 返回串S中元素的个数。 + * + *【注】 + * 该操作属于最小操作子集 + */ +int StrLength(SString S); + +/* + * ████████ 算法4.3 ████████ + * + * 求子串 + * + * 用Sub返回S[pos, pos+len-1]。 + * 返回值指示是否截取成功。 + * + *【注】 + * 该操作属于最小操作子集 + */ +Status SubString(SString Sub, SString S, int pos, int len); + +/* + * 删除 + * + * 删除S[pos, pos+len-1]。 + */ +Status StrDelete(SString S, int pos, int len); + +/* + * 比较 + * + * 比较串S和串T,返回比较结果。 + * + *【注】 + * 该操作属于最小操作子集 + */ +int StrCompare(SString S, SString T); + +/* + * 复制 + * + * 将串S复制到串T。 + */ +Status StrCopy(SString T, SString S); + +/* + * 清理字符串S中的空白,包括清理不可打印字符和清理空格。 + * + *【注】 + * 该函数是在本章中新增的。 + */ +Status ClearBlank(SString S); + +#endif diff --git a/CLion/ExerciseBook/05.38.2/05.38.2.c b/CLion/ExerciseBook/05.38.2/05.38.2.c new file mode 100644 index 0000000..9e72692 --- /dev/null +++ b/CLion/ExerciseBook/05.38.2/05.38.2.c @@ -0,0 +1,48 @@ +#include +#include "SString.h" //**▲04 串**// +#include "GList-E.h" //**▲05 数组和广义表**// + +/* + * 输出广义表中第l层的原子项(扩展线性链表存储表示) + */ +void Algo_5_38_2(GList L, int d, int l); + + +int main(int argc, char* argv[]) { + GList L; + char* s = "((a),(b),(c,(d,e,f)),(g,((h),i)))"; + SString S; + + printf("创建广义表 L ...\n"); + StrAssign(S, s); + CreateGList(&L, S); + printf("L = "); + PrintGraph(L); + + printf("广义表第 2 层的原子项为:"); + Algo_5_38_2(L, 0, 2); + printf("\n"); + + return 0; +} + + +/* + * 输出广义表中第l层的原子项(扩展线性链表存储表示) + */ +void Algo_5_38_2(GList L, int d, int l) { + int i = d; // d的初值赋值为0 + + if(L && l >= i) { + if(L->tag == Atom) { + // 层数符合 + if(l == i) { + printf("%c ", L->Node.atom); + } + } else { + Algo_5_38_2(L->Node.hp, i + 1, l); // 表头指针指向表的话层数增一 + } + + Algo_5_38_2(L->tp, i, l); + } +} diff --git a/CLion/ExerciseBook/05.38.2/CMakeLists.txt b/CLion/ExerciseBook/05.38.2/CMakeLists.txt new file mode 100644 index 0000000..3f25d1c --- /dev/null +++ b/CLion/ExerciseBook/05.38.2/CMakeLists.txt @@ -0,0 +1,7 @@ +# 包含公共库 +include_directories(${CMAKE_SOURCE_DIR}/Status) + +# 生成可执行文件 +add_executable(05.38.2 SString.h SString.c GList-E.h GList-E.c 05.38.2.c) +# 链接公共库 +target_link_libraries(05.38.2 Scanf_lib) \ No newline at end of file diff --git a/CLion/ExerciseBook/05.38.2/GList-E.c b/CLion/ExerciseBook/05.38.2/GList-E.c new file mode 100644 index 0000000..d994024 --- /dev/null +++ b/CLion/ExerciseBook/05.38.2/GList-E.c @@ -0,0 +1,449 @@ +/*=========================== + * 广义表的扩展线性链表存储表示 + ============================*/ + +#include "GList-E.h" //**▲05 数组和广义表**// + +/* + * 初始化 + * + * 初始化空的广义表,长度为0,深度为1。 + * + *【注】 + * 需要对每一层带上括号考察 + */ +Status InitGList(GList* L) { + if(L == NULL) { + return ERROR; + } + + *L = (GList) malloc(sizeof(GLNode)); + if(!*L) { + exit(OVERFLOW); + } + + (*L)->tag = List; + (*L)->Node.hp = NULL; + (*L)->tp = NULL; + + return OK; +} + +/* + * 创建 + * + * 由字符串S创建广义表L。 + */ +Status CreateGList(GList* L, SString S) { + SString emp, hsub, sub, tmp; + + if(L == NULL) { + return ERROR; + } + + // 清理字符串S中的空白,包括清理不可打印字符和清理空格 + ClearBlank(S); + + if(StrEmpty(S)) { + return ERROR; + } + + // 复制是为了不破坏S + StrCopy(sub, S); + + /* + * 初次执行到此时,带着最外层的括号 + * 再次执行到此时,已经脱去了外层括号 + */ + sever(hsub, sub); + + *L = (GList) malloc(sizeof(GLNode)); + if(*L == NULL) { + exit(OVERFLOW); + } + + StrAssign(emp, "()"); + + if(!StrCompare(hsub, emp)) { + (*L)->tag = List; + (*L)->Node.hp = NULL; + } else { + if(StrLength(hsub) == 1) { + (*L)->tag = Atom; + (*L)->Node.atom = hsub[1]; + } else { + (*L)->tag = List; + + SubString(tmp, hsub, 2, StrLength(hsub) - 2); + + CreateGList(&((*L)->Node.hp), tmp); + } + } + + // 如果不存在队尾,则退出本层递归 + if(StrEmpty(sub)) { + (*L)->tp = NULL; + } else { + // 继续递归求表尾 + CreateGList(&((*L)->tp), sub); + } + + return OK; +} + +/* + * 销毁 + * + * 释放广义表所占内存。 + */ +Status DestroyGList(GList* L) { + GList head, tail; + + if(L == NULL || *L == NULL) { + return ERROR; + } + + // 处理子表结点 + if((*L)->tag == List) { + head = (*L)->Node.hp; // 表头 + tail = (*L)->tp; // 表尾 + + free(*L); + *L = NULL; + + // 递归处理表头 + if(head != NULL) { + DestroyGList(&head); + } + + // 递归处理表尾 + if(tail != NULL) { + DestroyGList(&tail); + } + + // 处理原子结点 + } else { + tail = (*L)->tp; // 表尾 + + free(*L); + *L = NULL; + + if(tail != NULL) { + DestroyGList(&tail); + } + } + + return OK; +} + +/* + * 复制 + * + * 由广义表L复制得到广义表T。 + */ +Status CopyGList(GList* T, GList L) { + + if(L == NULL) { + return ERROR; + } + + *T = (GList) malloc(sizeof(GLNode)); + if(*T == NULL) { + exit(OVERFLOW); + } + + // 复制原子 + if(L->tag == Atom) { + (*T)->tag = Atom; + (*T)->Node.atom = L->Node.atom; + + // 复制子表 + } else { + (*T)->tag = List; + + // 复制表头 + if(L->Node.hp != NULL) { + CopyGList(&((*T)->Node.hp), L->Node.hp); + } else { + (*T)->Node.hp = NULL; + } + } + + // 复制表尾 + if(L->tp != NULL) { + CopyGList(&((*T)->tp), L->tp); + } else { + (*T)->tp = NULL; + } + + return OK; +} + +/* + * 计数 + * + * 返回广义表的长度。 + */ +int GListLength(GList L) { + int count = 0; + GList p; + + // 广义表不存在 + if(L == NULL) { + return -1; + } + + p = L->Node.hp; + + while(p != NULL) { + ++count; + p = p->tp; + } + + return count; +} + +/* + * 深度 + * + * 返回广义表的深度 + */ +int GListDepth(GList L) { + int max, deep; + GList p; + + max = 0; + + // 广义表不存在 + if(L == NULL) { + return -1; + } + + // 空表深度为1 + if(L->tag == List && !L->Node.hp) { + return 1; + } + + // 原子深度为0 + if(L->tag == Atom) { + return 0; + } + + // 递归求子表深度 + for(p = L->Node.hp; p != NULL; p = p->tp) { + // 求以p为头指针的子表深度 + deep = GListDepth(p); + if(deep > max) { + max = deep; + } + } + + return max + 1; +} + +/* + * 判空 + * + * 判断广义表是否为空。 + */ +Status GListEmpty(GList L) { + // 广义表不存在 + if(L == NULL) { + return ERROR; + } + + if(L->tag == List && L->Node.hp == NULL && L->tp == NULL) { + return TRUE; + } else { + return ERROR; + } +} + +/* + * 表头 + */ +GList GetHead(GList L) { + GList p, q; + + // 广义表不存在或广义表为空表,无法获取表头 + if(L == NULL || L->Node.hp == NULL) { + return NULL; + } + + q = L->Node.hp->tp; // 临时保存L的表尾信息 + L->Node.hp->tp = NULL; // 截去L的表尾部分 + + CopyGList(&p, L->Node.hp); // 复制表头信息(已屏蔽表尾) + + L->Node.hp->tp = q; // 恢复L的表尾信息 + + return p; +} + +/* + * 表尾 + */ +GList GetTail(GList L) { + GList p, q; + + // 广义表不存在或广义表为空表,无法获取表尾 + if(L == NULL || L->Node.hp == NULL) { + return NULL; + } + + q = L->Node.hp; // 临时保存L的表头信息 + L->Node.hp = q->tp; // 摘下L的表头部分 + + CopyGList(&p, L); // 复制表尾信息(已屏蔽表头) + + q->tp = L->Node.hp; // 恢复L的表头信息 + L->Node.hp = q; + + return p; +} + +/* + * 插入 + * + * 将元素e插入为广义表L的第一个元素。 + */ +Status InsertFirst(GList* L, GList e) { + + // 广义表不存在 + if(L == NULL || *L == NULL) { + return ERROR; + } + + if(e == NULL) { + return ERROR; + } + + e->tp = (*L)->Node.hp; + (*L)->Node.hp = e; + + return OK; +} + +/* + * 删除 + * + * 将广义表L的第一个元素删除,并用e返回。 + */ +Status DeleteFirst(GList* L, GList* e) { + GList p; + + // 广义表不存在或广义表为空表,则无法删除表头 + if(*L == NULL || (*L)->Node.hp == NULL) { + return ERROR; + } + + p = (*L)->Node.hp; + (*L)->Node.hp = p->tp; + p->tp = NULL; + + *e = p; + + return OK; +} + +/* + * 遍历 + * + * 用visit函数访问广义表L。 + */ +void Traverse(GList L, void(Visit)(AtomType)) { + if(L == NULL) { + return; + } + + if(L->tag == List) { + Traverse(L->Node.hp, Visit); + } else { + Visit(L->Node.atom); + } + + Traverse(L->tp, Visit); +} + +/* + * 图形化输出 + * + * 带括号输出广义表L。 + */ +void PrintGraph(GList L) { + Print(L); + printf("\n"); +} + +/* + * 图形化输出的内部实现。 + */ +static void Print(GList L) { + if(L == NULL) { + return; + } + + // 处理表结点 + if(L->tag == List) { + printf("("); + + if(L->Node.hp) { + Print(L->Node.hp); + } + + if(L->tp) { + printf("),"); + Print(L->tp); + } else { + printf(")"); + } + + // 处理原子结点 + } else { + printf("%c", L->Node.atom); + if(L->tp) { + printf(","); + Print(L->tp); + } + } +} + +/* + * 将非空串str分割成两部分:hsub为第一个','之前的子串,str为第一个','之后的子串。 + * + *【注】 + * 1.这里假设字符串str输入正确,其中无空白符号, + * 但str外层的括号可能脱去,也可能未脱去。 + * 2.分离完成后,str也会发生变化 + */ +static void sever(SString hstr, SString str) { + int i, k, n; + SString ch; + + n = StrLength(str); + + i = 0; // 遍历字符串时的游标 + k = 0; // 标记遇到的未配对括号数量 + + do { + ++i; + + // 截取str第一个字符 + SubString(ch, str, i, 1); + + if(ch[1] == '(') { + ++k; + } + if(ch[1] == ')') { + --k; + } + } while(i < n && (ch[1] != ',' || k != 0)); + + if(i < n) { + SubString(hstr, str, 1, i - 1); + SubString(str, str, i + 1, n - i); + } else { + StrCopy(hstr, str); + ClearString(str); + } +} diff --git a/CLion/ExerciseBook/05.38.2/GList-E.h b/CLion/ExerciseBook/05.38.2/GList-E.h new file mode 100644 index 0000000..5e5b625 --- /dev/null +++ b/CLion/ExerciseBook/05.38.2/GList-E.h @@ -0,0 +1,146 @@ +/*=========================== + * 广义表的扩展线性链表存储表示 + ============================*/ + +#ifndef GLIST_E_H +#define GLIST_E_H + +#include +#include // 提供 malloc、realloc、free、exit 原型 +#include "Status.h" //**▲01 绪论**// +#include "SString.h" //**▲04 串**// + +/* 原子元素类型 */ +typedef char AtomType; //原子类型 + +/* + * 广义表结点标记 + * + * Atom-0:原子结点 + * List-1:表结点 + */ +typedef enum { Atom, List } ElemTag; + +/* 广义表(扩展线性链表存储表示)类型定义 */ +typedef struct GLNode { + ElemTag tag; // 公共标记,用于区分原子结点和表结点 + + // 原子结点和表结点的联合部分 + union + { + AtomType atom; // atom是原子结点的值域,AtomType由用户定义 + struct GLNode* hp; // 指向表头 + } Node; + struct GLNode* tp; // 指向表尾 +} GLNode; + +/* 广义表类型 */ +typedef GLNode* GList; + + +/* + * 初始化 + * + * 初始化空的广义表,长度为0,深度为1。 + * + *【注】 + * 需要对每一层带上括号考察 + */ +Status InitGList(GList* L); + +/* + * 创建 + * + * 由字符串S创建广义表L。 + */ +Status CreateGList(GList* L, SString S); + +/* + * 销毁 + * + * 释放广义表所占内存。 + */ +Status DestroyGList(GList* L); + +/* + * 复制 + * + * 由广义表L复制得到广义表T。 + */ +Status CopyGList(GList* T, GList L); + +/* + * 计数 + * + * 返回广义表的长度。 + */ +int GListLength(GList L); + +/* + * 深度 + * + * 返回广义表的深度 + */ +int GListDepth(GList L); + +/* + * 判空 + * + * 判断广义表是否为空。 + */ +Status GListEmpty(GList L); + +/* + * 表头 + */ +GList GetHead(GList L); + +/* + * 表尾 + */ +GList GetTail(GList L); + +/* + * 插入 + * + * 将元素e插入为广义表L的第一个元素。 + */ +Status InsertFirst(GList* L, GList e); + +/* + * 删除 + * + * 将广义表L的第一个元素删除,并用e返回。 + */ +Status DeleteFirst(GList* L, GList* e); + +/* + * 遍历 + * + * 用visit函数访问广义表L。 + */ +void Traverse(GList L, void(Visit)(AtomType)); + +/* + * 图形化输出 + * + * 带括号输出广义表L。 + */ +void PrintGraph(GList L); + +/* + * 图形化输出的内部实现。 + */ +static void Print(GList L); + +/* + * 将非空串str分割成两部分:hsub为第一个','之前的子串,str为第一个','之后的子串。 + * + *【注】 + * 1.这里假设字符串str输入正确,其中无空白符号, + * 但str外层的括号可能脱去,也可能未脱去。 + * 2.分离完成后,str也会发生变化 + */ +static void sever(SString hstr, SString str); + +#endif diff --git a/CLion/ExerciseBook/05.38.2/SString.c b/CLion/ExerciseBook/05.38.2/SString.c new file mode 100644 index 0000000..41d9e15 --- /dev/null +++ b/CLion/ExerciseBook/05.38.2/SString.c @@ -0,0 +1,195 @@ +/*============================= + * 串的定长顺序存储表示(顺序串) + * + * 包含算法: 4.1、4.2、4.3、4.5 + ==============================*/ + +#include "SString.h" //**▲04 串**// + +/* + * 初始化 + * + * 构造一个值为chars的串T。 + * + *【注】 + * 该操作属于最小操作子集 + */ +Status StrAssign(SString T, const char* chars) { + int i, len; + + len = (int) strlen(chars); + + // chars过长 + if(len > MAXSTRLEN) { + return ERROR; + } + + T[0] = len; + for(i = 1; i <= len; i++) { + T[i] = chars[i - 1]; + } + + return OK; +} + +/* + * 清空 + * + * 将串S清空。 + */ +Status ClearString(SString S) { + // 只需要将长度置为0就可以 + S[0] = 0; + return OK; +} + +/* + * 判空 + * + * 判断串S中是否包含有效数据。 + * + * 返回值: + * TRUE : 串S为空 + * FALSE: 串S不为空 + */ +Status StrEmpty(SString S) { + return S[0] == 0 ? TRUE : FALSE; +} + +/* + * 计数 + * + * 返回串S中元素的个数。 + * + *【注】 + * 该操作属于最小操作子集 + */ +int StrLength(SString S) { + return S[0]; +} + +/* + * ████████ 算法4.3 ████████ + * + * 求子串 + * + * 用Sub返回S[pos, pos+len-1]。 + * 返回值指示是否截取成功。 + * + *【注】 + * 该操作属于最小操作子集 + */ +Status SubString(SString Sub, SString S, int pos, int len) { + int i; + + if(pos < 1 || pos > S[0] || len < 0 || pos + len - 1 > S[0]) { + return ERROR; + } + + // 复制元素 + for(i = 1; i <= len; i++) { + Sub[i] = S[pos + i - 1]; + } + + // 确定新长度 + Sub[0] = len; + + return OK; +} + +/* + * 删除 + * + * 删除S[pos, pos+len-1]。 + */ +Status StrDelete(SString S, int pos, int len) { + int i; + + if(pos < 1 || pos + len - 1 > S[0] || len < 0) { + return ERROR; + } + + // 如果待删除的长度为0,则提前返回 + if(len == 0) { + return OK; + } + + // 把后面的元素挪到前面,覆盖掉被删除的元素 + for(i = pos + len; i <= S[0]; i++) { + S[i - len] = S[i]; + } + + // 长度减少 + S[0] -= len; + + return OK; +} + +/* + * 比较 + * + * 比较串S和串T,返回比较结果。 + * + *【注】 + * 该操作属于最小操作子集 + */ +int StrCompare(SString S, SString T) { + int i = 1; + + while(i <= S[0] && i <= T[0]) { + // 遇到不同的字符时,比较其大小 + if(S[i] != T[i]) { + return S[i] - T[i]; + } + + i++; + } + + return S[0] - T[0]; +} + +/* + * 复制 + * + * 将串S复制到串T。 + */ +Status StrCopy(SString T, SString S) { + int i; + + // 连同长度信息一起复制 + for(i = 0; i <= S[0]; i++) { + T[i] = S[i]; + } + + return OK; +} + +/* + * 清理字符串S中的空白,包括清理不可打印字符和清理空格。 + * + *【注】 + * 该函数是在本章中新增的。 + */ +Status ClearBlank(SString S) { + int i, j; + + // 如果是空串 + if(S[0] == 0) { + return ERROR; + } + + for(i = 1, j = 0; i <= S[0]; i++) { + // 如果遇到空白,则略过 + if(S[i] == ' ' || !isprint(S[i])) { + continue; + } + + j++; + + S[j] = S[i]; + } + + S[0] = j; + + return OK; +} diff --git a/CLion/ExerciseBook/05.38.2/SString.h b/CLion/ExerciseBook/05.38.2/SString.h new file mode 100644 index 0000000..e81ca79 --- /dev/null +++ b/CLion/ExerciseBook/05.38.2/SString.h @@ -0,0 +1,117 @@ +/*============================= + * 串的定长顺序存储表示(顺序串) + * + * 包含算法: 4.1、4.2、4.3、4.5 + ==============================*/ + +#ifndef SSTRING_H +#define SSTRING_H + +#include +#include // 提供 strlen 原型 +#include // 提供 isprint 原型 +#include "Status.h" //**▲01 绪论**// + +/* 宏定义 */ +#define MAXSTRLEN 255 // 顺序串的最大串长 + +/* + * 串的顺序存储类型定义 + * + * 注:有效元素从SString的1号单元开始存储 + * SString的0号单元用来存储其长度 + */ +typedef unsigned char SString[MAXSTRLEN + 1]; // 0号单元存放串的长度 + + +/* + * ████ 提示 ████ + * + * 遵循教材的书写习惯,pos指示字符的位序(不是索引),从1开始计数 + */ + + +/* + * 初始化 + * + * 构造一个值为chars的串T。 + * + *【注】 + * 该操作属于最小操作子集 + */ +Status StrAssign(SString T, const char* chars); + +/* + * 清空 + * + * 将串S清空。 + */ +Status ClearString(SString S); + +/* + * 判空 + * + * 判断串S中是否包含有效数据。 + * + * 返回值: + * TRUE : 串S为空 + * FALSE: 串S不为空 + */ +Status StrEmpty(SString S); + +/* + * 计数 + * + * 返回串S中元素的个数。 + * + *【注】 + * 该操作属于最小操作子集 + */ +int StrLength(SString S); + +/* + * ████████ 算法4.3 ████████ + * + * 求子串 + * + * 用Sub返回S[pos, pos+len-1]。 + * 返回值指示是否截取成功。 + * + *【注】 + * 该操作属于最小操作子集 + */ +Status SubString(SString Sub, SString S, int pos, int len); + +/* + * 删除 + * + * 删除S[pos, pos+len-1]。 + */ +Status StrDelete(SString S, int pos, int len); + +/* + * 比较 + * + * 比较串S和串T,返回比较结果。 + * + *【注】 + * 该操作属于最小操作子集 + */ +int StrCompare(SString S, SString T); + +/* + * 复制 + * + * 将串S复制到串T。 + */ +Status StrCopy(SString T, SString S); + +/* + * 清理字符串S中的空白,包括清理不可打印字符和清理空格。 + * + *【注】 + * 该函数是在本章中新增的。 + */ +Status ClearBlank(SString S); + +#endif diff --git a/CLion/ExerciseBook/CMakeLists.txt b/CLion/ExerciseBook/CMakeLists.txt index 0d77604..ffd1980 100644 --- a/CLion/ExerciseBook/CMakeLists.txt +++ b/CLion/ExerciseBook/CMakeLists.txt @@ -67,3 +67,30 @@ add_subdirectory(04.27) add_subdirectory(04.28-04.29) add_subdirectory(04.30) add_subdirectory(04.31) + +add_subdirectory(05.17) +add_subdirectory(05.18) +add_subdirectory(05.19) +add_subdirectory(05.20) +add_subdirectory(05.21) +add_subdirectory(05.22) +add_subdirectory(05.23) +add_subdirectory(05.24) +add_subdirectory(05.25) +add_subdirectory(05.26) +add_subdirectory(05.27) +add_subdirectory(05.28-05.29) +add_subdirectory(05.30.1) +add_subdirectory(05.30.2) +add_subdirectory(05.31) +add_subdirectory(05.32.1) +add_subdirectory(05.32.2) +add_subdirectory(05.33.1) +add_subdirectory(05.33.2) +add_subdirectory(05.34.1) +add_subdirectory(05.34.2) +add_subdirectory(05.35-05.36) +add_subdirectory(05.37.1) +add_subdirectory(05.37.2) +add_subdirectory(05.38.1) +add_subdirectory(05.38.2) diff --git a/Dev-C++/ExerciseBook/05.17/05.17.cpp b/Dev-C++/ExerciseBook/05.17/05.17.cpp new file mode 100644 index 0000000..17a0f00 --- /dev/null +++ b/Dev-C++/ExerciseBook/05.17/05.17.cpp @@ -0,0 +1,137 @@ +#include +#include // ṩ systemrandsrand ԭ +#include // ṩ time ԭ +#include "SqList.h" //**02 Ա**// + +// ݹֵ +int Algo_5_17_1(SqList L, int len); + +// ݹСֵ +int Algo_5_17_2(SqList L, int len); + +// ݹ +int Algo_5_17_3(SqList L, int len); + +// ݹ +double Algo_5_17_4(SqList L, int len); + +// ݹƽ +double Algo_5_17_5(SqList L, int len); + + +int main(int argc, char* argv[]) { + SqList L; + int i; + + InitList(&L); + + srand((unsigned) time(NULL)); // ϵͳʱ + + for(i = 1; i <= 10; i++) { + ListInsert(&L, i, rand() % 100); + } + + printf("˳еΪ"); + for(i = 0; i < L.length; i++) { + printf("%d ", L.elem[i]); + } + printf("\n"); + + printf("˳еֵΪ %d \n", Algo_5_17_1(L, L.length)); + printf("˳еСֵΪ %d \n", Algo_5_17_2(L, L.length)); + printf("˳еĺΪ %d \n", Algo_5_17_3(L, L.length)); + printf("˳еĻΪ %.2f \n", Algo_5_17_4(L, L.length)); + printf("˳еƽֵΪ %.2f \n", Algo_5_17_5(L, L.length)); + + return 0; +} + + +// ݹֵ +int Algo_5_17_1(SqList L, int len) { + int value, max; + + // ȡǰλõֵ + GetElem(L, len, &value); + + if(len == 1) { + return value; + } + + // ȡǰеֵ + max = Algo_5_17_1(L, --len); + + return max > value ? max : value; +} + +// ݹСֵ +int Algo_5_17_2(SqList L, int len) { + int value, min; + + // ȡǰλõֵ + GetElem(L, len, &value); + + if(len == 1) { + return value; + } + + // ȡǰеСֵ + min = Algo_5_17_2(L, --len); + + return min < value ? min : value; +} + +// ݹ +int Algo_5_17_3(SqList L, int len) { + int sum; + + // ȡǰλõֵ + GetElem(L, len, &sum); + + if(len == 1) { + return sum; + } + + // ȡǰеĺ + sum += Algo_5_17_3(L, --len); + + return sum; +} + +// ݹ +double Algo_5_17_4(SqList L, int len) { + int value; + double mul; + + // ȡǰλõֵ + GetElem(L, len, &value); + mul = value; + + if(len == 1) { + return mul; + } + + // ȡǰеĻ + mul *= Algo_5_17_4(L, --len); + + return mul; +} + +// ݹƽ +double Algo_5_17_5(SqList L, int len) { + int value; + double avg; + + // ȡǰλõֵ + GetElem(L, len, &value); + avg = value; + + if(len == 1) { + return avg; + } + + // ȡǰеƽ + avg = (Algo_5_17_5(L, len - 1) * (len - 1) + value) / len; + + return avg; +} diff --git a/Dev-C++/ExerciseBook/05.17/05.17.dev b/Dev-C++/ExerciseBook/05.17/05.17.dev new file mode 100644 index 0000000..572566c --- /dev/null +++ b/Dev-C++/ExerciseBook/05.17/05.17.dev @@ -0,0 +1,82 @@ +[Project] +FileName=05.17.dev +Name=05.17 +Type=1 +Ver=2 +ObjFiles= +Includes= +Libs= +PrivateResource= +ResourceIncludes= +MakeIncludes= +Compiler= +CppCompiler= +Linker= +IsCpp=0 +Icon= +ExeOutput= +ObjectOutput= +LogOutput= +LogOutputEnabled=0 +OverrideOutput=0 +OverrideOutputName= +HostApplication= +UseCustomMakefile=0 +CustomMakefile= +CommandLine= +Folders= +IncludeVersionInfo=0 +SupportXPThemes=0 +CompilerSet=1 +CompilerSettings=0000000000000000001000000 +UnitCount=3 + +[VersionInfo] +Major=1 +Minor=0 +Release=0 +Build=0 +LanguageID=1033 +CharsetID=1252 +CompanyName= +FileVersion= +FileDescription=Developed using the Dev-C++ IDE +InternalName= +LegalCopyright= +LegalTrademarks= +OriginalFilename= +ProductName= +ProductVersion= +AutoIncBuildNr=0 +SyncProduct=1 + +[Unit1] +FileName=05.17.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit2] +FileName=SqList.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit3] +FileName=SqList.h +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + diff --git a/Dev-C++/ExerciseBook/05.17/SqList.cpp b/Dev-C++/ExerciseBook/05.17/SqList.cpp new file mode 100644 index 0000000..f797103 --- /dev/null +++ b/Dev-C++/ExerciseBook/05.17/SqList.cpp @@ -0,0 +1,337 @@ +/*============================= + * Ա˳洢ṹ˳ + * + * 㷨: 2.32.42.52.6 + =============================*/ + +#include "SqList.h" + +/* + * 㷨2.3 + * + * ʼ + * + * ʼɹ򷵻OK򷵻ERROR + */ +Status InitList(SqList* L) { + // ָڴ棬ʧܣ򷵻NULL + (*L).elem = (ElemType*) malloc(LIST_INIT_SIZE * sizeof(ElemType)); + if((*L).elem == NULL) { + // 洢ڴʧ + exit(OVERFLOW); + } + + (*L).length = 0; // ʼ˳Ϊ0 + (*L).listsize = LIST_INIT_SIZE; // ˳ʼڴ + + return OK; // ʼɹ +} + +/* + * (ṹ) + * + * ͷ˳ռڴ档 + */ +Status DestroyList(SqList* L) { + // ȷ˳ṹ + if(L == NULL || (*L).elem == NULL) { + return ERROR; + } + + // ͷ˳ڴ + free((*L).elem); + + // ͷڴÿָ + (*L).elem = NULL; + + // ˳ȸ + (*L).length = 0; + (*L).listsize = 0; + + return OK; +} + +/* + * ÿ() + * + * ֻ˳д洢ݣͷ˳ռڴ档 + */ +Status ClearList(SqList* L) { + // ȷ˳ṹ + if(L == NULL || (*L).elem == NULL) { + return ERROR; + } + + (*L).length = 0; + + return OK; +} + +/* + * п + * + * ж˳ǷЧݡ + * + * ֵ + * TRUE : ˳Ϊ + * FALSE: ˳Ϊ + */ +Status ListEmpty(SqList L) { + return L.length == 0 ? TRUE : FALSE; +} + +/* + * + * + * ˳ЧԪص + */ +int ListLength(SqList L) { + return L.length; +} + +/* + * ȡֵ + * + * ȡ˳еiԪأ洢eС + * ҵOK򣬷ERROR + * + *ע + * ̲iĺԪλã1ʼⲻϱͨԼ + * ͨiĺӦָ0ʼ + */ +Status GetElem(SqList L, int i, ElemType* e) { + // ΪiĺλãϷΧǣ[1, length] + if(i < 1 || i > L.length) { + return ERROR; //iֵϷ + } + + *e = L.elem[i - 1]; + + return OK; +} + +/* + * 㷨2.6 + * + * + * + * ˳׸eCompareϵԪλ + * Ԫأ򷵻0 + * + *ע + * ԪeCompareڶβ + */ +int LocateElem(SqList L, ElemType e, Status(Compare)(ElemType, ElemType)) { + int i; + ElemType* p; + + // ȷ˳ṹ + if(L.elem == NULL) { + return ERROR; + } + + /* + * iijֵΪ1Ԫصλ + * + * ʵȻдǽiʼΪ1Ԫص + * ڽ̲ǰλģдλ + */ + i = 1; + + // pijֵΪ1ԪصĴ洢λ + p = L.elem; + + // ˳ + while(i <= L.length && !Compare(*p++, e)) { + ++i; + } + + if(i <= L.length) { + return i; + } else { + return 0; + } +} + +/* + * ǰ + * + * ȡԪcur_eǰ + * ڣ洢pre_eУOK + * ڣ򷵻ERROR + */ +Status PriorElem(SqList L, ElemType cur_e, ElemType* pre_e) { + int i; + + // ȷ˳ṹڣٰԪ + if(L.elem == NULL || L.length < 2) { + return ERROR; + } + + // iʼΪ1Ԫصġ + i = 0; + + // ӵ1Ԫؿʼcur_eλ + while(i < L.length && L.elem[i] != cur_e) { + ++i; + } + + // cur_e׸Ԫ(ûǰ)ûҵԪcur_eERROR + if(i==0 || i >= L.length) { + return ERROR; + } + + // 洢cur_eǰ + *pre_e = L.elem[i - 1]; + + return OK; +} + +/* + * + * + * ȡԪcur_eḷ́ + * ڣ洢next_eУOK + * ڣ򷵻ERROR + */ +Status NextElem(SqList L, ElemType cur_e, ElemType* next_e) { + int i; + + // ȷ˳ṹڣٰԪ + if(L.elem == NULL || L.length < 2) { + return ERROR; + } + + // iʼΪ1Ԫصġ + i = 0; + + // ӵ1Ԫؿʼcur_eλ + while(i < L.length-1 && L.elem[i] != cur_e) { + ++i; + } + + // cur_e1Ԫ(ûǰ)ûҵԪcur_eERROR + if(i >= L.length-1) { + return ERROR; + } + + // 洢cur_eǰ + *next_e = L.elem[i + 1]; + + return OK; +} + +/* + * 㷨2.4 + * + * + * + * ˳iλϲeɹ򷵻OK򷵻ERROR + * + *ע + * ̲iĺԪλã1ʼ + */ +Status ListInsert(SqList* L, int i, ElemType e) { + ElemType* newbase; + ElemType* p, * q; + + // ȷ˳ṹ + if(L == NULL || (*L).elem == NULL) { + return ERROR; + } + + // iֵԽ + if(i < 1 || i > (*L).length + 1) { + return ERROR; + } + + // 洢ռ¿ռ + if((*L).length >= (*L).listsize) { + // пռ + newbase = (ElemType*) realloc((*L).elem, ((*L).listsize + LISTINCREMENT) * sizeof(ElemType)); + if(newbase == NULL) { + // 洢ڴʧ + exit(OVERFLOW); + } + + // »ַ + (*L).elem = newbase; + // Ĵ洢ռ + (*L).listsize += LISTINCREMENT; + } + + // qΪλ + q = &(*L).elem[i - 1]; + + // 1.Ԫأڳλ + for(p = &(*L).elem[(*L).length - 1]; p >= q; --p) { + *(p + 1) = *p; + } + + // 2.e + *q = e; + + // 3.1 + (*L).length++; + + return OK; +} + +/* + * 㷨2.5 + * + * ɾ + * + * ɾ˳iλϵԪأɾԪش洢eС + * ɾɹ򷵻OK򷵻ERROR + * + *ע + * ̲iĺԪλã1ʼ + */ +Status ListDelete(SqList* L, int i, ElemType* e) { + ElemType* p, * q; + + // ȷ˳ṹ + if(L == NULL || (*L).elem == NULL) { + return ERROR; + } + + // iֵԽ + if(i < 1 || i > (*L).length) { + return ERROR; + } + + // pΪɾԪصλ + p = &(*L).elem[i - 1]; + + // 1.ȡɾԪ + *e = *p; + + // βԪλ + q = (*L).elem + (*L).length - 1; + + // 2.ԪأɾԪصλϻԪؽ + for(++p; p <= q; ++p) { + *(p - 1) = *p; + } + + // 3.1 + (*L).length--; + + return OK; +} + +/* + * + * + * visit˳L + */ +void ListTraverse(SqList L, void(Visit)(ElemType)) { + int i; + + for(i = 0; i < L.length; i++) { + Visit(L.elem[i]); + } + + printf("\n"); +} diff --git a/Dev-C++/ExerciseBook/05.17/SqList.h b/Dev-C++/ExerciseBook/05.17/SqList.h new file mode 100644 index 0000000..975e5b1 --- /dev/null +++ b/Dev-C++/ExerciseBook/05.17/SqList.h @@ -0,0 +1,149 @@ +/*============================= + * Ա˳洢ṹ˳ + * + * 㷨: 2.32.42.52.6 + =============================*/ + +#ifndef SQLIST_H +#define SQLIST_H + +#include +#include // ṩmallocreallocfreeexitԭ +#include "Status.h" //**01 **// + +/* 궨 */ +#define LIST_INIT_SIZE 100 // ˳洢ռijʼ +#define LISTINCREMENT 10 // ˳洢ռķ + +/* ˳ԪͶ */ +typedef int ElemType; + +/* + * ˳ṹ + * + * עelemʹǰҪΪڴ棬Ԫشelem[0]ʼ洢 + */ +typedef struct { + ElemType* elem; // ˳洢ռĻַָ˳ռڴʼλã + int length; // ǰ˳ȣԪأ + int listsize; // ǰĴ洢Դ洢Ԫأ +} SqList; + + +/* + * 㷨2.3 + * + * ʼ + * + * ʼɹ򷵻OK򷵻ERROR + */ +Status InitList(SqList* L); + +/* + * (ṹ) + * + * ͷ˳ռڴ档 + */ +Status DestroyList(SqList* L); + +/* + * ÿ() + * + * ֻ˳д洢ݣͷ˳ռڴ档 + */ +Status ClearList(SqList* L); + +/* + * п + * + * ж˳ǷЧݡ + * + * ֵ + * TRUE : ˳Ϊ + * FALSE: ˳Ϊ + */ +Status ListEmpty(SqList L); + +/* + * + * + * ˳ЧԪص + */ +int ListLength(SqList L); + +/* + * ȡֵ + * + * ȡ˳еiԪأ洢eС + * ҵOK򣬷ERROR + * + *ע + * ̲iĺԪλã1ʼⲻϱͨԼ + * ͨiĺӦָ0ʼ + */ +Status GetElem(SqList L, int i, ElemType* e); + +/* + * 㷨2.6 + * + * + * + * ˳׸eCompareϵԪλ + * Ԫأ򷵻0 + * + *ע + * ԪeCompareڶβ + */ +int LocateElem(SqList L, ElemType e, Status(Compare)(ElemType, ElemType)); + +/* + * ǰ + * + * ȡԪcur_eǰ + * ڣ洢pre_eУOK + * ڣ򷵻ERROR + */ +Status PriorElem(SqList L, ElemType cur_e, ElemType* pre_e); + +/* + * + * + * ȡԪcur_eḷ́ + * ڣ洢next_eУOK + * ڣ򷵻ERROR + */ +Status NextElem(SqList L, ElemType cur_e, ElemType* next_e); + +/* + * 㷨2.4 + * + * + * + * ˳iλϲeɹ򷵻OK򷵻ERROR + * + *ע + * ̲iĺԪλã1ʼ + */ +Status ListInsert(SqList* L, int i, ElemType e); + +/* + * 㷨2.5 + * + * ɾ + * + * ɾ˳iλϵԪأɾԪش洢eС + * ɾɹ򷵻OK򷵻ERROR + * + *ע + * ̲iĺԪλã1ʼ + */ +Status ListDelete(SqList* L, int i, ElemType* e); + +/* + * + * + * visit˳L + */ +void ListTraverse(SqList L, void (Visit)(ElemType)); + +#endif diff --git a/Dev-C++/ExerciseBook/05.18/05.18.cpp b/Dev-C++/ExerciseBook/05.18/05.18.cpp new file mode 100644 index 0000000..2633309 --- /dev/null +++ b/Dev-C++/ExerciseBook/05.18/05.18.cpp @@ -0,0 +1,91 @@ +#include +#include // ṩ systemrandsrand ԭ +#include // ṩ time ԭ +#include "Status.h" //**01 **// +#include "Array.h" //**05 ͹**// + +/* + * AеԪѭkλ + */ +Status Algo_5_18(Array A, int k); + +// [begin, end]ΧڵԪ +static Status Reversal_5_18(Array A, int begin, int end); + + +int main(int argc, char* argv[]) { + Array A; + ElemType e; + int i; + int k = 7; // λ + + // ʼΪ10һά + InitArray(&A, 1, 10); + + srand((unsigned) time(NULL)); // ϵͳʱ + + for(i = 0; i < Length(A); i++) { + e = rand() % 100; + Assign(&A, e, i); + } + + printf("AԪΪ\n"); + for(i = 0; i < Length(A); i++) { + Value(A, &e, i); + printf("%2d ", e); + } + printf("\n"); + + printf("Aѭ %d λ\n", k); + Algo_5_18(A, k); + for(i = 0; i < Length(A); i++) { + Value(A, &e, i); + printf("%2d ", e); + } + printf("\n"); + + return 0; +} + + +/* + * AеԪѭkλ + */ +Status Algo_5_18(Array A, int k) { + int n, p; + + n = Length(A); + + p = k % n; // ʵҪѭƵλ + if(p <= 0) { + return ERROR; + } + + Reversal_5_18(A, 0, n-1); // [0, n-1]ΧڵԪ + Reversal_5_18(A, 0, p-1); // [0, p-1]ΧڵԪ + Reversal_5_18(A, p, n-1); // [p, n-1]ΧڵԪ + + return OK; +} + +// [begin, end]ΧڵԪ +static Status Reversal_5_18(Array A, int begin, int end) { + int i; + ElemType e1, e2; + + if(begin < 0 || end > Length(A)-1 || begin >= end) { + return ERROR; + } + + // "" + for(i = 0; i < (end - begin + 1) / 2; i++) { + Value(A, &e1, begin + i); // ȡеǰԪ + Value(A, &e2, end - i); // ȡеԪ + + // Ԫɽ + Assign(&A, e2, begin + i); + Assign(&A, e1, end - i); + } + + return OK; +} diff --git a/Dev-C++/ExerciseBook/05.18/05.18.dev b/Dev-C++/ExerciseBook/05.18/05.18.dev new file mode 100644 index 0000000..57dbe54 --- /dev/null +++ b/Dev-C++/ExerciseBook/05.18/05.18.dev @@ -0,0 +1,82 @@ +[Project] +FileName=05.18.dev +Name=05.18 +Type=1 +Ver=2 +ObjFiles= +Includes= +Libs= +PrivateResource= +ResourceIncludes= +MakeIncludes= +Compiler= +CppCompiler= +Linker= +IsCpp=0 +Icon= +ExeOutput= +ObjectOutput= +LogOutput= +LogOutputEnabled=0 +OverrideOutput=0 +OverrideOutputName= +HostApplication= +UseCustomMakefile=0 +CustomMakefile= +CommandLine= +Folders= +IncludeVersionInfo=0 +SupportXPThemes=0 +CompilerSet=1 +CompilerSettings=0000000000000000001000000 +UnitCount=3 + +[VersionInfo] +Major=1 +Minor=0 +Release=0 +Build=0 +LanguageID=1033 +CharsetID=1252 +CompanyName= +FileVersion= +FileDescription=Developed using the Dev-C++ IDE +InternalName= +LegalCopyright= +LegalTrademarks= +OriginalFilename= +ProductName= +ProductVersion= +AutoIncBuildNr=0 +SyncProduct=1 + +[Unit2] +FileName=Array.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit1] +FileName=05.18.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit3] +FileName=Array.h +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + diff --git a/Dev-C++/ExerciseBook/05.18/Array.cpp b/Dev-C++/ExerciseBook/05.18/Array.cpp new file mode 100644 index 0000000..494d467 --- /dev/null +++ b/Dev-C++/ExerciseBook/05.18/Array.cpp @@ -0,0 +1,195 @@ +/*======== + * ά + =========*/ + +#include "Array.h" //**05 ͹**// + +/* + * ʼ + * + * ʼάΪdim飬ɱָʾάȵĴС + */ +Status InitArray(Array* A, int dim, ...) { + int elemtotal; // ͳԪظ + va_list ap; // apſɱϢָʾάȵĴС + int i; + + if(A == NULL) { + return ERROR; + } + + if(dim < 1 || dim > MAX_ARRAY_DIM) { // ά + return ERROR; + } + + (*A).dim = dim; // ʼά + + // ʼάϢ + (*A).bounds = (int*) malloc(dim * sizeof(int)); + if((*A).bounds == NULL) { + exit(OVERFLOW); + } + + // άȳȺϷboundsAԪelemtotal + elemtotal = 1; + + // ʹapָһɱdim൱ʼʶ + va_start(ap, dim); + + for(i = 0; i < dim; i++) { + // ¼ǰάȵĿ + (*A).bounds[i] = va_arg(ap, int); + if((*A).bounds[i] <= 0) { + return ERROR; + } + + elemtotal *= A->bounds[i]; + } + + // ÿap + va_end(ap); + + // ʼռ䣬ԴԪ + (*A).base = (ElemType*) malloc(elemtotal * sizeof(ElemType)); + if((*A).base == NULL) { + exit(OVERFLOW); + } + + // ʼӳϢ + (*A).constants = (int*) malloc(dim * sizeof(int)); + if((*A).constants == NULL) { + exit(OVERFLOW); + } + + // һάȣÿҪԽһԪ + (*A).constants[dim - 1] = 1; + for(i = dim - 2; i >= 0; i--) { + (*A).constants[i] = (*A).bounds[i + 1] * (*A).constants[i + 1]; + } + + /* + * + * ά[2,3,4]˵boundsֵΪ<2,3,4>constantsֵΪ<12,4,1> + * boundsһάа2Ԫأڶάа3Ԫأάа4Ԫ + * constantsһάÿҪ12ԪأڶάÿҪԽ4ԪأάÿҪԽ1Ԫ + */ + + return OK; +} + +/* + * (ṹ) + * + * ռõĿռ䡣 + */ +Status DestroyArray(Array* A) { + if(A == NULL || (*A).base == NULL || (*A).bounds == NULL || (*A).constants == NULL) { + return ERROR; + } + + free((*A).base); + (*A).base = NULL; + + free((*A).bounds); + (*A).bounds = NULL; + + free((*A).constants); + (*A).constants = NULL; + + (*A).dim = 0; + + return OK; +} + +/* + * ȡֵ + * + * ȡָ±괦ԪֵɱΪdim±ֵָʾȡԪ±ꡣ + */ +Status Value(Array A, ElemType* e, ...) { + va_list ap; + Status result; + int off; + + va_start(ap, e); + + // ԪصĿԪҪԽԪ + result = Locate(A, ap, &off); + + va_end(ap); + + if(result == OVERFLOW) { + return result; + } + + *e = *(A.base + off); + + return OK; +} + +/* + * ֵ + * + * Ϊָ±괦ԪظֵɱΪdim±ֵָʾֵԪ±ꡣ + */ +Status Assign(Array* A, ElemType e, ...) { + va_list ap; + Status result; + int off; + + va_start(ap, e); + + // ԪصĿԪҪԽԪ + result = Locate(*A, ap, &off); + + va_end(ap); + + if(result == OVERFLOW) { + return result; + } + + *(A->base + off) = e; + + return OK; +} + +/* + * apָʾֵAеλã + * ԪصĿԪҪԽԪ + */ +static Status Locate(Array A, va_list ap, int* off) { + int i, ind; + + *off = 0; + + for(i = 0; i < A.dim; i++) { + ind = va_arg(ap, int); + + // ֤±겻Խ + if(ind < 0 || ind >= A.bounds[i]) { + return OVERFLOW; + } + + // ijάȵĵλԪظ*Ҫĵλ + *off += A.constants[i] * ind; + } + + return OK; +} + +/* + * Ԫصĸ + * + *ע + * Ϊĺ + */ +int Length(Array A) { + int i; + int elemtotal = 1; + + for(i = 0; i < A.dim; i++) { + elemtotal *= A.bounds[i]; + } + + return elemtotal; +} diff --git a/Dev-C++/ExerciseBook/05.18/Array.h b/Dev-C++/ExerciseBook/05.18/Array.h new file mode 100644 index 0000000..bae6fab --- /dev/null +++ b/Dev-C++/ExerciseBook/05.18/Array.h @@ -0,0 +1,70 @@ +/*======== + * ά + =========*/ + +#ifndef ARRAY_H +#define ARRAY_H + +#include +#include // ṩmallocreallocfreeexitԭ +#include // ṩva_startva_argva_end +#include "Status.h" //**01 **// + +/* 궨 */ +#define MAX_ARRAY_DIM 8 // άΪ8 + +/* Ԫ */ +typedef int ElemType; + +/* ˳洢ʾ */ +typedef struct { + ElemType* base; // ԪػַԪأ + int dim; // ά + int* bounds; // άַСϢ + int* constants; // ӳַ洢ijάʱÿҪԽԪظ +} Array; + + +/* + * ʼ + * + * ʼάΪdim飬ɱָʾάȵĴС + */ +Status InitArray(Array* A, int dim, ...); + +/* + * (ṹ) + * + * ռõĿռ䡣 + */ +Status DestroyArray(Array* A); + +/* + * ȡֵ + * + * ȡָ±괦ԪֵɱΪdim±ֵָʾȡԪ±ꡣ + */ +Status Value(Array A, ElemType* e, ...); + +/* + * ֵ + * + * Ϊָ±괦ԪظֵɱΪdim±ֵָʾֵԪ±ꡣ + */ +Status Assign(Array* A, ElemType e, ...); + +/* + * apָʾֵAеλã + * ԪصĿԪҪԽԪ + */ +static Status Locate(Array A, va_list ap, int *off); + +/* + * Ԫصĸ + * + *ע + * Ϊĺ + */ +int Length(Array A); + +#endif diff --git a/Dev-C++/ExerciseBook/05.19/05.19.cpp b/Dev-C++/ExerciseBook/05.19/05.19.cpp new file mode 100644 index 0000000..c5f3ccb --- /dev/null +++ b/Dev-C++/ExerciseBook/05.19/05.19.cpp @@ -0,0 +1,114 @@ +#include +#include +#include +#include "Array.h" //**05 ͹**// + +/* Ԫ */ +typedef struct { + int x; + int y; + ElemType value; +} Elem; + +/* + * ѰҶάAе + * + *ע + * ÿÿеԪزΨһ + */ +void Algo_5_19(Array A); + + +int main(int argc, char* argv[]) { + int a[3][4] = { + {10, 16, 13, 14}, + {15, 18, 15, 20}, + { 5, 8, 12, 32} + }; + int i, j; + Array A; + + // ׼ + InitArray(&A, 2, 3, 4); + for(i = 0; i < 3; i++) { + for(j = 0; j < 4; j++) { + Assign(&A, a[i][j], i, j); + } + } + + // Ѱ + Algo_5_19(A); + + return 0; +} + + +/* + * ѰҶάAе + * + *ע + * ÿÿеԪزΨһ + */ +void Algo_5_19(Array A) { + int row, col; // + Elem* Min; // 洢AÿеСֵϢ + ElemType* Max; // 洢Aÿеֵֻ洢ֵ + int total, k; // total¼Minд洢Ԫ + int i, j; + ElemType e; + int count; + int min; + + row = A.bounds[0]; + col = A.bounds[1]; + + Min = (Elem*) malloc(row * col * sizeof(Elem)); + + Max = (ElemType*) malloc(col * sizeof(ElemType)); + // ʼֵ + for(j = 0; j < col; j++) { + Max[j] = INT_MIN; + } + + total = 0; + + for(i = 0; i < row; i++) { + min = INT_MAX; // ǰСֵ + + for(j = 0; j < col; j++) { + // ȡԪA[i][j] + Value(A, &e, i, j); + + // ¼ֵ + if(e > Max[j]) { + Max[j] = e; + } + + // ¼СֵϢ + if(e <= min) { + // ÿηָСģkҪ + if(e < min) { + k = total; // ͳƵǰеСֵԪ + min = e; + } + + Min[k].x = i; + Min[k].y = j; + Min[k].value = e; + + k++; + } + } + + // ۼӱԪ + total += (k - total); + } + + count = 0; + for(k = 0; k < total; k++) { + // ǰСֵеֵ뵱ǰСֵһ£ + if(Max[Min[k].y] == Min[k].value) { + printf(" %2d λ (%2d, %2d) %d\n", ++count, Min[k].x, Min[k].y, Min[k].value); + } + } +} diff --git a/Dev-C++/ExerciseBook/05.19/05.19.dev b/Dev-C++/ExerciseBook/05.19/05.19.dev new file mode 100644 index 0000000..17db02a --- /dev/null +++ b/Dev-C++/ExerciseBook/05.19/05.19.dev @@ -0,0 +1,82 @@ +[Project] +FileName=05.19.dev +Name=05.19 +Type=1 +Ver=2 +ObjFiles= +Includes= +Libs= +PrivateResource= +ResourceIncludes= +MakeIncludes= +Compiler= +CppCompiler= +Linker= +IsCpp=0 +Icon= +ExeOutput= +ObjectOutput= +LogOutput= +LogOutputEnabled=0 +OverrideOutput=0 +OverrideOutputName= +HostApplication= +UseCustomMakefile=0 +CustomMakefile= +CommandLine= +Folders= +IncludeVersionInfo=0 +SupportXPThemes=0 +CompilerSet=1 +CompilerSettings=0000000000000000001000000 +UnitCount=3 + +[VersionInfo] +Major=1 +Minor=0 +Release=0 +Build=0 +LanguageID=1033 +CharsetID=1252 +CompanyName= +FileVersion= +FileDescription=Developed using the Dev-C++ IDE +InternalName= +LegalCopyright= +LegalTrademarks= +OriginalFilename= +ProductName= +ProductVersion= +AutoIncBuildNr=0 +SyncProduct=1 + +[Unit1] +FileName=05.19.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit2] +FileName=Array.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit3] +FileName=Array.h +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + diff --git a/Dev-C++/ExerciseBook/05.19/Array.cpp b/Dev-C++/ExerciseBook/05.19/Array.cpp new file mode 100644 index 0000000..e81eac3 --- /dev/null +++ b/Dev-C++/ExerciseBook/05.19/Array.cpp @@ -0,0 +1,178 @@ +/*======== + * ά + =========*/ + +#include "Array.h" //**05 ͹**// + +/* + * ʼ + * + * ʼάΪdim飬ɱָʾάȵĴС + */ +Status InitArray(Array* A, int dim, ...) { + int elemtotal; // ͳԪظ + va_list ap; // apſɱϢָʾάȵĴС + int i; + + if(A == NULL) { + return ERROR; + } + + if(dim < 1 || dim > MAX_ARRAY_DIM) { // ά + return ERROR; + } + + (*A).dim = dim; // ʼά + + // ʼάϢ + (*A).bounds = (int*) malloc(dim * sizeof(int)); + if((*A).bounds == NULL) { + exit(OVERFLOW); + } + + // άȳȺϷboundsAԪelemtotal + elemtotal = 1; + + // ʹapָһɱdim൱ʼʶ + va_start(ap, dim); + + for(i = 0; i < dim; i++) { + // ¼ǰάȵĿ + (*A).bounds[i] = va_arg(ap, int); + if((*A).bounds[i] <= 0) { + return ERROR; + } + + elemtotal *= A->bounds[i]; + } + + // ÿap + va_end(ap); + + // ʼռ䣬ԴԪ + (*A).base = (ElemType*) malloc(elemtotal * sizeof(ElemType)); + if((*A).base == NULL) { + exit(OVERFLOW); + } + + // ʼӳϢ + (*A).constants = (int*) malloc(dim * sizeof(int)); + if((*A).constants == NULL) { + exit(OVERFLOW); + } + + // һάȣÿҪԽһԪ + (*A).constants[dim - 1] = 1; + for(i = dim - 2; i >= 0; i--) { + (*A).constants[i] = (*A).bounds[i + 1] * (*A).constants[i + 1]; + } + + /* + * + * ά[2,3,4]˵boundsֵΪ<2,3,4>constantsֵΪ<12,4,1> + * boundsһάа2Ԫأڶάа3Ԫأάа4Ԫ + * constantsһάÿҪ12ԪأڶάÿҪԽ4ԪأάÿҪԽ1Ԫ + */ + + return OK; +} + +/* + * (ṹ) + * + * ռõĿռ䡣 + */ +Status DestroyArray(Array* A) { + if(A == NULL || (*A).base == NULL || (*A).bounds == NULL || (*A).constants == NULL) { + return ERROR; + } + + free((*A).base); + (*A).base = NULL; + + free((*A).bounds); + (*A).bounds = NULL; + + free((*A).constants); + (*A).constants = NULL; + + (*A).dim = 0; + + return OK; +} + +/* + * ȡֵ + * + * ȡָ±괦ԪֵɱΪdim±ֵָʾȡԪ±ꡣ + */ +Status Value(Array A, ElemType* e, ...) { + va_list ap; + Status result; + int off; + + va_start(ap, e); + + // ԪصĿԪҪԽԪ + result = Locate(A, ap, &off); + + va_end(ap); + + if(result == OVERFLOW) { + return result; + } + + *e = *(A.base + off); + + return OK; +} + +/* + * ֵ + * + * Ϊָ±괦ԪظֵɱΪdim±ֵָʾֵԪ±ꡣ + */ +Status Assign(Array* A, ElemType e, ...) { + va_list ap; + Status result; + int off; + + va_start(ap, e); + + // ԪصĿԪҪԽԪ + result = Locate(*A, ap, &off); + + va_end(ap); + + if(result == OVERFLOW) { + return result; + } + + *(A->base + off) = e; + + return OK; +} + +/* + * apָʾֵAеλã + * ԪصĿԪҪԽԪ + */ +static Status Locate(Array A, va_list ap, int* off) { + int i, ind; + + *off = 0; + + for(i = 0; i < A.dim; i++) { + ind = va_arg(ap, int); + + // ֤±겻Խ + if(ind < 0 || ind >= A.bounds[i]) { + return OVERFLOW; + } + + // ijάȵĵλԪظ*Ҫĵλ + *off += A.constants[i] * ind; + } + + return OK; +} diff --git a/Dev-C++/ExerciseBook/05.19/Array.h b/Dev-C++/ExerciseBook/05.19/Array.h new file mode 100644 index 0000000..31dd29f --- /dev/null +++ b/Dev-C++/ExerciseBook/05.19/Array.h @@ -0,0 +1,62 @@ +/*======== + * ά + =========*/ + +#ifndef ARRAY_H +#define ARRAY_H + +#include +#include // ṩmallocreallocfreeexitԭ +#include // ṩva_startva_argva_end +#include "Status.h" //**01 **// + +/* 궨 */ +#define MAX_ARRAY_DIM 8 // άΪ8 + +/* Ԫ */ +typedef int ElemType; + +/* ˳洢ʾ */ +typedef struct { + ElemType* base; // ԪػַԪأ + int dim; // ά + int* bounds; // άַСϢ + int* constants; // ӳַ洢ijάʱÿҪԽԪظ +} Array; + + +/* + * ʼ + * + * ʼάΪdim飬ɱָʾάȵĴС + */ +Status InitArray(Array* A, int dim, ...); + +/* + * (ṹ) + * + * ռõĿռ䡣 + */ +Status DestroyArray(Array* A); + +/* + * ȡֵ + * + * ȡָ±괦ԪֵɱΪdim±ֵָʾȡԪ±ꡣ + */ +Status Value(Array A, ElemType* e, ...); + +/* + * ֵ + * + * Ϊָ±괦ԪظֵɱΪdim±ֵָʾֵԪ±ꡣ + */ +Status Assign(Array* A, ElemType e, ...); + +/* + * apָʾֵAеλã + * ԪصĿԪҪԽԪ + */ +static Status Locate(Array A, va_list ap, int *off); + +#endif diff --git a/Dev-C++/ExerciseBook/05.20/05.20.cpp b/Dev-C++/ExerciseBook/05.20/05.20.cpp new file mode 100644 index 0000000..4246091 --- /dev/null +++ b/Dev-C++/ExerciseBook/05.20/05.20.cpp @@ -0,0 +1,112 @@ +#include +#include // ṩ systemrandsrand ԭ +#include // ṩ time ԭ +#include "Array.h" //**05 ͹**// + +// ݶʽϵʽ +void Algo_5_20(Array A); + +// ڲʵ +static void Print(Array A, int dim, int index[]); + + +int main(int argc, char* argv[]) { + Array A; + int i, j, k; + ElemType e = 0; + + // ʼһάΪ<2,3,4>ά + InitArray(&A, 3, 2, 3, 4); + + srand((unsigned) time(NULL)); // ϵͳʱ + + // ׼ + for(i = 0; i < A.bounds[0]; i++) { + for(j = 0; j < A.bounds[1]; j++) { + for(k = 0; k < A.bounds[2]; k++) { + e = rand() % 50 - 25; // + Assign(&A, e, i, j, k); + } + } + } + + // ʽ + Algo_5_20(A); + + return 0; +} + + +// ݶʽϵʽ +void Algo_5_20(Array A) { + int i; + int* index; + + // ڱԪʱ¼ÿԪصֻ¼ǰdim-1ά + index = (int*) malloc((A.dim - 1) * sizeof(int)); + for(i = 0; i < A.dim - 1; i++) { + index[i] = -1; + } + + Print(A, 1, index); + + printf("\n"); +} + +// ڲʵ +static void Print(Array A, int dim, int index[]) { + int i, j; + int start; + ElemType coef; + + if(dim == A.dim) { + start = 0; + + // 㱾αʼԪλ + for(i = 0; i < dim - 1; i++) { + start += index[i] * A.constants[i]; + } + + // һάڵԪ + for(i = 0; i < A.bounds[dim - 1]; i++) { + // ȡϵ + coef = A.base[start + i]; + + // ϵΪ0 + if(coef == 0) { + continue; + } + + if(coef < 0) { + printf(" - "); + } else { + printf(" + "); + } + + // ϵľֵΪ1ʱϵ + if(abs(coef) != 1) { + // ϵţǰѾţһҲŷ + printf("%d", abs(coef)); + } + + /* + * ʽÿһδ֪abc... + * + *ע + * ָλ0ָλ1ΣȻӡ + * ѡ񲻴ӡЩ + */ + for(j = 0; j < dim - 1; j++) { + printf("%c^%d", 'a' + j, index[j]); + } + printf("%c^%d", 'a' + j, i); + } + } else { + for(i = 0; i < A.bounds[dim - 1]; i++) { + // ת + index[dim - 1] = (index[dim - 1] + 1 + A.bounds[dim - 1]) % A.bounds[dim - 1]; + + Print(A, dim + 1, index); + } + } +} diff --git a/Dev-C++/ExerciseBook/05.20/05.20.dev b/Dev-C++/ExerciseBook/05.20/05.20.dev new file mode 100644 index 0000000..41c6f86 --- /dev/null +++ b/Dev-C++/ExerciseBook/05.20/05.20.dev @@ -0,0 +1,82 @@ +[Project] +FileName=05.20.dev +Name=05.20 +Type=1 +Ver=2 +ObjFiles= +Includes= +Libs= +PrivateResource= +ResourceIncludes= +MakeIncludes= +Compiler= +CppCompiler= +Linker= +IsCpp=0 +Icon= +ExeOutput= +ObjectOutput= +LogOutput= +LogOutputEnabled=0 +OverrideOutput=0 +OverrideOutputName= +HostApplication= +UseCustomMakefile=0 +CustomMakefile= +CommandLine= +Folders= +IncludeVersionInfo=0 +SupportXPThemes=0 +CompilerSet=1 +CompilerSettings=0000000000000000001000000 +UnitCount=3 + +[VersionInfo] +Major=1 +Minor=0 +Release=0 +Build=0 +LanguageID=1033 +CharsetID=1252 +CompanyName= +FileVersion= +FileDescription=Developed using the Dev-C++ IDE +InternalName= +LegalCopyright= +LegalTrademarks= +OriginalFilename= +ProductName= +ProductVersion= +AutoIncBuildNr=0 +SyncProduct=1 + +[Unit1] +FileName=05.20.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit2] +FileName=Array.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit3] +FileName=Array.h +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + diff --git a/Dev-C++/ExerciseBook/05.20/Array.cpp b/Dev-C++/ExerciseBook/05.20/Array.cpp new file mode 100644 index 0000000..e81eac3 --- /dev/null +++ b/Dev-C++/ExerciseBook/05.20/Array.cpp @@ -0,0 +1,178 @@ +/*======== + * ά + =========*/ + +#include "Array.h" //**05 ͹**// + +/* + * ʼ + * + * ʼάΪdim飬ɱָʾάȵĴС + */ +Status InitArray(Array* A, int dim, ...) { + int elemtotal; // ͳԪظ + va_list ap; // apſɱϢָʾάȵĴС + int i; + + if(A == NULL) { + return ERROR; + } + + if(dim < 1 || dim > MAX_ARRAY_DIM) { // ά + return ERROR; + } + + (*A).dim = dim; // ʼά + + // ʼάϢ + (*A).bounds = (int*) malloc(dim * sizeof(int)); + if((*A).bounds == NULL) { + exit(OVERFLOW); + } + + // άȳȺϷboundsAԪelemtotal + elemtotal = 1; + + // ʹapָһɱdim൱ʼʶ + va_start(ap, dim); + + for(i = 0; i < dim; i++) { + // ¼ǰάȵĿ + (*A).bounds[i] = va_arg(ap, int); + if((*A).bounds[i] <= 0) { + return ERROR; + } + + elemtotal *= A->bounds[i]; + } + + // ÿap + va_end(ap); + + // ʼռ䣬ԴԪ + (*A).base = (ElemType*) malloc(elemtotal * sizeof(ElemType)); + if((*A).base == NULL) { + exit(OVERFLOW); + } + + // ʼӳϢ + (*A).constants = (int*) malloc(dim * sizeof(int)); + if((*A).constants == NULL) { + exit(OVERFLOW); + } + + // һάȣÿҪԽһԪ + (*A).constants[dim - 1] = 1; + for(i = dim - 2; i >= 0; i--) { + (*A).constants[i] = (*A).bounds[i + 1] * (*A).constants[i + 1]; + } + + /* + * + * ά[2,3,4]˵boundsֵΪ<2,3,4>constantsֵΪ<12,4,1> + * boundsһάа2Ԫأڶάа3Ԫأάа4Ԫ + * constantsһάÿҪ12ԪأڶάÿҪԽ4ԪأάÿҪԽ1Ԫ + */ + + return OK; +} + +/* + * (ṹ) + * + * ռõĿռ䡣 + */ +Status DestroyArray(Array* A) { + if(A == NULL || (*A).base == NULL || (*A).bounds == NULL || (*A).constants == NULL) { + return ERROR; + } + + free((*A).base); + (*A).base = NULL; + + free((*A).bounds); + (*A).bounds = NULL; + + free((*A).constants); + (*A).constants = NULL; + + (*A).dim = 0; + + return OK; +} + +/* + * ȡֵ + * + * ȡָ±괦ԪֵɱΪdim±ֵָʾȡԪ±ꡣ + */ +Status Value(Array A, ElemType* e, ...) { + va_list ap; + Status result; + int off; + + va_start(ap, e); + + // ԪصĿԪҪԽԪ + result = Locate(A, ap, &off); + + va_end(ap); + + if(result == OVERFLOW) { + return result; + } + + *e = *(A.base + off); + + return OK; +} + +/* + * ֵ + * + * Ϊָ±괦ԪظֵɱΪdim±ֵָʾֵԪ±ꡣ + */ +Status Assign(Array* A, ElemType e, ...) { + va_list ap; + Status result; + int off; + + va_start(ap, e); + + // ԪصĿԪҪԽԪ + result = Locate(*A, ap, &off); + + va_end(ap); + + if(result == OVERFLOW) { + return result; + } + + *(A->base + off) = e; + + return OK; +} + +/* + * apָʾֵAеλã + * ԪصĿԪҪԽԪ + */ +static Status Locate(Array A, va_list ap, int* off) { + int i, ind; + + *off = 0; + + for(i = 0; i < A.dim; i++) { + ind = va_arg(ap, int); + + // ֤±겻Խ + if(ind < 0 || ind >= A.bounds[i]) { + return OVERFLOW; + } + + // ijάȵĵλԪظ*Ҫĵλ + *off += A.constants[i] * ind; + } + + return OK; +} diff --git a/Dev-C++/ExerciseBook/05.20/Array.h b/Dev-C++/ExerciseBook/05.20/Array.h new file mode 100644 index 0000000..31dd29f --- /dev/null +++ b/Dev-C++/ExerciseBook/05.20/Array.h @@ -0,0 +1,62 @@ +/*======== + * ά + =========*/ + +#ifndef ARRAY_H +#define ARRAY_H + +#include +#include // ṩmallocreallocfreeexitԭ +#include // ṩva_startva_argva_end +#include "Status.h" //**01 **// + +/* 궨 */ +#define MAX_ARRAY_DIM 8 // άΪ8 + +/* Ԫ */ +typedef int ElemType; + +/* ˳洢ʾ */ +typedef struct { + ElemType* base; // ԪػַԪأ + int dim; // ά + int* bounds; // άַСϢ + int* constants; // ӳַ洢ijάʱÿҪԽԪظ +} Array; + + +/* + * ʼ + * + * ʼάΪdim飬ɱָʾάȵĴС + */ +Status InitArray(Array* A, int dim, ...); + +/* + * (ṹ) + * + * ռõĿռ䡣 + */ +Status DestroyArray(Array* A); + +/* + * ȡֵ + * + * ȡָ±괦ԪֵɱΪdim±ֵָʾȡԪ±ꡣ + */ +Status Value(Array A, ElemType* e, ...); + +/* + * ֵ + * + * Ϊָ±괦ԪظֵɱΪdim±ֵָʾֵԪ±ꡣ + */ +Status Assign(Array* A, ElemType e, ...); + +/* + * apָʾֵAеλã + * ԪصĿԪҪԽԪ + */ +static Status Locate(Array A, va_list ap, int *off); + +#endif diff --git a/Dev-C++/ExerciseBook/05.21/05.21.cpp b/Dev-C++/ExerciseBook/05.21/05.21.cpp new file mode 100644 index 0000000..c6f0b54 --- /dev/null +++ b/Dev-C++/ExerciseBook/05.21/05.21.cpp @@ -0,0 +1,43 @@ +#include +#include "Status.h" //**01 **// +#include "TSMatrix.h" //**05 ͹**// + +/* + * ϡӷAddSMatrix + * + *ע + * úTSMatrixļж + */ +Status Algo_5_21(TSMatrix A, TSMatrix B, TSMatrix* C); + + +int main(int argc, char* argv[]) { + TSMatrix A, B, C; + + printf(" ϡ AB ...\n"); + CreateSMatrix(&A, "TestData_A.txt"); + CreateSMatrix(&B, "TestData_B.txt"); + printf(" A = \n"); + PrintSMatrix(A); + printf(" B = \n"); + PrintSMatrix(B); + + // + Algo_5_21(A, B, &C); + + printf(" C = A + B = \n"); + PrintSMatrix(C); + + return 0; +} + + +/* + * ϡӷAddSMatrix + * + *ע + * úTSMatrixļж + */ +Status Algo_5_21(TSMatrix A, TSMatrix B, TSMatrix* C) { + return AddSMatrix(A, B, C); +} diff --git a/Dev-C++/ExerciseBook/05.21/05.21.dev b/Dev-C++/ExerciseBook/05.21/05.21.dev new file mode 100644 index 0000000..d5cb312 --- /dev/null +++ b/Dev-C++/ExerciseBook/05.21/05.21.dev @@ -0,0 +1,100 @@ +[Project] +FileName=05.21.dev +Name=05.21 +Type=1 +Ver=2 +ObjFiles= +Includes= +Libs= +PrivateResource= +ResourceIncludes= +MakeIncludes= +Compiler= +CppCompiler= +Linker= +IsCpp=0 +Icon= +ExeOutput= +ObjectOutput= +LogOutput= +LogOutputEnabled=0 +OverrideOutput=0 +OverrideOutputName= +HostApplication= +UseCustomMakefile=0 +CustomMakefile= +CommandLine= +Folders= +IncludeVersionInfo=0 +SupportXPThemes=0 +CompilerSet=1 +CompilerSettings=0000000000000000001000000 +UnitCount=5 + +[VersionInfo] +Major=1 +Minor=0 +Release=0 +Build=0 +LanguageID=1033 +CharsetID=1252 +CompanyName= +FileVersion= +FileDescription=Developed using the Dev-C++ IDE +InternalName= +LegalCopyright= +LegalTrademarks= +OriginalFilename= +ProductName= +ProductVersion= +AutoIncBuildNr=0 +SyncProduct=1 + +[Unit4] +FileName=TSMatrix.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit1] +FileName=05.21.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit2] +FileName=TestData_A.txt +Folder= +Compile=0 +Link=0 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit3] +FileName=TestData_B.txt +Folder= +Compile=0 +Link=0 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit5] +FileName=TSMatrix.h +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + diff --git a/Dev-C++/ExerciseBook/05.21/TSMatrix.cpp b/Dev-C++/ExerciseBook/05.21/TSMatrix.cpp new file mode 100644 index 0000000..05eeaad --- /dev/null +++ b/Dev-C++/ExerciseBook/05.21/TSMatrix.cpp @@ -0,0 +1,433 @@ +/*======================= + * Ԫ˳ϡ + * + * 㷨: 5.15.2 + ========================*/ + +#include "TSMatrix.h" //**05 ͹**// + +/* + * ϡM + * + * + *ע + * + * ̲Ĭϴӿ̨ȡݡ + * Ϊ˷ԣÿжֶݣ + * ѡԤļpathжȡݡ + * + * Ҫӿ̨ȡݣpathΪNULLΪմ + * ҪļжȡݣҪpathдļϢ + */ +Status CreateSMatrix(TSMatrix* M, char* path) { + int k; + FILE* fp; + int readFromConsole; // Ƿӿ̨ȡ + + // ûļ·Ϣӿ̨ȡ + readFromConsole = path == NULL || strcmp(path, "") == 0; + + // ûļ·Ϣӿ̨ȡ + if(readFromConsole) { + printf(""); + scanf("%d", &((*M).mu)); + printf(""); + scanf("%d", &((*M).nu)); + printf("Ԫظ"); + scanf("%d", &((*M).tu)); + printf("%dԪϢ\n", (*M).tu); + for(k = 1; k <= (*M).tu; k++) { + printf("%2d飺", k); + scanf("%d%d%d", &((*M).data[k].i), &((*M).data[k].j), &((*M).data[k].e)); + } + } else { + fp = fopen(path, "r"); + + ReadData(fp, "%d%d%d", &((*M).mu), &((*M).nu), &((*M).tu)); + + for(k = 1; k <= (*M).tu; k++) { + ReadData(fp, "%d%d%d", &((*M).data[k].i), &((*M).data[k].j), &((*M).data[k].e)); + } + + fclose(fp); + } + + return OK; +} + +/* + * ϡ + * + *ע + * Ԫ˳Ľṹ޷١ + */ +Status DestroySMatrix(TSMatrix* M) { + if(M == NULL) { + return ERROR; + } + + (*M).mu = 0; + (*M).nu = 0; + (*M).tu = 0; + + return OK; +} + +/* + * + * + * һ¾Tþ˴ӾMаݡ + */ +Status CopySMatrix(TSMatrix M, TSMatrix* T) { + (*T) = M; // ṹֱ֮ӸƣʹڲҲ + + return OK; +} + +/* + * ӷ + * + * Q = M + N + */ +Status AddSMatrix(TSMatrix M, TSMatrix N, TSMatrix* Q) { + int m, n, k; + + if(M.mu != N.mu || M.nu != N.nu) { + printf("\n"); + return ERROR; + } + + // ʼQ + (*Q).mu = M.mu; + (*Q).nu = M.nu; + (*Q).tu = 0; + + m = n = k = 1; + + // αMNԪ + while(m <= M.tu && n <= N.tu) { + // MеԪ±С + if(M.data[m].i < N.data[n].i) { + (*Q).data[k] = M.data[m]; + m++; + + // NеԪ±С + } else if(M.data[m].i > N.data[n].i) { + (*Q).data[k] = N.data[n]; + n++; + + // MNеԪ±һ£ҪһȽ + } else { + // MеԪ±С + if(M.data[m].j < N.data[n].j) { + (*Q).data[k] = M.data[m]; + m++; + + // NеԪ±С + } else if(M.data[m].j > N.data[n].j) { + (*Q).data[k] = N.data[n]; + n++; + + // MNеԪ±һ£Ҫмӷ + } else { + // ֵѾΪ0ĻҪ洢Ԫ + if((M.data[m].e + N.data[n].e) == 0) { + m++; + n++; + continue; + } else { + (*Q).data[k].i = M.data[m].i; + (*Q).data[k].j = M.data[m].j; + (*Q).data[k].e = M.data[m].e + N.data[n].e; + m++; + n++; + } + } + } + + k++; + (*Q).tu++; + } + + // MʣԪ + while(m <= M.tu) { + (*Q).data[k] = M.data[m]; + m++; + k++; + (*Q).tu++; + } + + // NʣԪ + while(n <= N.tu) { + (*Q).data[k] = N.data[n]; + n++; + k++; + (*Q).tu++; + } + + return OK; +} + +/* + * + * + * Q = M - N + */ +Status SubSMatrix(TSMatrix M, TSMatrix N, TSMatrix* Q) { + int m, n, k; + + if(M.mu != N.mu || M.nu != N.nu) { + printf("\n"); + return ERROR; + } + + // ʼQ + (*Q).mu = M.mu; + (*Q).nu = M.nu; + (*Q).tu = 0; + + m = n = k = 1; + + // αMNԪ + while(m <= M.tu && n <= N.tu) { + // MеԪ±С + if(M.data[m].i < N.data[n].i) { + (*Q).data[k] = M.data[m]; + m++; + + // NеԪ±С + } else if(M.data[m].i > N.data[n].i) { + (*Q).data[k].i = N.data[n].i; + (*Q).data[k].j = N.data[n].j; + (*Q).data[k].e = -N.data[n].e; // ҪԪֵȡ෴ + n++; + + // MNеԪ±һ£ҪһȽ + } else { + // MеԪ±С + if(M.data[m].j < N.data[n].j) { + (*Q).data[k] = M.data[m]; + m++; + + // NеԪ±С + } else if(M.data[m].j > N.data[n].j) { + (*Q).data[k].i = N.data[n].i; + (*Q).data[k].j = N.data[n].j; + (*Q).data[k].e = -N.data[n].e; // ҪԪֵȡ෴ + n++; + + // MNеԪ±һ£Ҫм + } else { + // ֵѾΪ0ĻҪ洢Ԫ + if((M.data[m].e - N.data[n].e) == 0) { + m++; + n++; + continue; + } else { + (*Q).data[k].i = M.data[m].i; + (*Q).data[k].j = M.data[m].j; + (*Q).data[k].e = M.data[m].e - N.data[n].e; + m++; + n++; + } + } + } + + k++; + (*Q).tu++; + } + + // MʣԪ + while(m <= M.tu) { + (*Q).data[k] = M.data[m]; + m++; + k++; + (*Q).tu++; + } + + // NʣԪ + while(n <= N.tu) { + (*Q).data[k].i = N.data[n].i; + (*Q).data[k].j = N.data[n].j; + (*Q).data[k].e = -N.data[n].e; + n++; + k++; + (*Q).tu++; + } + + return OK; +} + +/* + * ˷ + * + * Q = M * NʵֵǴͳ˷ + */ +Status MultSMatrix(TSMatrix M, TSMatrix N, TSMatrix* Q) { + int m, n, i, j, k; + ElemType c, c1, c2; + + // MҪN + if(M.nu != N.mu) { + printf("\n"); + return ERROR; + } + + // ʼQ + (*Q).mu = M.mu; + (*Q).nu = N.nu; + (*Q).tu = 0; + + // + if(M.tu * N.tu == 0) { + return OK; + } + + // M + for(i = 1; i <= M.mu; i++) { + // N + for(j = 1; j <= N.nu; j++) { + c = 0; + for(k = 1; k <= M.nu; k++) { + // ¼M[i][k]ֵ + c1 = 0; + // ѰλָλõMԪ + for(m = 1; m <= M.tu; m++) { + if(M.data[m].i == i && M.data[m].j == k) { + c1 = M.data[m].e; + break; + } + } + + // ¼N[k][j]ֵ + c2 = 0; + //ѰλָλõNԪ + for(n = 1; n <= N.tu; n++) { + if(N.data[n].i == k && N.data[n].j == j) { + c2 = N.data[n].e; + break; + } + } + + // Q[i][j]ֵ + if(c1 && c2) { + c += c1 * c2; + } + } + + // Ϊ0д洢 + if(c != 0) { + (*Q).tu++; + (*Q).data[(*Q).tu].i = i; + (*Q).data[(*Q).tu].j = j; + (*Q).data[(*Q).tu].e = c; + } + } + } + + return OK; +} + +/* + * 㷨5.1 + * + * ת + */ +Status TransposeSMatrix(TSMatrix M, TSMatrix* T) { + int p, q, col; + + (*T).mu = M.nu; + (*T).nu = M.mu; + (*T).tu = M.tu; + + if((*T).tu != 0) { + q = 1; // qTзԪļ + + // colMУT + for(col = 1; col <= M.nu; ++col) { + // MвҵjеԪأνתõT + for(p = 1; p <= M.tu; ++p) { + if(M.data[p].j == col) { + (*T).data[q].i = M.data[p].j; // MбΪT + (*T).data[q].j = M.data[p].i; // MбΪT + (*T).data[q].e = M.data[p].e; // ÿԪֵ + ++q; + } + } + } + } + + return OK; +} + +/* + * 㷨5.2 + * + * ת + */ +Status FastTransposeSMatrix(TSMatrix M, TSMatrix* T) { + int col, t, p, q; + int* num; // num[col] ʾMcolзԪĸ + int* copt; // copt[col]ʾMcolеһԪתúеλ + + (*T).mu = M.nu; + (*T).nu = M.mu; + (*T).tu = M.tu; + + // ǰ + if((*T).tu == 0) { + return ERROR; + } + + num = (int*) malloc(M.nu * sizeof(int)); + copt = (int*) malloc(M.nu * sizeof(int)); + + // ʼnum + for(col = 1; col <= M.nu; ++col) { + num[col] = 0; + } + + // ͳMеķԪͳÿзԪĸ + for(t = 1; t <= M.tu; ++t) { + num[M.data[t].j]++; + } + + // 1е1Ԫλתúеλ + copt[1] = 1; + // е1Ԫתþеλ + for(col = 2; col <= M.nu; ++col) { + copt[col] = copt[col - 1] + num[col - 1]; + } + + // ɨMеԪ + for(p = 1; p <= M.tu; ++p) { + col = M.data[p].j; // 㵱ǰԪ + q = copt[col]; // 㵱ǰԪתþеλ + (*T).data[q].i = M.data[p].j; + (*T).data[q].j = M.data[p].i; + (*T).data[q].e = M.data[p].e; + ++copt[col]; // ԪʱתþеλӦһòҪ + } + + return OK; +} + +/* + * + */ +void PrintSMatrix(TSMatrix M) { + int r, c; + int k = 1; + + for(r = 1; r <= M.mu; r++) { + for(c = 1; c <= M.nu; c++) { + if(r == M.data[k].i && c == M.data[k].j) { + printf("%3d ", M.data[k].e); + k++; + } else { + printf("%3d ", 0); + } + } + printf("\n"); + } +} diff --git a/Dev-C++/ExerciseBook/05.21/TSMatrix.h b/Dev-C++/ExerciseBook/05.21/TSMatrix.h new file mode 100644 index 0000000..52cdeea --- /dev/null +++ b/Dev-C++/ExerciseBook/05.21/TSMatrix.h @@ -0,0 +1,107 @@ +/*======================= + * Ԫ˳ϡ + * + * 㷨: 5.15.2 + ========================*/ + +#ifndef TSMATRIX_H +#define TSMATRIX_H + +#include +#include // ṩ malloc ԭ +#include // ṩ strstr ԭ +#include "Status.h" //**01 **// + +/* + * Ԫֵ + * עֵҪIDEջڴ + */ +#define MAXSIZE 100 + +/* ԪϡԪ */ +typedef int ElemType; + +/* ԪͶ壬Ҫ洢Ԫ */ +typedef struct { + int i, j; // ԪԪ±± + ElemType e; +} Triple; + +/* ԪϡͶ */ +typedef struct { + Triple data[MAXSIZE + 1]; // ԪԪdata[0]δ + int mu, nu, tu; // ͷԪ +} TSMatrix; + + +/* + * ϡM + * + * + *ע + * + * ̲Ĭϴӿ̨ȡݡ + * Ϊ˷ԣÿжֶݣ + * ѡԤļpathжȡݡ + * + * Ҫӿ̨ȡݣpathΪNULLΪմ + * ҪļжȡݣҪpathдļϢ + */ +Status CreateSMatrix(TSMatrix* M, char* path); + +/* + * ϡ + * + *ע + * Ԫ˳Ľṹ޷١ + */ +Status DestroySMatrix(TSMatrix* M); + +/* + * + * + * һ¾Tþ˴ӾMаݡ + */ +Status CopySMatrix(TSMatrix M, TSMatrix* T); + +/* + * ӷ + * + * Q = M + N + */ +Status AddSMatrix(TSMatrix M, TSMatrix N, TSMatrix* Q); + +/* + * + * + * Q = M - N + */ +Status SubSMatrix(TSMatrix M, TSMatrix N, TSMatrix* Q); + +/* + * ˷ + * + * Q = M * NʵֵǴͳ˷ + */ +Status MultSMatrix(TSMatrix M, TSMatrix N, TSMatrix* Q); + +/* + * 㷨5.1 + * + * ת + */ +Status TransposeSMatrix(TSMatrix M, TSMatrix* T); + +/* + * 㷨5.2 + * + * ת + */ +Status FastTransposeSMatrix(TSMatrix M, TSMatrix* T); + +/* + * + */ +void PrintSMatrix(TSMatrix M); + +#endif diff --git a/Dev-C++/ExerciseBook/05.21/TestData_A.txt b/Dev-C++/ExerciseBook/05.21/TestData_A.txt new file mode 100644 index 0000000..be25c94 --- /dev/null +++ b/Dev-C++/ExerciseBook/05.21/TestData_A.txt @@ -0,0 +1,4 @@ +5 +5 +Ԫ10 +Ԫ飺(1,2,1),(1,4,5),(2,3,-3),(2,5,2),(3,1,2),(3,2,3),(3,3,4),(4,4,2),(5,1,3),(5,2,-1) \ No newline at end of file diff --git a/Dev-C++/ExerciseBook/05.21/TestData_B.txt b/Dev-C++/ExerciseBook/05.21/TestData_B.txt new file mode 100644 index 0000000..7c940db --- /dev/null +++ b/Dev-C++/ExerciseBook/05.21/TestData_B.txt @@ -0,0 +1,4 @@ +5 +5 +Ԫ8 +Ԫ飺(1,1,-3)(1,3,2)(2,4,-1)(3,2,4)(4,1,6)(4,5,5)(5,1,3)(5,3,2) \ No newline at end of file diff --git a/Dev-C++/ExerciseBook/05.22/05.22.cpp b/Dev-C++/ExerciseBook/05.22/05.22.cpp new file mode 100644 index 0000000..6ee74f7 --- /dev/null +++ b/Dev-C++/ExerciseBook/05.22/05.22.cpp @@ -0,0 +1,106 @@ +#include +#include "Status.h" //**01 **// +#include "TSMatrix.h" //**05 ͹**// + +/* + * ϡӷAddSMatrix + * + *ע + * Ҫ浽ԭA + */ +Status Algo_5_22(TSMatrix* A, TSMatrix B); + + +int main(int argc, char* argv[]) { + TSMatrix A, B; + + printf(" ϡ AB ...\n"); + CreateSMatrix(&A, "TestData_A.txt"); + CreateSMatrix(&B, "TestData_B.txt"); + printf(" A = \n"); + PrintSMatrix(A); + printf(" B = \n"); + PrintSMatrix(B); + + // + Algo_5_22(&A, B); + + printf(" A = A + B = \n"); + PrintSMatrix(A); + + return 0; +} + + +/* + * ϡӷAddSMatrix + * + *ע + * Ҫ浽ԭA + */ +Status Algo_5_22(TSMatrix* A, TSMatrix B) { + int m, n, k; + + if((*A).mu != B.mu || (*A).nu != B.nu) { + printf("\n"); + return ERROR; + } + + // AԪƶƶΪBԪظ + for(k = (*A).tu; k > 0; k--) { + (*A).data[k + B.tu] = (*A).data[k]; + } + + m = B.tu + 1; // A + n = 1; // B + k = 0; // ָα + + // αABԪ + while(m <= (*A).tu + B.tu && n <= B.tu) { + // AеԪ±С + if((*A).data[m].i < B.data[n].i) { + (*A).data[++k] = (*A).data[m++]; + + // BеԪ±С + } else if((*A).data[m].i > B.data[n].i) { + (*A).data[++k] = B.data[n++]; + + // ABеԪ±һ£ҪһȽ + } else { + // AеԪ±С + if((*A).data[m].j < B.data[n].j) { + (*A).data[++k] = (*A).data[m++]; + + // BеԪ±С + } else if((*A).data[m].j > B.data[n].j) { + (*A).data[++k] = B.data[n++]; + + // ABеԪ±һ£Ҫмӷ + } else { + // ֵΪ0ʱҪ洢Ԫ + if(((*A).data[m].e + B.data[n].e) != 0) { + k++; + (*A).data[k].i = (*A).data[m].i; + (*A).data[k].j = (*A).data[m].j; + (*A).data[k].e = (*A).data[m].e + B.data[n].e; + } + m++; + n++; + } + } + } + + // AʣԪ + while(m <= (*A).tu + B.tu) { + (*A).data[++k] = (*A).data[m++]; + } + + // BʣԪ + while(n <= B.tu) { + (*A).data[++k] = B.data[n++]; + } + + (*A).tu = k; + + return OK; +} diff --git a/Dev-C++/ExerciseBook/05.22/05.22.dev b/Dev-C++/ExerciseBook/05.22/05.22.dev new file mode 100644 index 0000000..06603f3 --- /dev/null +++ b/Dev-C++/ExerciseBook/05.22/05.22.dev @@ -0,0 +1,100 @@ +[Project] +FileName=05.22.dev +Name=05.22 +Type=1 +Ver=2 +ObjFiles= +Includes= +Libs= +PrivateResource= +ResourceIncludes= +MakeIncludes= +Compiler= +CppCompiler= +Linker= +IsCpp=0 +Icon= +ExeOutput= +ObjectOutput= +LogOutput= +LogOutputEnabled=0 +OverrideOutput=0 +OverrideOutputName= +HostApplication= +UseCustomMakefile=0 +CustomMakefile= +CommandLine= +Folders= +IncludeVersionInfo=0 +SupportXPThemes=0 +CompilerSet=1 +CompilerSettings=0000000000000000001000000 +UnitCount=5 + +[VersionInfo] +Major=1 +Minor=0 +Release=0 +Build=0 +LanguageID=1033 +CharsetID=1252 +CompanyName= +FileVersion= +FileDescription=Developed using the Dev-C++ IDE +InternalName= +LegalCopyright= +LegalTrademarks= +OriginalFilename= +ProductName= +ProductVersion= +AutoIncBuildNr=0 +SyncProduct=1 + +[Unit4] +FileName=TSMatrix.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit1] +FileName=05.22.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit2] +FileName=TestData_A.txt +Folder= +Compile=0 +Link=0 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit3] +FileName=TestData_B.txt +Folder= +Compile=0 +Link=0 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit5] +FileName=TSMatrix.h +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + diff --git a/Dev-C++/ExerciseBook/05.22/TSMatrix.cpp b/Dev-C++/ExerciseBook/05.22/TSMatrix.cpp new file mode 100644 index 0000000..05eeaad --- /dev/null +++ b/Dev-C++/ExerciseBook/05.22/TSMatrix.cpp @@ -0,0 +1,433 @@ +/*======================= + * Ԫ˳ϡ + * + * 㷨: 5.15.2 + ========================*/ + +#include "TSMatrix.h" //**05 ͹**// + +/* + * ϡM + * + * + *ע + * + * ̲Ĭϴӿ̨ȡݡ + * Ϊ˷ԣÿжֶݣ + * ѡԤļpathжȡݡ + * + * Ҫӿ̨ȡݣpathΪNULLΪմ + * ҪļжȡݣҪpathдļϢ + */ +Status CreateSMatrix(TSMatrix* M, char* path) { + int k; + FILE* fp; + int readFromConsole; // Ƿӿ̨ȡ + + // ûļ·Ϣӿ̨ȡ + readFromConsole = path == NULL || strcmp(path, "") == 0; + + // ûļ·Ϣӿ̨ȡ + if(readFromConsole) { + printf(""); + scanf("%d", &((*M).mu)); + printf(""); + scanf("%d", &((*M).nu)); + printf("Ԫظ"); + scanf("%d", &((*M).tu)); + printf("%dԪϢ\n", (*M).tu); + for(k = 1; k <= (*M).tu; k++) { + printf("%2d飺", k); + scanf("%d%d%d", &((*M).data[k].i), &((*M).data[k].j), &((*M).data[k].e)); + } + } else { + fp = fopen(path, "r"); + + ReadData(fp, "%d%d%d", &((*M).mu), &((*M).nu), &((*M).tu)); + + for(k = 1; k <= (*M).tu; k++) { + ReadData(fp, "%d%d%d", &((*M).data[k].i), &((*M).data[k].j), &((*M).data[k].e)); + } + + fclose(fp); + } + + return OK; +} + +/* + * ϡ + * + *ע + * Ԫ˳Ľṹ޷١ + */ +Status DestroySMatrix(TSMatrix* M) { + if(M == NULL) { + return ERROR; + } + + (*M).mu = 0; + (*M).nu = 0; + (*M).tu = 0; + + return OK; +} + +/* + * + * + * һ¾Tþ˴ӾMаݡ + */ +Status CopySMatrix(TSMatrix M, TSMatrix* T) { + (*T) = M; // ṹֱ֮ӸƣʹڲҲ + + return OK; +} + +/* + * ӷ + * + * Q = M + N + */ +Status AddSMatrix(TSMatrix M, TSMatrix N, TSMatrix* Q) { + int m, n, k; + + if(M.mu != N.mu || M.nu != N.nu) { + printf("\n"); + return ERROR; + } + + // ʼQ + (*Q).mu = M.mu; + (*Q).nu = M.nu; + (*Q).tu = 0; + + m = n = k = 1; + + // αMNԪ + while(m <= M.tu && n <= N.tu) { + // MеԪ±С + if(M.data[m].i < N.data[n].i) { + (*Q).data[k] = M.data[m]; + m++; + + // NеԪ±С + } else if(M.data[m].i > N.data[n].i) { + (*Q).data[k] = N.data[n]; + n++; + + // MNеԪ±һ£ҪһȽ + } else { + // MеԪ±С + if(M.data[m].j < N.data[n].j) { + (*Q).data[k] = M.data[m]; + m++; + + // NеԪ±С + } else if(M.data[m].j > N.data[n].j) { + (*Q).data[k] = N.data[n]; + n++; + + // MNеԪ±һ£Ҫмӷ + } else { + // ֵѾΪ0ĻҪ洢Ԫ + if((M.data[m].e + N.data[n].e) == 0) { + m++; + n++; + continue; + } else { + (*Q).data[k].i = M.data[m].i; + (*Q).data[k].j = M.data[m].j; + (*Q).data[k].e = M.data[m].e + N.data[n].e; + m++; + n++; + } + } + } + + k++; + (*Q).tu++; + } + + // MʣԪ + while(m <= M.tu) { + (*Q).data[k] = M.data[m]; + m++; + k++; + (*Q).tu++; + } + + // NʣԪ + while(n <= N.tu) { + (*Q).data[k] = N.data[n]; + n++; + k++; + (*Q).tu++; + } + + return OK; +} + +/* + * + * + * Q = M - N + */ +Status SubSMatrix(TSMatrix M, TSMatrix N, TSMatrix* Q) { + int m, n, k; + + if(M.mu != N.mu || M.nu != N.nu) { + printf("\n"); + return ERROR; + } + + // ʼQ + (*Q).mu = M.mu; + (*Q).nu = M.nu; + (*Q).tu = 0; + + m = n = k = 1; + + // αMNԪ + while(m <= M.tu && n <= N.tu) { + // MеԪ±С + if(M.data[m].i < N.data[n].i) { + (*Q).data[k] = M.data[m]; + m++; + + // NеԪ±С + } else if(M.data[m].i > N.data[n].i) { + (*Q).data[k].i = N.data[n].i; + (*Q).data[k].j = N.data[n].j; + (*Q).data[k].e = -N.data[n].e; // ҪԪֵȡ෴ + n++; + + // MNеԪ±һ£ҪһȽ + } else { + // MеԪ±С + if(M.data[m].j < N.data[n].j) { + (*Q).data[k] = M.data[m]; + m++; + + // NеԪ±С + } else if(M.data[m].j > N.data[n].j) { + (*Q).data[k].i = N.data[n].i; + (*Q).data[k].j = N.data[n].j; + (*Q).data[k].e = -N.data[n].e; // ҪԪֵȡ෴ + n++; + + // MNеԪ±һ£Ҫм + } else { + // ֵѾΪ0ĻҪ洢Ԫ + if((M.data[m].e - N.data[n].e) == 0) { + m++; + n++; + continue; + } else { + (*Q).data[k].i = M.data[m].i; + (*Q).data[k].j = M.data[m].j; + (*Q).data[k].e = M.data[m].e - N.data[n].e; + m++; + n++; + } + } + } + + k++; + (*Q).tu++; + } + + // MʣԪ + while(m <= M.tu) { + (*Q).data[k] = M.data[m]; + m++; + k++; + (*Q).tu++; + } + + // NʣԪ + while(n <= N.tu) { + (*Q).data[k].i = N.data[n].i; + (*Q).data[k].j = N.data[n].j; + (*Q).data[k].e = -N.data[n].e; + n++; + k++; + (*Q).tu++; + } + + return OK; +} + +/* + * ˷ + * + * Q = M * NʵֵǴͳ˷ + */ +Status MultSMatrix(TSMatrix M, TSMatrix N, TSMatrix* Q) { + int m, n, i, j, k; + ElemType c, c1, c2; + + // MҪN + if(M.nu != N.mu) { + printf("\n"); + return ERROR; + } + + // ʼQ + (*Q).mu = M.mu; + (*Q).nu = N.nu; + (*Q).tu = 0; + + // + if(M.tu * N.tu == 0) { + return OK; + } + + // M + for(i = 1; i <= M.mu; i++) { + // N + for(j = 1; j <= N.nu; j++) { + c = 0; + for(k = 1; k <= M.nu; k++) { + // ¼M[i][k]ֵ + c1 = 0; + // ѰλָλõMԪ + for(m = 1; m <= M.tu; m++) { + if(M.data[m].i == i && M.data[m].j == k) { + c1 = M.data[m].e; + break; + } + } + + // ¼N[k][j]ֵ + c2 = 0; + //ѰλָλõNԪ + for(n = 1; n <= N.tu; n++) { + if(N.data[n].i == k && N.data[n].j == j) { + c2 = N.data[n].e; + break; + } + } + + // Q[i][j]ֵ + if(c1 && c2) { + c += c1 * c2; + } + } + + // Ϊ0д洢 + if(c != 0) { + (*Q).tu++; + (*Q).data[(*Q).tu].i = i; + (*Q).data[(*Q).tu].j = j; + (*Q).data[(*Q).tu].e = c; + } + } + } + + return OK; +} + +/* + * 㷨5.1 + * + * ת + */ +Status TransposeSMatrix(TSMatrix M, TSMatrix* T) { + int p, q, col; + + (*T).mu = M.nu; + (*T).nu = M.mu; + (*T).tu = M.tu; + + if((*T).tu != 0) { + q = 1; // qTзԪļ + + // colMУT + for(col = 1; col <= M.nu; ++col) { + // MвҵjеԪأνתõT + for(p = 1; p <= M.tu; ++p) { + if(M.data[p].j == col) { + (*T).data[q].i = M.data[p].j; // MбΪT + (*T).data[q].j = M.data[p].i; // MбΪT + (*T).data[q].e = M.data[p].e; // ÿԪֵ + ++q; + } + } + } + } + + return OK; +} + +/* + * 㷨5.2 + * + * ת + */ +Status FastTransposeSMatrix(TSMatrix M, TSMatrix* T) { + int col, t, p, q; + int* num; // num[col] ʾMcolзԪĸ + int* copt; // copt[col]ʾMcolеһԪתúеλ + + (*T).mu = M.nu; + (*T).nu = M.mu; + (*T).tu = M.tu; + + // ǰ + if((*T).tu == 0) { + return ERROR; + } + + num = (int*) malloc(M.nu * sizeof(int)); + copt = (int*) malloc(M.nu * sizeof(int)); + + // ʼnum + for(col = 1; col <= M.nu; ++col) { + num[col] = 0; + } + + // ͳMеķԪͳÿзԪĸ + for(t = 1; t <= M.tu; ++t) { + num[M.data[t].j]++; + } + + // 1е1Ԫλתúеλ + copt[1] = 1; + // е1Ԫתþеλ + for(col = 2; col <= M.nu; ++col) { + copt[col] = copt[col - 1] + num[col - 1]; + } + + // ɨMеԪ + for(p = 1; p <= M.tu; ++p) { + col = M.data[p].j; // 㵱ǰԪ + q = copt[col]; // 㵱ǰԪתþеλ + (*T).data[q].i = M.data[p].j; + (*T).data[q].j = M.data[p].i; + (*T).data[q].e = M.data[p].e; + ++copt[col]; // ԪʱתþеλӦһòҪ + } + + return OK; +} + +/* + * + */ +void PrintSMatrix(TSMatrix M) { + int r, c; + int k = 1; + + for(r = 1; r <= M.mu; r++) { + for(c = 1; c <= M.nu; c++) { + if(r == M.data[k].i && c == M.data[k].j) { + printf("%3d ", M.data[k].e); + k++; + } else { + printf("%3d ", 0); + } + } + printf("\n"); + } +} diff --git a/Dev-C++/ExerciseBook/05.22/TSMatrix.h b/Dev-C++/ExerciseBook/05.22/TSMatrix.h new file mode 100644 index 0000000..52cdeea --- /dev/null +++ b/Dev-C++/ExerciseBook/05.22/TSMatrix.h @@ -0,0 +1,107 @@ +/*======================= + * Ԫ˳ϡ + * + * 㷨: 5.15.2 + ========================*/ + +#ifndef TSMATRIX_H +#define TSMATRIX_H + +#include +#include // ṩ malloc ԭ +#include // ṩ strstr ԭ +#include "Status.h" //**01 **// + +/* + * Ԫֵ + * עֵҪIDEջڴ + */ +#define MAXSIZE 100 + +/* ԪϡԪ */ +typedef int ElemType; + +/* ԪͶ壬Ҫ洢Ԫ */ +typedef struct { + int i, j; // ԪԪ±± + ElemType e; +} Triple; + +/* ԪϡͶ */ +typedef struct { + Triple data[MAXSIZE + 1]; // ԪԪdata[0]δ + int mu, nu, tu; // ͷԪ +} TSMatrix; + + +/* + * ϡM + * + * + *ע + * + * ̲Ĭϴӿ̨ȡݡ + * Ϊ˷ԣÿжֶݣ + * ѡԤļpathжȡݡ + * + * Ҫӿ̨ȡݣpathΪNULLΪմ + * ҪļжȡݣҪpathдļϢ + */ +Status CreateSMatrix(TSMatrix* M, char* path); + +/* + * ϡ + * + *ע + * Ԫ˳Ľṹ޷١ + */ +Status DestroySMatrix(TSMatrix* M); + +/* + * + * + * һ¾Tþ˴ӾMаݡ + */ +Status CopySMatrix(TSMatrix M, TSMatrix* T); + +/* + * ӷ + * + * Q = M + N + */ +Status AddSMatrix(TSMatrix M, TSMatrix N, TSMatrix* Q); + +/* + * + * + * Q = M - N + */ +Status SubSMatrix(TSMatrix M, TSMatrix N, TSMatrix* Q); + +/* + * ˷ + * + * Q = M * NʵֵǴͳ˷ + */ +Status MultSMatrix(TSMatrix M, TSMatrix N, TSMatrix* Q); + +/* + * 㷨5.1 + * + * ת + */ +Status TransposeSMatrix(TSMatrix M, TSMatrix* T); + +/* + * 㷨5.2 + * + * ת + */ +Status FastTransposeSMatrix(TSMatrix M, TSMatrix* T); + +/* + * + */ +void PrintSMatrix(TSMatrix M); + +#endif diff --git a/Dev-C++/ExerciseBook/05.22/TestData_A.txt b/Dev-C++/ExerciseBook/05.22/TestData_A.txt new file mode 100644 index 0000000..be25c94 --- /dev/null +++ b/Dev-C++/ExerciseBook/05.22/TestData_A.txt @@ -0,0 +1,4 @@ +5 +5 +Ԫ10 +Ԫ飺(1,2,1),(1,4,5),(2,3,-3),(2,5,2),(3,1,2),(3,2,3),(3,3,4),(4,4,2),(5,1,3),(5,2,-1) \ No newline at end of file diff --git a/Dev-C++/ExerciseBook/05.22/TestData_B.txt b/Dev-C++/ExerciseBook/05.22/TestData_B.txt new file mode 100644 index 0000000..7c940db --- /dev/null +++ b/Dev-C++/ExerciseBook/05.22/TestData_B.txt @@ -0,0 +1,4 @@ +5 +5 +Ԫ8 +Ԫ飺(1,1,-3)(1,3,2)(2,4,-1)(3,2,4)(4,1,6)(4,5,5)(5,1,3)(5,3,2) \ No newline at end of file diff --git a/Dev-C++/ExerciseBook/05.23/05.23.cpp b/Dev-C++/ExerciseBook/05.23/05.23.cpp new file mode 100644 index 0000000..27818c4 --- /dev/null +++ b/Dev-C++/ExerciseBook/05.23/05.23.cpp @@ -0,0 +1,52 @@ +#include +#include "Status.h" //**01 **// +#include "RLSMatrix.h" //**05 ͹**// + +/* + * ȡеiеjеԪأ洢e + */ +Status Algo_5_23(RLSMatrix M, int i, int j, int* e); + + +int main(int argc, char* argv[]) { + RLSMatrix M; + int e; + + printf(" ϡ M ...\n"); + CreateSMatrix(&M, "TestData_M.txt"); + printf("M = \n"); + PrintSMatrix(M); + + Algo_5_23(M, 2, 3, &e); + printf(" %d %d еԪΪ %d\n", 2, 3, e); + + return 0; +} + + +/* + * ȡеiеjеԪأ洢e + */ +Status Algo_5_23(RLSMatrix M, int i, int j, int* e) { + int begin, end, k; + + if(i < 1 || i > M.mu || j < 1 || j > M.nu) { + return ERROR; + } + + // ȡi׸ԪԪеλ + begin = M.rpos[i]; + end = (i == M.mu ? M.tu : M.rpos[i + 1] - 1); + + *e = 0; // ĬΪ0 + + for(k = begin; k <= end; k++) { + // ҵӦ±Ԫ + if(M.data[k].j == j) { + *e = M.data[k].e; + break; + } + } + + return OK; +} diff --git a/Dev-C++/ExerciseBook/05.23/05.23.dev b/Dev-C++/ExerciseBook/05.23/05.23.dev new file mode 100644 index 0000000..8492dec --- /dev/null +++ b/Dev-C++/ExerciseBook/05.23/05.23.dev @@ -0,0 +1,91 @@ +[Project] +FileName=05.23.dev +Name=05.23 +Type=1 +Ver=2 +ObjFiles= +Includes= +Libs= +PrivateResource= +ResourceIncludes= +MakeIncludes= +Compiler= +CppCompiler= +Linker= +IsCpp=0 +Icon= +ExeOutput= +ObjectOutput= +LogOutput= +LogOutputEnabled=0 +OverrideOutput=0 +OverrideOutputName= +HostApplication= +UseCustomMakefile=0 +CustomMakefile= +CommandLine= +Folders= +IncludeVersionInfo=0 +SupportXPThemes=0 +CompilerSet=1 +CompilerSettings=0000000000000000001000000 +UnitCount=4 + +[VersionInfo] +Major=1 +Minor=0 +Release=0 +Build=0 +LanguageID=1033 +CharsetID=1252 +CompanyName= +FileVersion= +FileDescription=Developed using the Dev-C++ IDE +InternalName= +LegalCopyright= +LegalTrademarks= +OriginalFilename= +ProductName= +ProductVersion= +AutoIncBuildNr=0 +SyncProduct=1 + +[Unit2] +FileName=RLSMatrix.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit1] +FileName=05.23.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit3] +FileName=RLSMatrix.h +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit4] +FileName=TestData_M.txt +Folder= +Compile=0 +Link=0 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + diff --git a/Dev-C++/ExerciseBook/05.23/RLSMatrix.cpp b/Dev-C++/ExerciseBook/05.23/RLSMatrix.cpp new file mode 100644 index 0000000..5d28a0e --- /dev/null +++ b/Dev-C++/ExerciseBook/05.23/RLSMatrix.cpp @@ -0,0 +1,515 @@ +/*============================= + * ߼ӵ˳ϡ + * + * 㷨: 5.3 + ==============================*/ + +#include "RLSMatrix.h" //**05 ͹**// + +/* + * ϡM + * + * + *ע + * + * ̲Ĭϴӿ̨ȡݡ + * Ϊ˷ԣÿжֶݣ + * ѡԤļpathжȡݡ + * + * Ҫӿ̨ȡݣpathΪNULLΪմ + * ҪļжȡݣҪpathдļϢ + */ +Status CreateSMatrix(RLSMatrix* M, char* path) { + int k; + FILE* fp; + int readFromConsole; // Ƿӿ̨ȡ + + // ûļ·Ϣӿ̨ȡ + readFromConsole = path == NULL || strcmp(path, "") == 0; + + // ûļ·Ϣӿ̨ȡ + if(readFromConsole) { + printf(""); + scanf("%d", &((*M).mu)); + printf(""); + scanf("%d", &((*M).nu)); + printf("Ԫظ"); + scanf("%d", &((*M).tu)); + printf("%dԪϢ\n", (*M).tu); + for(k = 1; k <= (*M).tu; k++) { + printf("%2d飺", k); + scanf("%d%d%d", &((*M).data[k].i), &((*M).data[k].j), &((*M).data[k].e)); + } + } else { + fp = fopen(path, "r"); + + ReadData(fp, "%d%d%d", &((*M).mu), &((*M).nu), &((*M).tu)); + + for(k = 1; k <= (*M).tu; k++) { + ReadData(fp, "%d%d%d", &((*M).data[k].i), &((*M).data[k].j), &((*M).data[k].e)); + } + + fclose(fp); + } + + // Ϊrpos鸳ֵ + AssignRpos(M); + + return OK; +} + +/* + * ϡ + * + *ע + * ߼ӵ˳ṹ޷١ + */ +Status DestroySMatrix(RLSMatrix* M) { + int i; + + if(M == NULL) { + return ERROR; + } + + M->mu = 0; + M->nu = 0; + M->tu = 0; + + for(i = 0; i <= MAXRC; ++i) { + M->rpos[i] = 0; + } + + return OK; +} + +/* + * + * + * һ¾Tþ˴ӾMаݡ + */ +Status CopySMatrix(RLSMatrix M, RLSMatrix* T) { + (*T) = M; // ṹֱ֮ӸƣʹڲҲ + + return OK; +} + +/* + * ӷ + * + * Q = M + N + */ +Status AddSMatrix(RLSMatrix M, RLSMatrix N, RLSMatrix* Q) { + int m, n, k; + + if(M.mu != N.mu || M.nu != N.nu) { + printf("\n"); + return ERROR; + } + + // ʼQϢ + (*Q).mu = M.mu; + (*Q).nu = M.nu; + (*Q).tu = 0; + + m = n = k = 1; + + // αMNԪ + while(m <= M.tu && n <= N.tu) { + // MеԪ±С + if(M.data[m].i < N.data[n].i) { + (*Q).data[k] = M.data[m]; + m++; + + // NеԪ±С + } else if(M.data[m].i > N.data[n].i) { + (*Q).data[k] = N.data[n]; + n++; + + // MNеԪ±һ£ҪһȽ + } else { + // MеԪ±С + if(M.data[m].j < N.data[n].j) { + (*Q).data[k] = M.data[m]; + m++; + + // NеԪ±С + } else if(M.data[m].j > N.data[n].j) { + (*Q).data[k] = N.data[n]; + n++; + + // MNеԪ±һ£Ҫмӷ + } else { + // ֵѾΪ0ĻҪ洢Ԫ + if((M.data[m].e + N.data[n].e) == 0) { + m++; + n++; + continue; + } else { + (*Q).data[k].i = M.data[m].i; + (*Q).data[k].j = M.data[m].j; + (*Q).data[k].e = M.data[m].e + N.data[n].e; + m++; + n++; + } + } + } + + k++; + (*Q).tu++; + } + + // MʣԪ + while(m <= M.tu) { + (*Q).data[k] = M.data[m]; + m++; + k++; + (*Q).tu++; + } + + // NʣԪ + while(n <= N.tu) { + (*Q).data[k] = N.data[n]; + n++; + k++; + (*Q).tu++; + } + + // Ϊrpos鸳ֵ + AssignRpos(Q); + + return OK; +} + +/* + * + * + * Q = M - N + */ +Status SubSMatrix(RLSMatrix M, RLSMatrix N, RLSMatrix* Q) { + int m, n, k; + + if(M.mu != N.mu || M.nu != N.nu) { + printf("\n"); + return ERROR; + } + + // ʼQϢ + (*Q).mu = M.mu; + (*Q).nu = M.nu; + (*Q).tu = 0; + + m = n = k = 1; + + // αMNԪ + while(m <= M.tu && n <= N.tu) { + // MеԪ±С + if(M.data[m].i < N.data[n].i) { + (*Q).data[k] = M.data[m]; + m++; + + // NеԪ±С + } else if(M.data[m].i > N.data[n].i) { + (*Q).data[k].i = N.data[n].i; + (*Q).data[k].j = N.data[n].j; + (*Q).data[k].e = -N.data[n].e; // ҪԪֵȡ෴ + n++; + + // MNеԪ±һ£ҪһȽ + } else { + // MеԪ±С + if(M.data[m].j < N.data[n].j) { + (*Q).data[k] = M.data[m]; + m++; + + // NеԪ±С + } else if(M.data[m].j > N.data[n].j) { + (*Q).data[k].i = N.data[n].i; + (*Q).data[k].j = N.data[n].j; + (*Q).data[k].e = -N.data[n].e; // ҪԪֵȡ෴ + n++; + + // MNеԪ±һ£Ҫм + } else { + // ֵѾΪ0ĻҪ洢Ԫ + if((M.data[m].e - N.data[n].e) == 0) { + m++; + n++; + continue; + } else { + (*Q).data[k].i = M.data[m].i; + (*Q).data[k].j = M.data[m].j; + (*Q).data[k].e = M.data[m].e - N.data[n].e; + m++; + n++; + } + } + } + + k++; + (*Q).tu++; + } + + // MʣԪ + while(m <= M.tu) { + (*Q).data[k] = M.data[m]; + m++; + k++; + (*Q).tu++; + } + + // NʣԪ + while(n <= N.tu) { + (*Q).data[k].i = N.data[n].i; + (*Q).data[k].j = N.data[n].j; + (*Q).data[k].e = -N.data[n].e; + n++; + k++; + (*Q).tu++; + } + + // Ϊrpos鸳ֵ + AssignRpos(Q); + + return OK; +} + +/* + * 㷨5.3 + * + * ˷ + * + * Q = M * N + */ +Status MultSMatrix(RLSMatrix M, RLSMatrix N, RLSMatrix* Q) { + int arow, p, tp; + int brow, q, tq; + int ccol; + int* ctemp; // QиԪֵۼctemp[0]Ԫ + int i; + + // MҪN + if(M.nu != N.mu) { + printf("\n"); + return ERROR; + } + + // ʼQϢ + (*Q).mu = M.mu; + (*Q).nu = N.nu; + (*Q).tu = 0; + + // + if(M.tu * N.tu == 0) { + return OK; + } + + ctemp = (int*) malloc((N.nu + 1) * sizeof(int)); + + // Mÿһ + for(arow = 1; arow <= M.mu; ++arow) { + // ʼQԪֵ + for(i = 0; i <= N.nu; ++i) { + ctemp[i] = 0; + } + + // tpָMǰеһеһԪλ + if(arow < M.mu) { + tp = M.rpos[arow + 1]; + } else { + tp = M.tu + 1; + } + + // MarowезԪ + for(p = M.rpos[arow]; p < tp; ++p) { + // ȡ÷ԪNек + brow = M.data[p].j; + + // tqָNǰеһеһԪλ + if(brow < N.mu) { + tq = N.rpos[brow + 1]; + } else { + tq = N.tu + 1; + } + + // NbrowезԪ + for(q = N.rpos[brow]; q < tq; ++q) { + // ˻ԪQек + ccol = N.data[q].j; + + // ۼӳ˻ + ctemp[ccol] += M.data[p].e * N.data[q].e; + } + } + + /* + * ˣQеarowԪ + */ + + // ij˻ѡȡԪQ + for(ccol = 1; ccol <= (*Q).nu; ++ccol) { + // QеarowccolԪزΪ0 + if(ctemp[ccol]) { + ++(*Q).tu; + + // Ԫ + if((*Q).tu > MAXSIZE) { + return ERROR; + } + + (*Q).data[(*Q).tu].i = arow; + (*Q).data[(*Q).tu].j = ccol; + (*Q).data[(*Q).tu].e = ctemp[ccol]; + } + } + } + + // Ϊrpos鸳ֵ + AssignRpos(Q); + + return OK; +} + +/* + * ת + */ +Status TransposeSMatrix(RLSMatrix M, RLSMatrix* T) { + int p, q, col; + + (*T).mu = M.nu; + (*T).nu = M.mu; + (*T).tu = M.tu; + + if((*T).tu) { + q = 1; // qTзԪļ + + // colMУT + for(col = 1; col <= M.nu; ++col) { + // MвҵjеԪأνתõT + for(p = 1; p <= M.tu; ++p) { + if(M.data[p].j == col) { + (*T).data[q].i = M.data[p].j; // MбΪT + (*T).data[q].j = M.data[p].i; // MбΪT + (*T).data[q].e = M.data[p].e; // ÿԪֵ + + ++q; + } + } + } + } + + // Ϊrpos鸳ֵ + AssignRpos(T); + + return OK; +} + +/* + * ת + */ +Status FastTransposeSMatrix(RLSMatrix M, RLSMatrix* T) { + int col, t, p, q; + int* num; // num[col] ʾMcolзԪĸ + int* copt; // copt[col]ʾMcolеһԪתúеλ + + (*T).mu = M.nu; + (*T).nu = M.mu; + (*T).tu = M.tu; + + // ǰ + if((*T).tu == 0) { + return ERROR; + } + + num = (int*) malloc(M.nu * sizeof(int)); + copt = (int*) malloc(M.nu * sizeof(int)); + + // ʼnum + for(col = 1; col <= M.nu; ++col) { + num[col] = 0; + } + + // ͳMеķԪͳÿзԪĸ + for(t = 1; t <= M.tu; ++t) { + num[M.data[t].j]++; + } + + // 1е1Ԫλתúеλ + copt[1] = 1; + // е1Ԫתþеλ + for(col = 2; col <= M.nu; ++col) { + copt[col] = copt[col - 1] + num[col - 1]; + } + + // ɨMеԪ + for(p = 1; p <= M.tu; ++p) { + col = M.data[p].j; // 㵱ǰԪ + q = copt[col]; // 㵱ǰԪתþеλ + (*T).data[q].i = M.data[p].j; + (*T).data[q].j = M.data[p].i; + (*T).data[q].e = M.data[p].e; + ++copt[col]; // ԪʱתþеλӦһòҪ + } + + // Ϊrpos鸳ֵ + AssignRpos(T); + + return OK; +} + +/* + * + */ +void PrintSMatrix(RLSMatrix M) { + int r, c; + int k = 1; + + for(r = 1; r <= M.mu; ++r) { + for(c = 1; c <= M.nu; ++c) { + if(r == M.data[k].i && c == M.data[k].j) { + printf("%3d ", M.data[k].e); + k++; + } else { + printf("%3d ", 0); + } + } + printf("\n"); + } + + printf("rpos = "); + for(k = 1; k <= M.mu; ++k) { + printf("%d ", M.rpos[k]); + } + printf("\n"); +} + +// Ϊrpos鸳ֵ +static void AssignRpos(RLSMatrix* M) { + int k, m; + + // ʼrpos + for(k = 0; k <= MAXRC; ++k) { + (*M).rpos[k] = 0; + } + + for(k = 1; k <= (*M).tu; k++) { + m = (*M).data[k].i; // ǰԪԪھеλ + + // ¼ÿеһԪԪеλ + if((*M).rpos[m] == 0) { + (*M).rpos[m] = k; // ֻڵǰзԪ¼¼ + } + } + + // ЩûзԪ + for(k = (*M).mu; k >= 1; k--) { + // ǰûзԪ˴ֱȡһеIJ + if((*M).rpos[k] == 0) { + // һ޷ԪΪѾһˣ⴦ + if(k == (*M).mu) { + (*M).rpos[k] = (*M).tu + 1; + } else { + (*M).rpos[k] = (*M).rpos[k + 1]; + } + } + } +} diff --git a/Dev-C++/ExerciseBook/05.23/RLSMatrix.h b/Dev-C++/ExerciseBook/05.23/RLSMatrix.h new file mode 100644 index 0000000..0550c13 --- /dev/null +++ b/Dev-C++/ExerciseBook/05.23/RLSMatrix.h @@ -0,0 +1,107 @@ +/*============================= + * ߼ӵ˳ϡ + * + * 㷨: 5.3 + ==============================*/ + +#ifndef RLSMATRIX_H +#define RLSMATRIX_H + +#include +#include // ṩ malloc ԭ +#include // ṩ strstr ԭ +#include "Status.h" //**01 **// + +/* 궨 */ +#define MAXSIZE 12500 // Ԫֵ +#define MAXRC 20 // Ԫظֵ + +/* ߼ӵϡԪ */ +typedef int ElemType; + +/* ԪͶ壬Ҫ洢Ԫ */ +typedef struct { + int i, j; // ÷Ԫ±± + ElemType e; +} Triple; + +/* ߼ӵϡͶ */ +typedef struct { + Triple data[MAXSIZE + 1]; // ԪԪdata[0]δ + int rpos[MAXRC + 1]; // еһԪԪеλñrpos[0]δ + int mu, nu, tu; // ͷԪ +} RLSMatrix; + + +/* + * ϡM + * + * + *ע + * + * ̲Ĭϴӿ̨ȡݡ + * Ϊ˷ԣÿжֶݣ + * ѡԤļpathжȡݡ + * + * Ҫӿ̨ȡݣpathΪNULLΪմ + * ҪļжȡݣҪpathдļϢ + */ +Status CreateSMatrix(RLSMatrix* M, char* path); + +/* + * ϡ + * + *ע + * ߼ӵ˳ṹ޷١ + */ +Status DestroySMatrix(RLSMatrix* M); + +/* + * + * + * һ¾Tþ˴ӾMаݡ + */ +Status CopySMatrix(RLSMatrix M, RLSMatrix* T); + +/* + * ӷ + * + * Q = M + N + */ +Status AddSMatrix(RLSMatrix M, RLSMatrix N, RLSMatrix* Q); + +/* + * + * + * Q = M - N + */ +Status SubSMatrix(RLSMatrix M, RLSMatrix N, RLSMatrix* Q); + +/* + * 㷨5.3 + * + * ˷ + * + * Q = M * N + */ +Status MultSMatrix(RLSMatrix M, RLSMatrix N, RLSMatrix* Q); + +/* + * ת + */ +Status TransposeSMatrix(RLSMatrix M, RLSMatrix* T); + +/* + * ת + */ +Status FastTransposeSMatrix(RLSMatrix M, RLSMatrix* T); + +/* + * + */ +void PrintSMatrix(RLSMatrix M); + +// Ϊrpos鸳ֵ +static void AssignRpos(RLSMatrix* M); + +#endif diff --git a/Dev-C++/ExerciseBook/05.23/TestData_M.txt b/Dev-C++/ExerciseBook/05.23/TestData_M.txt new file mode 100644 index 0000000..be25c94 --- /dev/null +++ b/Dev-C++/ExerciseBook/05.23/TestData_M.txt @@ -0,0 +1,4 @@ +5 +5 +Ԫ10 +Ԫ飺(1,2,1),(1,4,5),(2,3,-3),(2,5,2),(3,1,2),(3,2,3),(3,3,4),(4,4,2),(5,1,3),(5,2,-1) \ No newline at end of file diff --git a/Dev-C++/ExerciseBook/05.24/05.24.cpp b/Dev-C++/ExerciseBook/05.24/05.24.cpp new file mode 100644 index 0000000..1da6f30 --- /dev/null +++ b/Dev-C++/ExerciseBook/05.24/05.24.cpp @@ -0,0 +1,49 @@ +#include +#include "Status.h" //**01 **// +#include "SMatrix.h" //**ϡ**// + +/* + * ȡеiеjеԪأ洢e + */ +Status Algo_5_24(SMatrix M, int i, int j, int* e); + + +int main(int argc, char* argv[]) { + SMatrix M; + int e; + + printf(" ϡ M ...\n"); + CreateSMatrix(&M, "TestData_M.txt"); + printf("M = \n"); + PrintSMatrix(M); + + Algo_5_24(M, 2, 3, &e); + printf(" %d %d еԪΪ %d\n", 2, 3, e); + + return 0; +} + + +/* + * ȡеiеjеԪأ洢e + */ +Status Algo_5_24(SMatrix M, int i, int j, int* e) { + int s, p; + + if(i < 1 || i > M.mu || j < 1 || j > M.nu) { + return ERROR; + } + + for(p = 1, s = (i - 1) * M.nu + j; M.data[p].seq < s; p++) { + // ѰָԪ + } + + *e = 0; // ĬΪ0 + + // ҵӦ±Ԫ + if(M.data[p].seq == s) { + *e = M.data[p].e; + } + + return OK; +} diff --git a/Dev-C++/ExerciseBook/05.24/05.24.dev b/Dev-C++/ExerciseBook/05.24/05.24.dev new file mode 100644 index 0000000..2c4a524 --- /dev/null +++ b/Dev-C++/ExerciseBook/05.24/05.24.dev @@ -0,0 +1,91 @@ +[Project] +FileName=05.24.dev +Name=05.24 +Type=1 +Ver=2 +ObjFiles= +Includes= +Libs= +PrivateResource= +ResourceIncludes= +MakeIncludes= +Compiler= +CppCompiler= +Linker= +IsCpp=0 +Icon= +ExeOutput= +ObjectOutput= +LogOutput= +LogOutputEnabled=0 +OverrideOutput=0 +OverrideOutputName= +HostApplication= +UseCustomMakefile=0 +CustomMakefile= +CommandLine= +Folders= +IncludeVersionInfo=0 +SupportXPThemes=0 +CompilerSet=1 +CompilerSettings=0000000000000000001000000 +UnitCount=4 + +[VersionInfo] +Major=1 +Minor=0 +Release=0 +Build=0 +LanguageID=1033 +CharsetID=1252 +CompanyName= +FileVersion= +FileDescription=Developed using the Dev-C++ IDE +InternalName= +LegalCopyright= +LegalTrademarks= +OriginalFilename= +ProductName= +ProductVersion= +AutoIncBuildNr=0 +SyncProduct=1 + +[Unit2] +FileName=SMatrix.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit1] +FileName=05.24.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit3] +FileName=SMatrix.h +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit4] +FileName=TestData_M.txt +Folder= +Compile=0 +Link=0 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + diff --git a/Dev-C++/ExerciseBook/05.24/SMatrix.cpp b/Dev-C++/ExerciseBook/05.24/SMatrix.cpp new file mode 100644 index 0000000..729641b --- /dev/null +++ b/Dev-C++/ExerciseBook/05.24/SMatrix.cpp @@ -0,0 +1,44 @@ +/*====================== + * ϡϰ5.24 + =======================*/ + +#include "SMatrix.h" //**ϡ**// + +// ϡM +Status CreateSMatrix(SMatrix* M, char* path) { + FILE* fp; + int k, i, j; + + fp = fopen(path, "r"); + + ReadData(fp, "%d%d%d", &((*M).mu), &((*M).nu), &((*M).tu)); + + // ȡԪ + for(k = 1; k <= (*M).tu; k++) { + ReadData(fp, "%d%d%d", &i, &j, &((*M).data[k].e)); + (*M).data[k].seq = (i - 1) * (*M).nu + j; + } + + fclose(fp); + + return OK; +} + +// ϡM +void PrintSMatrix(SMatrix M) { + int r, c; + int k = 1; + + for(r = 1; r <= M.mu; r++) { + for(c = 1; c <= M.nu; c++) { + if(r == (M.data[k].seq - 1) / M.nu + 1 && c == (M.data[k].seq - 1) % M.nu + 1) { + + printf("%3d ", M.data[k].e); + k++; + } else { + printf(" 0 "); + } + } + printf("\n"); + } +} diff --git a/Dev-C++/ExerciseBook/05.24/SMatrix.h b/Dev-C++/ExerciseBook/05.24/SMatrix.h new file mode 100644 index 0000000..5df069c --- /dev/null +++ b/Dev-C++/ExerciseBook/05.24/SMatrix.h @@ -0,0 +1,32 @@ +/*====================== + * ϡϰ5.24 + =======================*/ + +#ifndef SMATRIX_H +#define SMATRIX_H + +#include +#include "Status.h" //**01 **// + +#define MAXSIZE 100 // ԪֵΪ400 + +/* Ԫ */ +typedef struct { + int seq; // ÷ԪھеţΪ + int e; +} SElem; + +/* ϡ */ +typedef struct { + SElem data[MAXSIZE + 1]; // 洢Ԫأdata[0]δ + int mu, nu, tu; // ͷԪ +} SMatrix; + + +// ϡM +Status CreateSMatrix(SMatrix* M, char* path); + +// ϡM +void PrintSMatrix(SMatrix M); + +#endif diff --git a/Dev-C++/ExerciseBook/05.24/TestData_M.txt b/Dev-C++/ExerciseBook/05.24/TestData_M.txt new file mode 100644 index 0000000..be25c94 --- /dev/null +++ b/Dev-C++/ExerciseBook/05.24/TestData_M.txt @@ -0,0 +1,4 @@ +5 +5 +Ԫ10 +Ԫ飺(1,2,1),(1,4,5),(2,3,-3),(2,5,2),(3,1,2),(3,2,3),(3,3,4),(4,4,2),(5,1,3),(5,2,-1) \ No newline at end of file diff --git a/Dev-C++/ExerciseBook/05.25/05.25.cpp b/Dev-C++/ExerciseBook/05.25/05.25.cpp new file mode 100644 index 0000000..9851d07 --- /dev/null +++ b/Dev-C++/ExerciseBook/05.25/05.25.cpp @@ -0,0 +1,79 @@ +#include +#include "Status.h" //**01 **// +#include "SMatrix.h" //**ϡ**// + +/* + * ϡӷAddSMatrix + */ +Status Algo_5_25(SMatrix P, SMatrix Q, SMatrix* R); + + +int main(int argc, char* argv[]) { + SMatrix M, N, Q; + + printf(" ϡ MN ...\n"); + CreateSMatrix(&M, "TestData_M.txt"); + CreateSMatrix(&N, "TestData_N.txt"); + printf(" M = \n"); + PrintSMatrix(M); + printf(" N = \n"); + PrintSMatrix(N); + + Algo_5_25(M, N, &Q); + printf("Q = M + N = \n"); + PrintSMatrix(Q); + + return 0; +} + + +/* + * ϡӷAddSMatrix + */ +Status Algo_5_25(SMatrix P, SMatrix Q, SMatrix* R) { + int i, j; + int p, q, r; + + if(P.mu != Q.mu || P.nu != Q.nu) { + printf("\n"); + return ERROR; + } + + // ʼRϢ + (*R).mu = P.mu; + (*R).nu = P.nu; + (*R).tu = 0; + memset((*R).V, 0, sizeof((*R).V)); + memset((*R).B, 0, sizeof((*R).B)); + + // ָPQRеV + p = q = r = 0; + + for(i = 0; i < P.mu; ++i) { + for(j = 0; j < P.nu; ++j) { + if(P.B[i][j] == 0 && Q.B[i][j] == 0) { + continue; + } else if(P.B[i][j] == 0 && Q.B[i][j] == 1) { + (*R).V[r++] = Q.V[q++]; + (*R).B[i][j] = 1; + } else if(P.B[i][j] == 1 && Q.B[i][j] == 0) { + (*R).V[r++] = P.V[p++]; + (*R).B[i][j] = 1; + + // PQзԪ + } else { + if((P.V[p] + Q.V[q])!=0) { + (*R).V[r++] = P.V[p] + Q.V[q]; + (*R).B[i][j] = 1; + } + + p++; + q++; + } + } + } + + (*R).tu = r; + + return OK; +} diff --git a/Dev-C++/ExerciseBook/05.25/05.25.dev b/Dev-C++/ExerciseBook/05.25/05.25.dev new file mode 100644 index 0000000..b40407a --- /dev/null +++ b/Dev-C++/ExerciseBook/05.25/05.25.dev @@ -0,0 +1,100 @@ +[Project] +FileName=05.25.dev +Name=05.25 +Type=1 +Ver=2 +ObjFiles= +Includes= +Libs= +PrivateResource= +ResourceIncludes= +MakeIncludes= +Compiler= +CppCompiler= +Linker= +IsCpp=0 +Icon= +ExeOutput= +ObjectOutput= +LogOutput= +LogOutputEnabled=0 +OverrideOutput=0 +OverrideOutputName= +HostApplication= +UseCustomMakefile=0 +CustomMakefile= +CommandLine= +Folders= +IncludeVersionInfo=0 +SupportXPThemes=0 +CompilerSet=1 +CompilerSettings=0000000000000000001000000 +UnitCount=5 + +[VersionInfo] +Major=1 +Minor=0 +Release=0 +Build=0 +LanguageID=1033 +CharsetID=1252 +CompanyName= +FileVersion= +FileDescription=Developed using the Dev-C++ IDE +InternalName= +LegalCopyright= +LegalTrademarks= +OriginalFilename= +ProductName= +ProductVersion= +AutoIncBuildNr=0 +SyncProduct=1 + +[Unit1] +FileName=05.25.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit2] +FileName=SMatrix.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit3] +FileName=SMatrix.h +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit4] +FileName=TestData_M.txt +Folder= +Compile=0 +Link=0 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit5] +FileName=TestData_N.txt +Folder= +Compile=0 +Link=0 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + diff --git a/Dev-C++/ExerciseBook/05.25/SMatrix.cpp b/Dev-C++/ExerciseBook/05.25/SMatrix.cpp new file mode 100644 index 0000000..aaef587 --- /dev/null +++ b/Dev-C++/ExerciseBook/05.25/SMatrix.cpp @@ -0,0 +1,48 @@ +/*====================== + * ϡϰ5.25 + =======================*/ + +#include "SMatrix.h" //**ϡ**// + +// ϡM +Status CreateSMatrix(SMatrix* M, char* path) { + FILE* fp; + int v, i, j; + + fp = fopen(path, "r"); + + ReadData(fp, "%d%d%d", &((*M).mu), &((*M).nu), &((*M).tu)); + + memset((*M).V, 0, sizeof((*M).V)); + memset((*M).B, 0, sizeof((*M).B)); + + for(v=0; v < (*M).tu; v++) { + // ȡԪϢԪشV + ReadData(fp, "%d%d%d", &i, &j, &((*M).V[v])); + + (*M).B[i-1][j-1] = 1; + } + + fclose(fp); + + return OK; +} + +// ϡM +void PrintSMatrix(SMatrix M) { + int v, i, j; + + v = 0; // Vα + + for(i = 1; i <= M.mu; i++) { + for(j = 1; j <= M.nu; j++) { + if(M.B[i-1][j-1] == 1) { + printf("%3d ", M.V[v++]); + } else { + printf("%3d ", M.B[i-1][j-1]); + } + } + + printf("\n"); + } +} diff --git a/Dev-C++/ExerciseBook/05.25/SMatrix.h b/Dev-C++/ExerciseBook/05.25/SMatrix.h new file mode 100644 index 0000000..6ad263d --- /dev/null +++ b/Dev-C++/ExerciseBook/05.25/SMatrix.h @@ -0,0 +1,32 @@ +/*====================== + * ϡϰ5.25 + =======================*/ + +#ifndef SMATRIX_H +#define SMATRIX_H + +#include +#include +#include +#include "Status.h" //**01 **// + +/* 궨 */ +#define Mu 20 // ֵΪ20 +#define Nu 20 // ֵΪ20 +#define MAXSIZE 400 // ԪֵΪ400 + +/* ϡͶ */ +typedef struct { + int V[MAXSIZE]; // 洢Ԫ + int B[Mu][Nu]; // ǾиλԪǷΪԪ + int mu, nu, tu; // Ԫ +} SMatrix; + + +// ϡM +Status CreateSMatrix(SMatrix* M, char* path); + +// ϡM +void PrintSMatrix(SMatrix M); + +#endif diff --git a/Dev-C++/ExerciseBook/05.25/TestData_M.txt b/Dev-C++/ExerciseBook/05.25/TestData_M.txt new file mode 100644 index 0000000..be25c94 --- /dev/null +++ b/Dev-C++/ExerciseBook/05.25/TestData_M.txt @@ -0,0 +1,4 @@ +5 +5 +Ԫ10 +Ԫ飺(1,2,1),(1,4,5),(2,3,-3),(2,5,2),(3,1,2),(3,2,3),(3,3,4),(4,4,2),(5,1,3),(5,2,-1) \ No newline at end of file diff --git a/Dev-C++/ExerciseBook/05.25/TestData_N.txt b/Dev-C++/ExerciseBook/05.25/TestData_N.txt new file mode 100644 index 0000000..7c940db --- /dev/null +++ b/Dev-C++/ExerciseBook/05.25/TestData_N.txt @@ -0,0 +1,4 @@ +5 +5 +Ԫ8 +Ԫ飺(1,1,-3)(1,3,2)(2,4,-1)(3,2,4)(4,1,6)(4,5,5)(5,1,3)(5,3,2) \ No newline at end of file diff --git a/Dev-C++/ExerciseBook/05.26/05.26.cpp b/Dev-C++/ExerciseBook/05.26/05.26.cpp new file mode 100644 index 0000000..a2146d0 --- /dev/null +++ b/Dev-C++/ExerciseBook/05.26/05.26.cpp @@ -0,0 +1,49 @@ +#include +#include "Status.h" //**01 **// +#include "CrossList.h" //**05 ͹**// + +/* + * Ԫʽʮ + */ +Status Algo_5_26(CrossList M); + + +int main(int argc, char* argv[]) { + CrossList M; + + printf("ʮ M...\n"); + CreateSMatrix(&M, "TestData_M.txt"); + printf("M = \n"); + PrintSMatrix(M); + + printf("Ԫʽ M...\n"); + printf(" ֵ\n"); + Algo_5_26(M); + + return 0; +} + + +/* + * Ԫʽʮ + */ +Status Algo_5_26(CrossList M) { + int i, j; + OLNode* p; + + if(M.tu==0) { + return ERROR; + } + + for(i = 1; i <= M.mu; ++i) { + p = M.rhead[i]; + for(j = 1; j <= M.nu; ++j) { + if(p && p->j == j) { + printf("(%2d %2d %3d)\n", i, j, p->e); + p = p->right; + } + } + } + + return OK; +} diff --git a/Dev-C++/ExerciseBook/05.26/05.26.dev b/Dev-C++/ExerciseBook/05.26/05.26.dev new file mode 100644 index 0000000..6d925d3 --- /dev/null +++ b/Dev-C++/ExerciseBook/05.26/05.26.dev @@ -0,0 +1,91 @@ +[Project] +FileName=05.26.dev +Name=05.26 +Type=1 +Ver=2 +ObjFiles= +Includes= +Libs= +PrivateResource= +ResourceIncludes= +MakeIncludes= +Compiler= +CppCompiler= +Linker= +IsCpp=0 +Icon= +ExeOutput= +ObjectOutput= +LogOutput= +LogOutputEnabled=0 +OverrideOutput=0 +OverrideOutputName= +HostApplication= +UseCustomMakefile=0 +CustomMakefile= +CommandLine= +Folders= +IncludeVersionInfo=0 +SupportXPThemes=0 +CompilerSet=1 +CompilerSettings=0000000000000000001000000 +UnitCount=4 + +[VersionInfo] +Major=1 +Minor=0 +Release=0 +Build=0 +LanguageID=1033 +CharsetID=1252 +CompanyName= +FileVersion= +FileDescription=Developed using the Dev-C++ IDE +InternalName= +LegalCopyright= +LegalTrademarks= +OriginalFilename= +ProductName= +ProductVersion= +AutoIncBuildNr=0 +SyncProduct=1 + +[Unit2] +FileName=CrossList.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit1] +FileName=05.26.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit3] +FileName=CrossList.h +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit4] +FileName=TestData_M.txt +Folder= +Compile=0 +Link=0 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + diff --git a/Dev-C++/ExerciseBook/05.26/CrossList.cpp b/Dev-C++/ExerciseBook/05.26/CrossList.cpp new file mode 100644 index 0000000..07eb63d --- /dev/null +++ b/Dev-C++/ExerciseBook/05.26/CrossList.cpp @@ -0,0 +1,885 @@ +/*=================== + * ʮϡ + * + * 㷨: 5.4 + ====================*/ + +#include "CrossList.h" //**05 ͹**// + +/* + * 㷨5.4 + * + * ϡM + * + * + *ע + * + * ̲Ĭϴӿ̨ȡݡ + * Ϊ˷ԣÿжֶݣ + * ѡԤļpathжȡݡ + * + * Ҫӿ̨ȡݣpathΪNULLΪմ + * ҪļжȡݣҪpathдļϢ + */ +Status CreateSMatrix(CrossList* M, char* path) { + int i, j, k; + OLNode* p, * q; + FILE* fp; + int readFromConsole; // Ƿӿ̨ȡ + + // ûļ·Ϣӿ̨ȡ + readFromConsole = path == NULL || strcmp(path, "") == 0; + + if(readFromConsole) { + printf(""); + scanf("%d", &((*M).mu)); + printf(""); + scanf("%d", &((*M).nu)); + printf("Ԫظ"); + scanf("%d", &((*M).tu)); + printf("%dԪϢ\n", (*M).tu); + } else { + fp = fopen(path, "r"); + ReadData(fp, "%d%d%d", &((*M).mu), &((*M).nu), &((*M).tu)); + } + + // 0ŵԪã + (*M).rhead = (OLink*) malloc(((*M).mu + 1) * sizeof(OLink)); + if((*M).rhead == NULL) { + exit(OVERFLOW); + } + + // 0ŵԪã + (*M).chead = (OLink*) malloc(((*M).nu + 1) * sizeof(OLink)); + if((*M).chead == NULL) { + exit(OVERFLOW); + } + + // ʼΪNULL + for(k = 0; k <= (*M).mu; ++k) { + (*M).rhead[k] = NULL; + } + + // ʼΪNULL + for(k = 0; k <= (*M).nu; ++k) { + (*M).chead[k] = NULL; + } + + // ¼Ԫ + for(k = 1; k <= (*M).tu; ++k) { + // Ԫ + p = (OLNode*) malloc(sizeof(OLNode)); + if(p == NULL) { + exit(OVERFLOW); + } + + if(readFromConsole) { + printf("%2d飺", k); + scanf("%d%d%d", &i, &j, &(p->e)); + } else { + ReadData(fp, "%d%d%d", &i, &j, &(p->e)); + } + + p->i = i; // к + p->j = j; // к + p->right = p->down = NULL; + + /* + * ʼеIJ + */ + + // лûԪأԪؾλڸԪҲֱ࣬Ӳ + if((*M).rhead[i] == NULL || (*M).rhead[i]->j > j) { + // λбеIJλ + p->right = (*M).rhead[i]; + (*M).rhead[i] = p; + } else { + // ѰҲλõǰһλ + for(q = (*M).rhead[i]; (q->right) && (q->right->j < j); q = q->right) { + } + + if(q->j == p->j || ((q->right) && q->right->j == p->j)) { + printf("λѱռã\n"); + exit(ERROR); + } + + p->right = q->right; + q->right = p; + } + + /* + * ʼеIJ + */ + + // лûԪأԪؾλڸԪ²ֱ࣬Ӳ + if((*M).chead[j] == NULL || (*M).chead[j]->i > i) { + // λбеIJλ + p->down = (*M).chead[j]; + (*M).chead[j] = p; + } else { + // ѰҲλõǰһλ + for(q = (*M).chead[j]; (q->down) && (q->down->i < i); q = q->down) { + } + + if(q->i == p->i || ((q->down) && q->down->i == p->i)) { + printf("λѱռã\n"); + exit(ERROR); + } + + p->down = q->down; + q->down = p; + } + } + + if(!readFromConsole) { + fclose(fp); + } + + return OK; +} + +/* + * ϡ + */ +Status DestroySMatrix(CrossList* M) { + int i; + OLNode* p, * q; + + // ۴ӰлǰУֻҪһȥپͿ + for(i = 1; i <= (*M).mu; ++i) { + p = (*M).rhead[i]; + while(p != NULL) { + q = p; + p = p->right; + free(q); + } + } + + free((*M).rhead); + free((*M).chead); + + (*M).rhead = (*M).chead = NULL; + (*M).mu = (*M).nu = (*M).tu = 0; + + return OK; +} + +/* + * + * + * һ¾Tþ˴ӾMаݡ + */ +Status CopySMatrix(CrossList M, CrossList* T) { + int k; + OLNode* p, * q, * r, * l; + + if(T == NULL) { + return ERROR; + } + + // Ϣ + (*T).mu = M.mu; + (*T).nu = M.nu; + (*T).tu = M.tu; + + // 0ŵԪã + (*T).rhead = (OLink*) malloc(((*T).mu + 1) * sizeof(OLink)); + if((*T).rhead == NULL) { + exit(OVERFLOW); + } + + // 0ŵԪã + (*T).chead = (OLink*) malloc(((*T).nu + 1) * sizeof(OLink)); + if((*T).chead == NULL) { + exit(OVERFLOW); + } + + // ʼΪNULL + for(k = 0; k <= (*T).mu; ++k) { //ʼͷָΪ + (*T).rhead[k] = NULL; + } + + // ʼΪNULL + for(k = 0; k <= (*T).nu; ++k) { + (*T).chead[k] = NULL; + } + + // ɨ裬θƷԪ + for(k = 1; k <= M.mu; ++k) { + q = M.rhead[k]; + + // ǰûԪأֱ + if(q == NULL) { + continue; + } + + r = NULL; + + while(q != NULL) { + // Ԫ + p = (OLNode*) malloc(sizeof(OLNode)); + if(p == NULL) { + exit(OVERFLOW); + } + + // Ϊ㸳ֵ + p->i = q->i; + p->j = q->j; + p->e = q->e; + p->right = p->down = NULL; + + /* + * ʼеIJ + */ + + if(r == NULL) { + (*T).rhead[q->i] = p; + } else { + r->right = p; + } + + // rָǰ²Ľ + r = p; + + /* + * ʼеIJ + */ + + // ѰҲλ + if((*T).chead[q->j] == NULL || (*T).chead[q->j]->i > q->i) { + r->down = (*T).chead[q->j]; + (*T).chead[q->j] = r; + } else { + // ѰҲλõǰһλ + for(l = (*T).chead[q->j]; (l->down) && (l->down->i < q->i); l = l->down) { + } + r->down = l->down; + l->down = r; + } + + q = q->right; + } + } + + return OK; +} + +/* + * ӷ + * + * Q = M + N + */ +Status AddSMatrix(CrossList M, CrossList N, CrossList* Q) { + int i; + OLNode* pm, * pn, * p, * r, * l; + + if(M.mu != N.mu || M.nu != N.nu) { + printf("\n"); + return ERROR; + } + + // ʼQϢ + Q->mu = M.mu; + Q->nu = M.nu; + Q->tu = 0; + + // 0ŵԪã + Q->rhead = (OLink*) malloc((Q->mu + 1) * sizeof(OLink)); + if(!Q->rhead) { + exit(OVERFLOW); + } + + // 0ŵԪã + Q->chead = (OLink*) malloc((Q->nu + 1) * sizeof(OLink)); + if(!Q->chead) { + exit(OVERFLOW); + } + + // ʼΪNULL + for(i = 0; i <= Q->mu; ++i) { + Q->rhead[i] = NULL; + } + + // ʼΪNULL + for(i = 0; i <= Q->nu; ++i) { + Q->chead[i] = NULL; + } + + // ӵһ± + for(i = 1; i <= M.mu; ++i) { + pm = M.rhead[i]; + pn = N.rhead[i]; + + // MNĵǰоδķԪ + while(pm != NULL && pn != NULL) { + // + if(pm->j == pn->j && pm->e + pn->e == 0) { + pm = pm->right; + pn = pn->right; + continue; + } + + // + p = (OLNode*) malloc(sizeof(OLNode)); + if(!p) { + exit(OVERFLOW); + } + + // MеԪ±С + if(pm->j < pn->j) { + p->i = pm->i; + p->j = pm->j; + p->e = pm->e; + pm = pm->right; + + // NеԪ±С + } else if(pm->j > pn->j) { + p->i = pn->i; + p->j = pn->j; + p->e = pn->e; + pn = pn->right; + + // MNеԪ±һ£Ҫмӷ + } else { + p->i = pm->i; + p->j = pm->j; + p->e = pm->e + pn->e; + pm = pm->right; + pn = pn->right; + } + + p->right = p->down = NULL; + + Q->tu++; // QзԪһ + + /* + * ʼеIJ + */ + + if(Q->rhead[p->i] == NULL) { + Q->rhead[p->i] = p; + } else { + r->right = p; + } + + // rָǰ²Ľ + r = p; + + /* + * ʼеIJ + */ + + // ѰҲλ + if(Q->chead[p->j] == NULL || Q->chead[p->j]->i > p->i) { + r->down = Q->chead[p->j]; + Q->chead[p->j] = r; + } else { + // ѰҲλõǰһλ + for(l = Q->chead[p->j]; (l->down) && (l->down->i < p->i); l = l->down) { + } + r->down = l->down; + l->down = r; + } + } + + // MĵǰδķԪ + while(pm != NULL) { + p = (OLNode*) malloc(sizeof(OLNode)); + if(p == NULL) { + exit(OVERFLOW); + } + p->i = pm->i; + p->j = pm->j; + p->e = pm->e; + p->right = p->down = NULL; + + Q->tu++; // QзԪһ + + if(Q->rhead[p->i] == NULL) { + Q->rhead[p->i] = p; + } else { + r->right = p; + } + + // rָǰ²Ľ + r = p; + + // ѰҲλ + if(Q->chead[p->j] == NULL || Q->chead[p->j]->i > p->i) { + r->down = Q->chead[p->j]; + Q->chead[p->j] = r; + } else { + // ѰҲλõǰһλ + for(l = Q->chead[p->j]; (l->down) && (l->down->i < p->i); l = l->down) { + } + r->down = l->down; + l->down = r; + } + + pm = pm->right; + } + + // NĵǰδķԪ + while(pn != NULL) { + p = (OLNode*) malloc(sizeof(OLNode)); + if(p == NULL) { + exit(OVERFLOW); + } + p->i = pn->i; + p->j = pn->j; + p->e = pn->e; + p->right = p->down = NULL; + + Q->tu++; // QзԪһ + + if(Q->rhead[p->i] == NULL) { + Q->rhead[p->i] = p; + } else { + r->right = p; + } + + // rָǰ²Ľ + r = p; + + // ѰҲλ + if(Q->chead[p->j] == NULL || Q->chead[p->j]->i > p->i) { + r->down = Q->chead[p->j]; + Q->chead[p->j] = r; + } else { + // ѰҲλõǰһλ + for(l = Q->chead[p->j]; (l->down) && (l->down->i < p->i); l = l->down) { + } + r->down = l->down; + l->down = r; + } + + pn = pn->right; + } + } + + return OK; +} + +/* + * + * + * Q = M - N + */ +Status SubSMatrix(CrossList M, CrossList N, CrossList* Q) { + int i; + OLNode* pm, * pn, * p, * r, * l; + + if(M.mu != N.mu || M.nu != N.nu) { + printf("\n"); + return ERROR; + } + + // ʼQϢ + Q->mu = M.mu; + Q->nu = M.nu; + Q->tu = 0; + + // 0ŵԪã + Q->rhead = (OLink*) malloc((Q->mu + 1) * sizeof(OLink)); + if(!Q->rhead) { + exit(OVERFLOW); + } + + // 0ŵԪã + Q->chead = (OLink*) malloc((Q->nu + 1) * sizeof(OLink)); + if(!Q->chead) { + exit(OVERFLOW); + } + + // ʼΪNULL + for(i = 0; i <= Q->mu; ++i) { + Q->rhead[i] = NULL; + } + + // ʼΪNULL + for(i = 0; i <= Q->nu; ++i) { + Q->chead[i] = NULL; + } + + // ӵһ± + for(i = 1; i <= M.mu; ++i) { + pm = M.rhead[i]; + pn = N.rhead[i]; + + // MNĵǰоδķԪ + while(pm != NULL && pn != NULL) { + // + if(pm->j == pn->j && pm->e - pn->e == 0) { + pm = pm->right; + pn = pn->right; + continue; + } + + // + p = (OLNode*) malloc(sizeof(OLNode)); + if(!p) { + exit(OVERFLOW); + } + + // MеԪ±С + if(pm->j < pn->j) { + p->i = pm->i; + p->j = pm->j; + p->e = pm->e; + pm = pm->right; + + // NеԪ±С + } else if(pm->j > pn->j) { + p->i = pn->i; + p->j = pn->j; + p->e = -pn->e; // Ӹ + pn = pn->right; + + // MNеԪ±һ£Ҫм + } else { + p->i = pm->i; + p->j = pm->j; + p->e = pm->e - pn->e; + pm = pm->right; + pn = pn->right; + } + + p->right = p->down = NULL; + + Q->tu++; // QзԪһ + + /* + * ʼеIJ + */ + + if(Q->rhead[p->i] == NULL) { + Q->rhead[p->i] = p; + } else { + r->right = p; + } + + // rָǰ²Ľ + r = p; + + /* + * ʼеIJ + */ + + // ѰҲλ + if(Q->chead[p->j] == NULL || Q->chead[p->j]->i > p->i) { + r->down = Q->chead[p->j]; + Q->chead[p->j] = r; + } else { + //ѰҲλõǰһλ + for(l = Q->chead[p->j]; (l->down) && (l->down->i < p->i); l = l->down) { + } + r->down = l->down; + l->down = r; + } + } + + // MĵǰδķԪ + while(pm != NULL) { + p = (OLNode*) malloc(sizeof(OLNode)); + if(!p) { + exit(OVERFLOW); + } + p->i = pm->i; + p->j = pm->j; + p->e = pm->e; + p->right = p->down = NULL; + + Q->tu++; // QзԪһ + + if(Q->rhead[p->i] == NULL) { + Q->rhead[p->i] = p; + } else { + r->right = p; + } + + // rָǰ²Ľ + r = p; + + // ѰҲλ + if(Q->chead[p->j] == NULL || Q->chead[p->j]->i > p->i) { + r->down = Q->chead[p->j]; + Q->chead[p->j] = r; + } else { + // ѰҲλõǰһλ + for(l = Q->chead[p->j]; (l->down) && (l->down->i < p->i); l = l->down) { + } + r->down = l->down; + l->down = r; + } + + pm = pm->right; + } + + // NĵǰδķԪ + while(pn != NULL) { + p = (OLNode*) malloc(sizeof(OLNode)); + if(!p) { + exit(OVERFLOW); + } + p->i = pn->i; + p->j = pn->j; + p->e = -pn->e; // Ӹ + p->right = p->down = NULL; + + Q->tu++; // QзԪһ + + if(Q->rhead[p->i] == NULL) { + Q->rhead[p->i] = p; + } else { + r->right = p; + } + + // rָǰ²Ľ + r = p; + + // ѰҲλ + if(Q->chead[p->j] == NULL || Q->chead[p->j]->i > p->i) { + r->down = Q->chead[p->j]; + Q->chead[p->j] = r; + } else { + // ѰҲλõǰһλ + for(l = Q->chead[p->j]; (l->down) && (l->down->i < p->i); l = l->down) { + } + r->down = l->down; + l->down = r; + } + + pn = pn->right; + } + } + + return OK; +} + +/* + * ˷ + * + * Q = M * N + */ +Status MultSMatrix(CrossList M, CrossList N, CrossList* Q) { + int m_row, n_col, i; + ElemType e; + OLNode* pm, * pn, * p, * r, * l; + + // MҪN + if(M.nu != N.mu) { + printf("\n"); + return ERROR; + } + + // ʼQϢ + Q->mu = M.mu; + Q->nu = N.nu; + Q->tu = 0; + + // 0ŵԪã + Q->rhead = (OLink*) malloc((Q->mu + 1) * sizeof(OLink)); + if(!Q->rhead) { + exit(OVERFLOW); + } + + // 0ŵԪã + Q->chead = (OLink*) malloc((Q->nu + 1) * sizeof(OLink)); + if(!Q->chead) { + exit(OVERFLOW); + } + + // ʼΪNULL + for(i = 0; i <= Q->mu; ++i) { + Q->rhead[i] = NULL; + } + + // ʼΪNULL + for(i = 0; i <= Q->nu; ++i) { + Q->chead[i] = NULL; + } + + // QǷ + if(M.tu * N.tu) { + for(m_row = 1; m_row <= M.mu; ++m_row) { + for(n_col = 1; n_col <= N.nu; ++n_col) { + pm = M.rhead[m_row]; + pn = N.chead[n_col]; + + e = 0; + + // MN + while(pm && pn) { + if(pm->j < pn->i) { + pm = pm->right; + } else if(pm->j > pn->i) { + pn = pn->down; + } else { + e += pm->e * pn->e; + pm = pm->right; + pn = pn->down; + } + } + + if(e == 0) { + continue; + } + + p = (OLNode*) malloc(sizeof(OLNode)); + if(!p) { + exit(OVERFLOW); + } + + // Ϊ㸳ֵ + p->i = M.rhead[m_row]->i; + p->j = N.chead[n_col]->j; + p->e = e; + p->right = p->down = NULL; + + Q->tu++; // QзԪһ + + if(Q->rhead[p->i] == NULL) { + Q->rhead[p->i] = p; + } else { + r->right = p; + } + + // rָǰ²Ľ + r = p; + + // ѰҲλ + if(Q->chead[p->j] == NULL || Q->chead[p->j]->i > p->i) { + r->down = Q->chead[p->j]; + Q->chead[p->j] = r; + } else { + // ѰҲλõǰһλ + for(l = Q->chead[p->j]; (l->down) && (l->down->i < p->i); l = l->down) { + } + + r->down = l->down; + l->down = r; + } + } + } + } + + return OK; +} + +/* + * ת + */ +Status TransposeSMatrix(CrossList M, CrossList* T) { + int i; + OLNode* p, * q, * r, * l; + + // ʼQϢ + (*T).mu = M.nu; + (*T).nu = M.mu; + (*T).tu = M.tu; + + // 0ŵԪã + (*T).rhead = (OLink*) malloc(((*T).mu + 1) * sizeof(OLink)); + if(!(*T).rhead) { + exit(OVERFLOW); + } + + // 0ŵԪã + (*T).chead = (OLink*) malloc(((*T).nu + 1) * sizeof(OLink)); + if(!(*T).chead) { + exit(OVERFLOW); + } + + // ʼΪNULL + for(i = 0; i <= (*T).mu; ++i) { + (*T).rhead[i] = NULL; + } + + // ʼΪNULL + for(i = 0; i <= (*T).nu; ++i) { + (*T).chead[i] = NULL; + } + + // + if(!(*T).tu) { + return OK; + } + + // ɨ + for(i = 1; i <= M.nu; ++i) { + q = M.chead[i]; + + // ǰûԪأֱ + if(q == NULL) { + continue; + } + + while(q != NULL) { + // Ԫ + p = (OLNode*) malloc(sizeof(OLNode)); + if(!p) { + exit(OVERFLOW); + } + + // Ϊ㸳ֵбУб + p->i = q->j; + p->j = q->i; + p->e = q->e; + p->right = p->down = NULL; + + /* + * ʼеIJ + */ + + if((*T).rhead[p->i] == NULL) { + (*T).rhead[p->i] = p; + } else { + r->right = p; + } + + // rָǰ²Ľ + r = p; + + /* + * ʼеIJ + */ + + // ѰҲλ + if((*T).chead[p->j] == NULL || (*T).chead[p->j]->i > p->i) { + r->down = (*T).chead[p->j]; + (*T).chead[p->j] = r; + } else { + // ѰҲλõǰһλ + for(l = (*T).chead[p->j]; (l->down) && (l->down->i < p->i); l = l->down) { + } + r->down = l->down; + l->down = r; + } + + q = q->down; + } + } + + return OK; +} + +/* + * + */ +void PrintSMatrix(CrossList M) { + int i, j; + OLNode* p; + + for(i = 1; i <= M.mu; ++i) { + p = M.rhead[i]; + for(j = 1; j <= M.nu; ++j) { + if(p && p->j == j) { + printf("%3d ", p->e); + p = p->right; + } else { + printf("%3d ", 0); + } + } + printf("\n"); + } +} diff --git a/Dev-C++/ExerciseBook/05.26/CrossList.h b/Dev-C++/ExerciseBook/05.26/CrossList.h new file mode 100644 index 0000000..c774280 --- /dev/null +++ b/Dev-C++/ExerciseBook/05.26/CrossList.h @@ -0,0 +1,94 @@ +/*=================== + * ʮϡ + * + * 㷨: 5.4 + ====================*/ + +#ifndef CROSSLIST_H +#define CROSSLIST_H + +#include +#include // ṩmallocreallocfreeexitԭ +#include // ṩ strstr ԭ +#include "Status.h" //**01 **// + +/* ʮԪ */ +typedef int ElemType; + +/* ԪͶ */ +typedef struct OLNode { + int i, j; // ÷Ԫ±± + ElemType e; + struct OLNode* right; // ÷Ԫڵбĺ + struct OLNode* down; // ÷Ԫڵбĺ +} OLNode, * OLink; + +/* ʮͶ */ +typedef struct { + OLink* rhead; // ͷָ + OLink* chead; // ͷָ + int mu, nu, tu; // ͷԪ +} CrossList; + + +/* + * 㷨5.4 + * + * ϡM + * + * + *ע + * + * ̲Ĭϴӿ̨ȡݡ + * Ϊ˷ԣÿжֶݣ + * ѡԤļpathжȡݡ + * + * Ҫӿ̨ȡݣpathΪNULLΪմ + * ҪļжȡݣҪpathдļϢ + */ +Status CreateSMatrix(CrossList* M, char* path); + +/* + * ϡ + */ +Status DestroySMatrix(CrossList* M); + +/* + * + * + * һ¾Tþ˴ӾMаݡ + */ +Status CopySMatrix(CrossList M, CrossList* T); + +/* + * ӷ + * + * Q = M + N + */ +Status AddSMatrix(CrossList M, CrossList N, CrossList* Q); + +/* + * + * + * Q = M - N + */ +Status SubSMatrix(CrossList M, CrossList N, CrossList* Q); + +/* + * ˷ + * + * Q = M * N + */ +Status MultSMatrix(CrossList M, CrossList N, CrossList* Q); + +/* + * ת + */ +Status TransposeSMatrix(CrossList M, CrossList* T); + +/* + * + */ +void PrintSMatrix(CrossList M); + +#endif diff --git a/Dev-C++/ExerciseBook/05.26/TestData_M.txt b/Dev-C++/ExerciseBook/05.26/TestData_M.txt new file mode 100644 index 0000000..be25c94 --- /dev/null +++ b/Dev-C++/ExerciseBook/05.26/TestData_M.txt @@ -0,0 +1,4 @@ +5 +5 +Ԫ10 +Ԫ飺(1,2,1),(1,4,5),(2,3,-3),(2,5,2),(3,1,2),(3,2,3),(3,3,4),(4,4,2),(5,1,3),(5,2,-1) \ No newline at end of file diff --git a/Dev-C++/ExerciseBook/05.27/05.27.cpp b/Dev-C++/ExerciseBook/05.27/05.27.cpp new file mode 100644 index 0000000..c3015d0 --- /dev/null +++ b/Dev-C++/ExerciseBook/05.27/05.27.cpp @@ -0,0 +1,41 @@ +#include +#include "Status.h" //**01 **// +#include "CrossList.h" //**05 ͹**// + +/* + * ϡӷAddSMatrix + * + *ע + * úCrossListļж + */ +Status Algo_5_27(CrossList M, CrossList N, CrossList* Q); + + +int main(int argc, char* argv[]) { + CrossList M, N, Q; + + printf(" ϡ MN ...\n"); + CreateSMatrix(&M, "TestData_M.txt"); + CreateSMatrix(&N, "TestData_N.txt"); + printf(" M = \n"); + PrintSMatrix(M); + printf(" N = \n"); + PrintSMatrix(N); + + Algo_5_27(M, N, &Q); + printf(" Q = M + N = \n"); + PrintSMatrix(Q); + + return 0; +} + + +/* + * ϡӷAddSMatrix + * + *ע + * úCrossListļж + */ +Status Algo_5_27(CrossList M, CrossList N, CrossList* Q) { + return AddSMatrix(M, N, Q); +} diff --git a/Dev-C++/ExerciseBook/05.27/05.27.dev b/Dev-C++/ExerciseBook/05.27/05.27.dev new file mode 100644 index 0000000..2845795 --- /dev/null +++ b/Dev-C++/ExerciseBook/05.27/05.27.dev @@ -0,0 +1,100 @@ +[Project] +FileName=05.27.dev +Name=05.27 +Type=1 +Ver=2 +ObjFiles= +Includes= +Libs= +PrivateResource= +ResourceIncludes= +MakeIncludes= +Compiler= +CppCompiler= +Linker= +IsCpp=0 +Icon= +ExeOutput= +ObjectOutput= +LogOutput= +LogOutputEnabled=0 +OverrideOutput=0 +OverrideOutputName= +HostApplication= +UseCustomMakefile=0 +CustomMakefile= +CommandLine= +Folders= +IncludeVersionInfo=0 +SupportXPThemes=0 +CompilerSet=1 +CompilerSettings=0000000000000000001000000 +UnitCount=5 + +[VersionInfo] +Major=1 +Minor=0 +Release=0 +Build=0 +LanguageID=1033 +CharsetID=1252 +CompanyName= +FileVersion= +FileDescription=Developed using the Dev-C++ IDE +InternalName= +LegalCopyright= +LegalTrademarks= +OriginalFilename= +ProductName= +ProductVersion= +AutoIncBuildNr=0 +SyncProduct=1 + +[Unit2] +FileName=CrossList.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit1] +FileName=05.27.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit3] +FileName=CrossList.h +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit4] +FileName=TestData_M.txt +Folder= +Compile=0 +Link=0 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit5] +FileName=TestData_N.txt +Folder= +Compile=0 +Link=0 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + diff --git a/Dev-C++/ExerciseBook/05.27/CrossList.cpp b/Dev-C++/ExerciseBook/05.27/CrossList.cpp new file mode 100644 index 0000000..07eb63d --- /dev/null +++ b/Dev-C++/ExerciseBook/05.27/CrossList.cpp @@ -0,0 +1,885 @@ +/*=================== + * ʮϡ + * + * 㷨: 5.4 + ====================*/ + +#include "CrossList.h" //**05 ͹**// + +/* + * 㷨5.4 + * + * ϡM + * + * + *ע + * + * ̲Ĭϴӿ̨ȡݡ + * Ϊ˷ԣÿжֶݣ + * ѡԤļpathжȡݡ + * + * Ҫӿ̨ȡݣpathΪNULLΪմ + * ҪļжȡݣҪpathдļϢ + */ +Status CreateSMatrix(CrossList* M, char* path) { + int i, j, k; + OLNode* p, * q; + FILE* fp; + int readFromConsole; // Ƿӿ̨ȡ + + // ûļ·Ϣӿ̨ȡ + readFromConsole = path == NULL || strcmp(path, "") == 0; + + if(readFromConsole) { + printf(""); + scanf("%d", &((*M).mu)); + printf(""); + scanf("%d", &((*M).nu)); + printf("Ԫظ"); + scanf("%d", &((*M).tu)); + printf("%dԪϢ\n", (*M).tu); + } else { + fp = fopen(path, "r"); + ReadData(fp, "%d%d%d", &((*M).mu), &((*M).nu), &((*M).tu)); + } + + // 0ŵԪã + (*M).rhead = (OLink*) malloc(((*M).mu + 1) * sizeof(OLink)); + if((*M).rhead == NULL) { + exit(OVERFLOW); + } + + // 0ŵԪã + (*M).chead = (OLink*) malloc(((*M).nu + 1) * sizeof(OLink)); + if((*M).chead == NULL) { + exit(OVERFLOW); + } + + // ʼΪNULL + for(k = 0; k <= (*M).mu; ++k) { + (*M).rhead[k] = NULL; + } + + // ʼΪNULL + for(k = 0; k <= (*M).nu; ++k) { + (*M).chead[k] = NULL; + } + + // ¼Ԫ + for(k = 1; k <= (*M).tu; ++k) { + // Ԫ + p = (OLNode*) malloc(sizeof(OLNode)); + if(p == NULL) { + exit(OVERFLOW); + } + + if(readFromConsole) { + printf("%2d飺", k); + scanf("%d%d%d", &i, &j, &(p->e)); + } else { + ReadData(fp, "%d%d%d", &i, &j, &(p->e)); + } + + p->i = i; // к + p->j = j; // к + p->right = p->down = NULL; + + /* + * ʼеIJ + */ + + // лûԪأԪؾλڸԪҲֱ࣬Ӳ + if((*M).rhead[i] == NULL || (*M).rhead[i]->j > j) { + // λбеIJλ + p->right = (*M).rhead[i]; + (*M).rhead[i] = p; + } else { + // ѰҲλõǰһλ + for(q = (*M).rhead[i]; (q->right) && (q->right->j < j); q = q->right) { + } + + if(q->j == p->j || ((q->right) && q->right->j == p->j)) { + printf("λѱռã\n"); + exit(ERROR); + } + + p->right = q->right; + q->right = p; + } + + /* + * ʼеIJ + */ + + // лûԪأԪؾλڸԪ²ֱ࣬Ӳ + if((*M).chead[j] == NULL || (*M).chead[j]->i > i) { + // λбеIJλ + p->down = (*M).chead[j]; + (*M).chead[j] = p; + } else { + // ѰҲλõǰһλ + for(q = (*M).chead[j]; (q->down) && (q->down->i < i); q = q->down) { + } + + if(q->i == p->i || ((q->down) && q->down->i == p->i)) { + printf("λѱռã\n"); + exit(ERROR); + } + + p->down = q->down; + q->down = p; + } + } + + if(!readFromConsole) { + fclose(fp); + } + + return OK; +} + +/* + * ϡ + */ +Status DestroySMatrix(CrossList* M) { + int i; + OLNode* p, * q; + + // ۴ӰлǰУֻҪһȥپͿ + for(i = 1; i <= (*M).mu; ++i) { + p = (*M).rhead[i]; + while(p != NULL) { + q = p; + p = p->right; + free(q); + } + } + + free((*M).rhead); + free((*M).chead); + + (*M).rhead = (*M).chead = NULL; + (*M).mu = (*M).nu = (*M).tu = 0; + + return OK; +} + +/* + * + * + * һ¾Tþ˴ӾMаݡ + */ +Status CopySMatrix(CrossList M, CrossList* T) { + int k; + OLNode* p, * q, * r, * l; + + if(T == NULL) { + return ERROR; + } + + // Ϣ + (*T).mu = M.mu; + (*T).nu = M.nu; + (*T).tu = M.tu; + + // 0ŵԪã + (*T).rhead = (OLink*) malloc(((*T).mu + 1) * sizeof(OLink)); + if((*T).rhead == NULL) { + exit(OVERFLOW); + } + + // 0ŵԪã + (*T).chead = (OLink*) malloc(((*T).nu + 1) * sizeof(OLink)); + if((*T).chead == NULL) { + exit(OVERFLOW); + } + + // ʼΪNULL + for(k = 0; k <= (*T).mu; ++k) { //ʼͷָΪ + (*T).rhead[k] = NULL; + } + + // ʼΪNULL + for(k = 0; k <= (*T).nu; ++k) { + (*T).chead[k] = NULL; + } + + // ɨ裬θƷԪ + for(k = 1; k <= M.mu; ++k) { + q = M.rhead[k]; + + // ǰûԪأֱ + if(q == NULL) { + continue; + } + + r = NULL; + + while(q != NULL) { + // Ԫ + p = (OLNode*) malloc(sizeof(OLNode)); + if(p == NULL) { + exit(OVERFLOW); + } + + // Ϊ㸳ֵ + p->i = q->i; + p->j = q->j; + p->e = q->e; + p->right = p->down = NULL; + + /* + * ʼеIJ + */ + + if(r == NULL) { + (*T).rhead[q->i] = p; + } else { + r->right = p; + } + + // rָǰ²Ľ + r = p; + + /* + * ʼеIJ + */ + + // ѰҲλ + if((*T).chead[q->j] == NULL || (*T).chead[q->j]->i > q->i) { + r->down = (*T).chead[q->j]; + (*T).chead[q->j] = r; + } else { + // ѰҲλõǰһλ + for(l = (*T).chead[q->j]; (l->down) && (l->down->i < q->i); l = l->down) { + } + r->down = l->down; + l->down = r; + } + + q = q->right; + } + } + + return OK; +} + +/* + * ӷ + * + * Q = M + N + */ +Status AddSMatrix(CrossList M, CrossList N, CrossList* Q) { + int i; + OLNode* pm, * pn, * p, * r, * l; + + if(M.mu != N.mu || M.nu != N.nu) { + printf("\n"); + return ERROR; + } + + // ʼQϢ + Q->mu = M.mu; + Q->nu = M.nu; + Q->tu = 0; + + // 0ŵԪã + Q->rhead = (OLink*) malloc((Q->mu + 1) * sizeof(OLink)); + if(!Q->rhead) { + exit(OVERFLOW); + } + + // 0ŵԪã + Q->chead = (OLink*) malloc((Q->nu + 1) * sizeof(OLink)); + if(!Q->chead) { + exit(OVERFLOW); + } + + // ʼΪNULL + for(i = 0; i <= Q->mu; ++i) { + Q->rhead[i] = NULL; + } + + // ʼΪNULL + for(i = 0; i <= Q->nu; ++i) { + Q->chead[i] = NULL; + } + + // ӵһ± + for(i = 1; i <= M.mu; ++i) { + pm = M.rhead[i]; + pn = N.rhead[i]; + + // MNĵǰоδķԪ + while(pm != NULL && pn != NULL) { + // + if(pm->j == pn->j && pm->e + pn->e == 0) { + pm = pm->right; + pn = pn->right; + continue; + } + + // + p = (OLNode*) malloc(sizeof(OLNode)); + if(!p) { + exit(OVERFLOW); + } + + // MеԪ±С + if(pm->j < pn->j) { + p->i = pm->i; + p->j = pm->j; + p->e = pm->e; + pm = pm->right; + + // NеԪ±С + } else if(pm->j > pn->j) { + p->i = pn->i; + p->j = pn->j; + p->e = pn->e; + pn = pn->right; + + // MNеԪ±һ£Ҫмӷ + } else { + p->i = pm->i; + p->j = pm->j; + p->e = pm->e + pn->e; + pm = pm->right; + pn = pn->right; + } + + p->right = p->down = NULL; + + Q->tu++; // QзԪһ + + /* + * ʼеIJ + */ + + if(Q->rhead[p->i] == NULL) { + Q->rhead[p->i] = p; + } else { + r->right = p; + } + + // rָǰ²Ľ + r = p; + + /* + * ʼеIJ + */ + + // ѰҲλ + if(Q->chead[p->j] == NULL || Q->chead[p->j]->i > p->i) { + r->down = Q->chead[p->j]; + Q->chead[p->j] = r; + } else { + // ѰҲλõǰһλ + for(l = Q->chead[p->j]; (l->down) && (l->down->i < p->i); l = l->down) { + } + r->down = l->down; + l->down = r; + } + } + + // MĵǰδķԪ + while(pm != NULL) { + p = (OLNode*) malloc(sizeof(OLNode)); + if(p == NULL) { + exit(OVERFLOW); + } + p->i = pm->i; + p->j = pm->j; + p->e = pm->e; + p->right = p->down = NULL; + + Q->tu++; // QзԪһ + + if(Q->rhead[p->i] == NULL) { + Q->rhead[p->i] = p; + } else { + r->right = p; + } + + // rָǰ²Ľ + r = p; + + // ѰҲλ + if(Q->chead[p->j] == NULL || Q->chead[p->j]->i > p->i) { + r->down = Q->chead[p->j]; + Q->chead[p->j] = r; + } else { + // ѰҲλõǰһλ + for(l = Q->chead[p->j]; (l->down) && (l->down->i < p->i); l = l->down) { + } + r->down = l->down; + l->down = r; + } + + pm = pm->right; + } + + // NĵǰδķԪ + while(pn != NULL) { + p = (OLNode*) malloc(sizeof(OLNode)); + if(p == NULL) { + exit(OVERFLOW); + } + p->i = pn->i; + p->j = pn->j; + p->e = pn->e; + p->right = p->down = NULL; + + Q->tu++; // QзԪһ + + if(Q->rhead[p->i] == NULL) { + Q->rhead[p->i] = p; + } else { + r->right = p; + } + + // rָǰ²Ľ + r = p; + + // ѰҲλ + if(Q->chead[p->j] == NULL || Q->chead[p->j]->i > p->i) { + r->down = Q->chead[p->j]; + Q->chead[p->j] = r; + } else { + // ѰҲλõǰһλ + for(l = Q->chead[p->j]; (l->down) && (l->down->i < p->i); l = l->down) { + } + r->down = l->down; + l->down = r; + } + + pn = pn->right; + } + } + + return OK; +} + +/* + * + * + * Q = M - N + */ +Status SubSMatrix(CrossList M, CrossList N, CrossList* Q) { + int i; + OLNode* pm, * pn, * p, * r, * l; + + if(M.mu != N.mu || M.nu != N.nu) { + printf("\n"); + return ERROR; + } + + // ʼQϢ + Q->mu = M.mu; + Q->nu = M.nu; + Q->tu = 0; + + // 0ŵԪã + Q->rhead = (OLink*) malloc((Q->mu + 1) * sizeof(OLink)); + if(!Q->rhead) { + exit(OVERFLOW); + } + + // 0ŵԪã + Q->chead = (OLink*) malloc((Q->nu + 1) * sizeof(OLink)); + if(!Q->chead) { + exit(OVERFLOW); + } + + // ʼΪNULL + for(i = 0; i <= Q->mu; ++i) { + Q->rhead[i] = NULL; + } + + // ʼΪNULL + for(i = 0; i <= Q->nu; ++i) { + Q->chead[i] = NULL; + } + + // ӵһ± + for(i = 1; i <= M.mu; ++i) { + pm = M.rhead[i]; + pn = N.rhead[i]; + + // MNĵǰоδķԪ + while(pm != NULL && pn != NULL) { + // + if(pm->j == pn->j && pm->e - pn->e == 0) { + pm = pm->right; + pn = pn->right; + continue; + } + + // + p = (OLNode*) malloc(sizeof(OLNode)); + if(!p) { + exit(OVERFLOW); + } + + // MеԪ±С + if(pm->j < pn->j) { + p->i = pm->i; + p->j = pm->j; + p->e = pm->e; + pm = pm->right; + + // NеԪ±С + } else if(pm->j > pn->j) { + p->i = pn->i; + p->j = pn->j; + p->e = -pn->e; // Ӹ + pn = pn->right; + + // MNеԪ±һ£Ҫм + } else { + p->i = pm->i; + p->j = pm->j; + p->e = pm->e - pn->e; + pm = pm->right; + pn = pn->right; + } + + p->right = p->down = NULL; + + Q->tu++; // QзԪһ + + /* + * ʼеIJ + */ + + if(Q->rhead[p->i] == NULL) { + Q->rhead[p->i] = p; + } else { + r->right = p; + } + + // rָǰ²Ľ + r = p; + + /* + * ʼеIJ + */ + + // ѰҲλ + if(Q->chead[p->j] == NULL || Q->chead[p->j]->i > p->i) { + r->down = Q->chead[p->j]; + Q->chead[p->j] = r; + } else { + //ѰҲλõǰһλ + for(l = Q->chead[p->j]; (l->down) && (l->down->i < p->i); l = l->down) { + } + r->down = l->down; + l->down = r; + } + } + + // MĵǰδķԪ + while(pm != NULL) { + p = (OLNode*) malloc(sizeof(OLNode)); + if(!p) { + exit(OVERFLOW); + } + p->i = pm->i; + p->j = pm->j; + p->e = pm->e; + p->right = p->down = NULL; + + Q->tu++; // QзԪһ + + if(Q->rhead[p->i] == NULL) { + Q->rhead[p->i] = p; + } else { + r->right = p; + } + + // rָǰ²Ľ + r = p; + + // ѰҲλ + if(Q->chead[p->j] == NULL || Q->chead[p->j]->i > p->i) { + r->down = Q->chead[p->j]; + Q->chead[p->j] = r; + } else { + // ѰҲλõǰһλ + for(l = Q->chead[p->j]; (l->down) && (l->down->i < p->i); l = l->down) { + } + r->down = l->down; + l->down = r; + } + + pm = pm->right; + } + + // NĵǰδķԪ + while(pn != NULL) { + p = (OLNode*) malloc(sizeof(OLNode)); + if(!p) { + exit(OVERFLOW); + } + p->i = pn->i; + p->j = pn->j; + p->e = -pn->e; // Ӹ + p->right = p->down = NULL; + + Q->tu++; // QзԪһ + + if(Q->rhead[p->i] == NULL) { + Q->rhead[p->i] = p; + } else { + r->right = p; + } + + // rָǰ²Ľ + r = p; + + // ѰҲλ + if(Q->chead[p->j] == NULL || Q->chead[p->j]->i > p->i) { + r->down = Q->chead[p->j]; + Q->chead[p->j] = r; + } else { + // ѰҲλõǰһλ + for(l = Q->chead[p->j]; (l->down) && (l->down->i < p->i); l = l->down) { + } + r->down = l->down; + l->down = r; + } + + pn = pn->right; + } + } + + return OK; +} + +/* + * ˷ + * + * Q = M * N + */ +Status MultSMatrix(CrossList M, CrossList N, CrossList* Q) { + int m_row, n_col, i; + ElemType e; + OLNode* pm, * pn, * p, * r, * l; + + // MҪN + if(M.nu != N.mu) { + printf("\n"); + return ERROR; + } + + // ʼQϢ + Q->mu = M.mu; + Q->nu = N.nu; + Q->tu = 0; + + // 0ŵԪã + Q->rhead = (OLink*) malloc((Q->mu + 1) * sizeof(OLink)); + if(!Q->rhead) { + exit(OVERFLOW); + } + + // 0ŵԪã + Q->chead = (OLink*) malloc((Q->nu + 1) * sizeof(OLink)); + if(!Q->chead) { + exit(OVERFLOW); + } + + // ʼΪNULL + for(i = 0; i <= Q->mu; ++i) { + Q->rhead[i] = NULL; + } + + // ʼΪNULL + for(i = 0; i <= Q->nu; ++i) { + Q->chead[i] = NULL; + } + + // QǷ + if(M.tu * N.tu) { + for(m_row = 1; m_row <= M.mu; ++m_row) { + for(n_col = 1; n_col <= N.nu; ++n_col) { + pm = M.rhead[m_row]; + pn = N.chead[n_col]; + + e = 0; + + // MN + while(pm && pn) { + if(pm->j < pn->i) { + pm = pm->right; + } else if(pm->j > pn->i) { + pn = pn->down; + } else { + e += pm->e * pn->e; + pm = pm->right; + pn = pn->down; + } + } + + if(e == 0) { + continue; + } + + p = (OLNode*) malloc(sizeof(OLNode)); + if(!p) { + exit(OVERFLOW); + } + + // Ϊ㸳ֵ + p->i = M.rhead[m_row]->i; + p->j = N.chead[n_col]->j; + p->e = e; + p->right = p->down = NULL; + + Q->tu++; // QзԪһ + + if(Q->rhead[p->i] == NULL) { + Q->rhead[p->i] = p; + } else { + r->right = p; + } + + // rָǰ²Ľ + r = p; + + // ѰҲλ + if(Q->chead[p->j] == NULL || Q->chead[p->j]->i > p->i) { + r->down = Q->chead[p->j]; + Q->chead[p->j] = r; + } else { + // ѰҲλõǰһλ + for(l = Q->chead[p->j]; (l->down) && (l->down->i < p->i); l = l->down) { + } + + r->down = l->down; + l->down = r; + } + } + } + } + + return OK; +} + +/* + * ת + */ +Status TransposeSMatrix(CrossList M, CrossList* T) { + int i; + OLNode* p, * q, * r, * l; + + // ʼQϢ + (*T).mu = M.nu; + (*T).nu = M.mu; + (*T).tu = M.tu; + + // 0ŵԪã + (*T).rhead = (OLink*) malloc(((*T).mu + 1) * sizeof(OLink)); + if(!(*T).rhead) { + exit(OVERFLOW); + } + + // 0ŵԪã + (*T).chead = (OLink*) malloc(((*T).nu + 1) * sizeof(OLink)); + if(!(*T).chead) { + exit(OVERFLOW); + } + + // ʼΪNULL + for(i = 0; i <= (*T).mu; ++i) { + (*T).rhead[i] = NULL; + } + + // ʼΪNULL + for(i = 0; i <= (*T).nu; ++i) { + (*T).chead[i] = NULL; + } + + // + if(!(*T).tu) { + return OK; + } + + // ɨ + for(i = 1; i <= M.nu; ++i) { + q = M.chead[i]; + + // ǰûԪأֱ + if(q == NULL) { + continue; + } + + while(q != NULL) { + // Ԫ + p = (OLNode*) malloc(sizeof(OLNode)); + if(!p) { + exit(OVERFLOW); + } + + // Ϊ㸳ֵбУб + p->i = q->j; + p->j = q->i; + p->e = q->e; + p->right = p->down = NULL; + + /* + * ʼеIJ + */ + + if((*T).rhead[p->i] == NULL) { + (*T).rhead[p->i] = p; + } else { + r->right = p; + } + + // rָǰ²Ľ + r = p; + + /* + * ʼеIJ + */ + + // ѰҲλ + if((*T).chead[p->j] == NULL || (*T).chead[p->j]->i > p->i) { + r->down = (*T).chead[p->j]; + (*T).chead[p->j] = r; + } else { + // ѰҲλõǰһλ + for(l = (*T).chead[p->j]; (l->down) && (l->down->i < p->i); l = l->down) { + } + r->down = l->down; + l->down = r; + } + + q = q->down; + } + } + + return OK; +} + +/* + * + */ +void PrintSMatrix(CrossList M) { + int i, j; + OLNode* p; + + for(i = 1; i <= M.mu; ++i) { + p = M.rhead[i]; + for(j = 1; j <= M.nu; ++j) { + if(p && p->j == j) { + printf("%3d ", p->e); + p = p->right; + } else { + printf("%3d ", 0); + } + } + printf("\n"); + } +} diff --git a/Dev-C++/ExerciseBook/05.27/CrossList.h b/Dev-C++/ExerciseBook/05.27/CrossList.h new file mode 100644 index 0000000..c774280 --- /dev/null +++ b/Dev-C++/ExerciseBook/05.27/CrossList.h @@ -0,0 +1,94 @@ +/*=================== + * ʮϡ + * + * 㷨: 5.4 + ====================*/ + +#ifndef CROSSLIST_H +#define CROSSLIST_H + +#include +#include // ṩmallocreallocfreeexitԭ +#include // ṩ strstr ԭ +#include "Status.h" //**01 **// + +/* ʮԪ */ +typedef int ElemType; + +/* ԪͶ */ +typedef struct OLNode { + int i, j; // ÷Ԫ±± + ElemType e; + struct OLNode* right; // ÷Ԫڵбĺ + struct OLNode* down; // ÷Ԫڵбĺ +} OLNode, * OLink; + +/* ʮͶ */ +typedef struct { + OLink* rhead; // ͷָ + OLink* chead; // ͷָ + int mu, nu, tu; // ͷԪ +} CrossList; + + +/* + * 㷨5.4 + * + * ϡM + * + * + *ע + * + * ̲Ĭϴӿ̨ȡݡ + * Ϊ˷ԣÿжֶݣ + * ѡԤļpathжȡݡ + * + * Ҫӿ̨ȡݣpathΪNULLΪմ + * ҪļжȡݣҪpathдļϢ + */ +Status CreateSMatrix(CrossList* M, char* path); + +/* + * ϡ + */ +Status DestroySMatrix(CrossList* M); + +/* + * + * + * һ¾Tþ˴ӾMаݡ + */ +Status CopySMatrix(CrossList M, CrossList* T); + +/* + * ӷ + * + * Q = M + N + */ +Status AddSMatrix(CrossList M, CrossList N, CrossList* Q); + +/* + * + * + * Q = M - N + */ +Status SubSMatrix(CrossList M, CrossList N, CrossList* Q); + +/* + * ˷ + * + * Q = M * N + */ +Status MultSMatrix(CrossList M, CrossList N, CrossList* Q); + +/* + * ת + */ +Status TransposeSMatrix(CrossList M, CrossList* T); + +/* + * + */ +void PrintSMatrix(CrossList M); + +#endif diff --git a/Dev-C++/ExerciseBook/05.27/TestData_M.txt b/Dev-C++/ExerciseBook/05.27/TestData_M.txt new file mode 100644 index 0000000..be25c94 --- /dev/null +++ b/Dev-C++/ExerciseBook/05.27/TestData_M.txt @@ -0,0 +1,4 @@ +5 +5 +Ԫ10 +Ԫ飺(1,2,1),(1,4,5),(2,3,-3),(2,5,2),(3,1,2),(3,2,3),(3,3,4),(4,4,2),(5,1,3),(5,2,-1) \ No newline at end of file diff --git a/Dev-C++/ExerciseBook/05.27/TestData_N.txt b/Dev-C++/ExerciseBook/05.27/TestData_N.txt new file mode 100644 index 0000000..7c940db --- /dev/null +++ b/Dev-C++/ExerciseBook/05.27/TestData_N.txt @@ -0,0 +1,4 @@ +5 +5 +Ԫ8 +Ԫ飺(1,1,-3)(1,3,2)(2,4,-1)(3,2,4)(4,1,6)(4,5,5)(5,1,3)(5,3,2) \ No newline at end of file diff --git a/Dev-C++/ExerciseBook/05.28-05.29/05.28-05.29.cpp b/Dev-C++/ExerciseBook/05.28-05.29/05.28-05.29.cpp new file mode 100644 index 0000000..eb0a701 --- /dev/null +++ b/Dev-C++/ExerciseBook/05.28-05.29/05.28-05.29.cpp @@ -0,0 +1,336 @@ +#include +#include "MPList.h" //**05 ͹**// + +/* + * mԪʽPеһԪƫPD + * + * ԤһԪΪⲿ + */ +Status Algo_5_28(MPList P, MPList* PD); + +/* + * ָexp˵ʽPԭӽϵ + */ +static void HandleExp(MPList P, int exp); + +/* + * ʽӷR = P + Q + */ +Status Algo_5_29(MPList P, MPList Q, MPList* R); + +/* + * ԷǿյĶԶʽPQӣPQָǸԪбͷ㡣 + */ +static void AddMpList(MPList P, MPList Q, MPList* R); + +/* + * 󴴽һ½㡣 + * tpΪNULLΪԭӽһͷ㣬Ϊӱͷ㡣 + * vΪͷԪ + */ +static MPList VirtualNode(int v, MPList tp, MPList hp); + + +int main(int argc, char* argv[]) { + MPList P, Q; + MPList PD, QD; + MPList R; + char *p = "z((3,y((1,x((3, 1))))),(2,y((2,1))),(0,3))"; + char *q = "z((4,1),(3,y((1,x((3,-1))))),(2,x((1,1))),(0,y((1,1),(0,4))))"; + + printf("Ԫʽ...\n"); + CreateMPList(&P, p, "zyx"); + printf("P = "); + PrintGraph(P); + CreateMPList(&Q, q, "zyx"); + printf("Q = "); + PrintGraph(Q); + + // һԪƫ + printf("P' = "); + Algo_5_28(P, &PD); + PrintGraph(PD); + printf("Q' = "); + Algo_5_28(Q, &QD); + PrintGraph(QD); + + // ʽӷ + printf("R = "); + Algo_5_29(P, Q, &R); + PrintGraph(R); +} + + +/* + * mԪʽPеһԪƫPD + * + * ԤһԪΪⲿ + */ +Status Algo_5_28(MPList P, MPList* PD) { + MPList r, rd, s; + int count; + + if(P == NULL || PD == NULL) { + return ERROR; + } + + // ʽ + *PD = (MPList) malloc(sizeof(MPNode)); + (*PD)->tag = List; + (*PD)->exp = P->exp; + (*PD)->tp = NULL; + + // ͷ + (*PD)->Node.hp = (MPList) malloc(sizeof(MPNode)); + (*PD)->Node.hp->tag = P->Node.hp->tag; + (*PD)->Node.hp->exp = P->Node.hp->exp; + (*PD)->Node.hp->Node.hp = P->Node.hp->Node.hp; + + r = P->Node.hp; // ָPͷ + rd = (*PD)->Node.hp; // ָPDͷ + count = 0; + + // һԪб + while(r->tp != NULL) { + r = r->tp; + + // û""㣬ߣʽPһ"" + if(r->exp!=0 || count==0) { + rd->tp = (MPList) malloc(sizeof(MPNode)); + rd = rd->tp; + } + + /* + * ""㣬󵼺Ϊ0 + * ע""ָΪ0 + */ + if(r->exp == 0) { + // ʽPһ"" + if(count==0) { + rd->tag = Atom; + rd->exp = 0; + rd->Node.coef = 0; + } + + break; + } + + rd->tag = r->tag; + rd->exp = r->exp - 1; + + // ԭӽ㣬ֱӼϵ + if(r->tag==Atom) { + rd->Node.coef = r->Node.coef * r->exp; // ָϵ + + // ӱ㣬Ҫָ˵ʵλ + } else { + Copy(r->Node.hp, &(rd->Node.hp)); + + // ָΪ1ʱûҪ˵ + if(r->exp!=1) { + // ָexp˵ʽPԭӽϵ + HandleExp(rd->Node.hp, r->exp); + } + } + + count++; + } + + rd->tp = NULL; + + return OK; +} + +/* + * ָexp˵ʽPԭӽϵ + */ +static void HandleExp(MPList P, int exp) { + MPList r; + + if(P == NULL) { + return; + } + + for(r = P->tp; r != NULL; r = r->tp) { + if(r->tag == Atom) { + r->Node.coef *= exp; + } else { + HandleExp(r->Node.hp, exp); + } + } +} + +/* + * ʽӷR = P + Q + */ +Status Algo_5_29(MPList P, MPList Q, MPList* R) { + MPList r; + + // ҪʽԪ + if(P == NULL || Q == NULL || R==NULL || P->exp != Q->exp) { + return ERROR; + } + + // ʽ + *R = (MPList) malloc(sizeof(MPNode)); + if(*R == NULL) { + exit(OVERFLOW); + } + (*R)->tag = List; + (*R)->exp = P->exp; // ʽԪ + (*R)->tp = NULL; + + AddMpList(P->Node.hp, Q->Node.hp, &r); + + if(r->tp == NULL) { + r->tp = (MPList) malloc(sizeof(MPNode)); + r->tp->tag = Atom; + r->tp->exp = 0; + r->tp->Node.coef = 0.0f; + r->tp->tp = NULL; + } + + (*R)->Node.hp = r; + + return OK; +} + +/* + * ԷǿյĶԶʽPQӣPQָǸԪбͷ㡣 + */ +static void AddMpList(MPList P, MPList Q, MPList* R) { + MPList p, q, h, r; + MPList t; + MPList tp; + float sum; + int a, b; + int v; + + // ͬһԪ + if(P->exp!=Q->exp) { + + a = (int)(strchr(Var, P->exp)-Var); + b = (int)(strchr(Var, Q->exp)-Var); + + if(aexp, NULL, Q); + v = P->exp; + } + + if(a>b) { + P = VirtualNode(Q->exp, NULL, P); + v = Q->exp; + } + } else { + v = P->exp; + } + + // ͷ + *R = (MPList) malloc(sizeof(MPNode)); + (*R)->tag = List; + (*R)->exp = v; + (*R)->Node.hp =NULL; + + h = *R; + + p = P->tp; + q = Q->tp; + + while(p!=NULL && q!=NULL){ + if(p->exp>q->exp) { + tp = p->tp; + p->tp = NULL; + Copy(p, &(h->tp)); + p->tp = tp; + p = p->tp; + h = h->tp; + } else if(p->expexp) { + tp = q->tp; + q->tp = NULL; + Copy(q, &(h->tp)); + q->tp = tp; + q = q->tp; + h = h->tp; + + // ָͬ + } else { + sum = 0.0f; // ʼϵͣһõ + r = NULL; + + if(p->tag==Atom && q->tag==List) { + t = VirtualNode(q->Node.hp->exp, p, NULL); + tp = p->tp; + p->tp = NULL; + AddMpList(t, q->Node.hp, &r); + p->tp = tp; + } else if(p->tag==List && q->tag==Atom) { + t = VirtualNode(p->Node.hp->exp, q, NULL); + tp = q->tp; + q->tp = NULL; + AddMpList(p->Node.hp, t, &r); + q->tp = tp; + + // ӱ + } else if(p->tag==List && q->tag==List) { + AddMpList(p->Node.hp, q->Node.hp, &r); + + // ԭӵĻֱ + } else if(p->tag==Atom && q->tag==Atom) { + sum = p->Node.coef + q->Node.coef; + } + + if(sum!=0.0f || (r!=NULL && r->tp!=NULL)) { + h->tp = (MPList) malloc(sizeof(MPNode)); + h = h->tp; + h->exp = p->exp; + + if(sum!=0.0f) { + h->tag = Atom; + h->Node.coef = sum; + } else { + h->tag = List; + h->Node.hp = r; + } + } + + p = p->tp; + q = q->tp; + } + } + + h->tp = NULL; + + if(p!=NULL){ + Copy(p, &(h->tp)); + } + + if(q!=NULL){ + Copy(q, &(h->tp)); + } +} + +/* + * 󴴽һ½㡣 + * tpΪNULLΪԭӽһͷ㣬Ϊӱͷ㡣 + * vΪͷԪ + */ +static MPList VirtualNode(int v, MPList tp, MPList hp){ + MPList P; + + P = (MPList) malloc(sizeof(MPNode)); + P->tag = List; + P->exp = v; + P->Node.hp = NULL; + + if(tp!=NULL) { + P->tp = tp; + } else { + P->tp = (MPList) malloc(sizeof(MPNode)); + P->tp->exp = 0; + P->tp->tag = List; + P->tp->Node.hp = hp; + P->tp->tp = NULL; + } + + return P; +} diff --git a/Dev-C++/ExerciseBook/05.28-05.29/05.28-05.29.dev b/Dev-C++/ExerciseBook/05.28-05.29/05.28-05.29.dev new file mode 100644 index 0000000..e1049f7 --- /dev/null +++ b/Dev-C++/ExerciseBook/05.28-05.29/05.28-05.29.dev @@ -0,0 +1,102 @@ +[Project] +FileName=05.28-05.29.dev +Name=05.28-05.29 +Type=1 +Ver=2 +ObjFiles= +Includes= +Libs= +PrivateResource= +ResourceIncludes= +MakeIncludes= +Compiler= +CppCompiler= +Linker= +IsCpp=0 +Icon= +ExeOutput= +ObjectOutput= +LogOutput= +LogOutputEnabled=0 +OverrideOutput=0 +OverrideOutputName= +HostApplication= +UseCustomMakefile=0 +CustomMakefile= +CommandLine= +Folders= +IncludeVersionInfo=0 +SupportXPThemes=0 +CompilerSet=1 +CompilerSettings=0000000000000000001000000 +UnitCount=5 + +[VersionInfo] +Major=1 +Minor=0 +Release=0 +Build=0 +LanguageID=1033 +CharsetID=1252 +CompanyName= +FileVersion= +FileDescription=Developed using the Dev-C++ IDE +InternalName= +LegalCopyright= +LegalTrademarks= +OriginalFilename= +ProductName= +ProductVersion= +AutoIncBuildNr=0 +SyncProduct=1 + +[Unit2] +FileName=MPList.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit4] +FileName=StringUtil.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit1] +FileName=05.28-05.29.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit3] +FileName=MPList.h +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit5] +FileName=StringUtil.h +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + diff --git a/Dev-C++/ExerciseBook/05.28-05.29/MPList.cpp b/Dev-C++/ExerciseBook/05.28-05.29/MPList.cpp new file mode 100644 index 0000000..1f08b74 --- /dev/null +++ b/Dev-C++/ExerciseBook/05.28-05.29/MPList.cpp @@ -0,0 +1,233 @@ +/*========== + * mԪʽ + ===========*/ + +#include "MPList.h" + +// μͷļе +char Var[27]; + +/* + * + * + * ַSmԪP + * УSǷдȷ + * + * P : Ķʽ + * S : ʽַ + * vars: бӵһԪʼУxyzԪʽеδ֪ + */ +Status CreateMPList(MPList* P, char* S, char* vars) { + if(P == NULL) { + return ERROR; + } + + // ַSеĿհףɴӡַո + ClearBlank(&S); + + if(strlen(S) == 0) { + *P = NULL; + return ERROR; + } + + // ʼԪϢ + strcpy(Var, vars); + + *P = (MPList) malloc(sizeof(MPNode)); + if(*P == NULL) { + exit(OVERFLOW); + } + + (*P)->tag = List; + (*P)->exp = (int) strlen(vars); + (*P)->tp = NULL; + + Create(&(*P)->Node.hp, S); + + return OK; +} + +/* + * mԪʽ + */ +static Status Create(MPList* P, char* S) { + char* Sc; + char* hhstr, * hstr, * str; + char* sub; + MPList r; + float f; + + // ȡSһ + SubString(&Sc, S, 1, (int) strlen(S)); + + *P = (MPList) malloc(sizeof(MPNode)); + if(*P == NULL) { + exit(OVERFLOW); + } + + (*P)->tag = List; + (*P)->exp = (int) Sc[0]; // δ֪ǣxyz + (*P)->Node.hp = NULL; + (*P)->tp = NULL; + + StrDelete(&Sc, 1, 1); // ɾδ֪ + SubString(&str, Sc, 2, (int) strlen(Sc) - 2); // ȥ + + r = *P; + + while(!StrEmpty(str)) { + // + sever(&hstr, &str); + + SubString(&sub, hstr, 2, (int) strlen(hstr) - 2); // ȥ + sever(&hhstr, &sub); + + // ӽ + r->tp = (MPList) malloc(sizeof(MPNode)); + if(r->tp == NULL) { + exit(OVERFLOW); + } + GetElem(hhstr, 1, &f); + r->tp->exp = (int) f; // ȡָ + r->tp->tp = NULL; + + if(ElemCount(sub) == 1) { + r->tp->tag = Atom; + GetElem(sub, 1, &f); + r->tp->Node.coef = f; + } else { + r->tp->tag = List; + Create(&(r->tp->Node.hp), sub); + } + + r = r->tp; + } + + return OK; +} + +/* + * ͼλ + * + * mԪP + */ +void PrintGraph(MPList P) { + if(P == NULL) { + printf("\n"); + return; + } + Print(P->Node.hp); + printf("\n"); +} + +/* + * ͼλڲʵ + */ +static void Print(MPList head) { + MPList p; + + if(head == NULL) { + return; + } + + printf("%c(", head->exp); + + p = head->tp; + + while(p != NULL) { + printf("(%d,", p->exp); + + if(p->tag == List) { + Print(p->Node.hp); + } else { + printf("%.2f", p->Node.coef); + } + + printf(")"); + + p = p->tp; + + if(p != NULL) { + printf(","); + } + } + + printf(")"); +} + +/* + * ǿմstrָ֣hsubΪһ','֮ǰӴstrΪһ','֮Ӵ + * + *ע + * 1.ַstrȷ޿հ׷ţstrѾȥš + * 2.ɺstrҲᷢ仯 + */ +static void sever(char** hstr, char** str) { + int i, k, n; + + char* head, * tail; + + // strΪʱhstrҲΪ + if(strlen(*str) == 0) { + *hstr = NULL; + return; + } + + n = (int) strlen(*str); + + i = 0; // ַʱα + k = 0; // δ + + do { + if((*str)[i] == '(') { + ++k; + } + + if((*str)[i] == ')') { + --k; + } + + i++; + } while(i < n && ((*str)[i] != ',' || k != 0)); + + if(i < n) { + head = (char*) malloc((i + 1) * sizeof(char)); + tail = (char*) malloc((n - i - 1 + 1) * sizeof(char)); + + strncpy(head, *str, i); + head[i] = '\0'; + + strncpy(tail, (*str + i + 1), n - i - 1); + tail[n - i - 1] = '\0'; + } else { + head = *str; + tail = (char*) malloc(sizeof(char)); + tail[0] = '\0'; + } + + *hstr = head; + *str = tail; +} + + +/* + * ƶʽPƵQ + */ +void Copy(MPList P, MPList* Q) { + if(P == NULL) { + *Q = NULL; + return; + } + + *Q = (MPList) malloc(sizeof(MPNode)); + (*Q)->tag = P->tag; + (*Q)->exp = P->exp; + + if(P->tag == List) { + Copy(P->Node.hp, &((*Q)->Node.hp)); + } else { + (*Q)->Node.coef = P->Node.coef; + } + + Copy(P->tp, &((*Q)->tp)); +} diff --git a/Dev-C++/ExerciseBook/05.28-05.29/MPList.h b/Dev-C++/ExerciseBook/05.28-05.29/MPList.h new file mode 100644 index 0000000..455e7ea --- /dev/null +++ b/Dev-C++/ExerciseBook/05.28-05.29/MPList.h @@ -0,0 +1,97 @@ +/*========== + * mԪʽ + ===========*/ + +#ifndef MPLIST_H +#define MPLIST_H + +#include +#include // ṩ mallocreallocfreeexit ԭ +#include // ṩ strlen ԭ +#include "Status.h" //**01 **// +#include "StringUtil.h" //**ַ**// + +/* + * ʾ + * + * 1.ڶԪԼһԪλ㡣 + * 2.δ֪ĬΪa~zA~Z26ĸ + * 3.ԼʽÿԪָǡݼģ321 + */ + + +/* + * 浱ǰʽıϢxyz + * Լvarеַ˳λԪĴ磺 + * "zyx"ָʾzΪһԪyΪڶԪxΪԪ + */ +extern char Var[27]; + +/* + * mԪʽ + * + * Atom-0ԭӽ + * List-1 + */ +typedef enum { Atom, List } ElemTag; + +/* mԪʽԪؽ */ +typedef struct MPNode { + ElemTag tag; // ԭӽͱ + int exp; // ָ򣬶ͷ㣬洢δ֪ǣxyz + union { + float coef; // ϵ + struct MPNode* hp; // ıͷָ + } Node; + struct MPNode* tp; // ൱nextָһԪؽ +} MPNode; + +/* mԪʽ */ +typedef MPNode* MPList; + + +/* + * + * + * ַSmԪP + * УSǷдȷ + * + * P : Ķʽ + * S : ʽַ + * vars: бӵһԪʼУxyzԪʽеδ֪ + */ +Status CreateMPList(MPList* P, char* S, char* vars); + +/* + * mԪʽ + */ +static Status Create(MPList* P, char* S); + +/* + * ͼλ + * + * mԪP + */ +void PrintGraph(MPList P); + +/* + * ͼλڲʵ + */ +static void Print(MPList P); + +/* + * ǿմstrָ֣hsubΪһ','֮ǰӴstrΪһ','֮Ӵ + * + *ע + * 1.ַstrȷ޿հ׷ţstrѾȥš + * 2.ɺstrҲᷢ仯 + */ +static void sever(char** hstr, char** str); + + +/* + * ƶʽ + */ +void Copy(MPList P, MPList* Q); + +#endif diff --git a/Dev-C++/ExerciseBook/05.28-05.29/StringUtil.cpp b/Dev-C++/ExerciseBook/05.28-05.29/StringUtil.cpp new file mode 100644 index 0000000..b1b0fbf --- /dev/null +++ b/Dev-C++/ExerciseBook/05.28-05.29/StringUtil.cpp @@ -0,0 +1,160 @@ +/*================ + * ַ + =================*/ + +#include "StringUtil.h" + +/* + * ɾ + * + * ɾs[pos, pos+len-1]pos1ʼ + */ +Status StrDelete(char** s, int pos, int n) { + int len; + char* ss; + + len = (int) strlen(*s); + + if(pos < 1 || pos + n - 1 > len || n < 0) { + return ERROR; + } + + // ɾijΪ0ǰ + if(n == 0) { + return ERROR; + } + + ss = (char*) malloc((len - n + 1) * sizeof(char)); + + strncpy(ss, *s, pos - 1); + strncpy(ss, *s + pos + n - 1, len - pos - n + 1); + + ss[len - n] = '\0'; + + *s = ss; + + return OK; +} + +/* + * Ӵ + * + * subs[pos, pos+len-1]pos1ʼ + */ +Status SubString(char** sub, char* s, int pos, int n) { + int len, i; + + len = (int) strlen(s); + + if(pos < 1 || pos > len || n < 0 || pos + n - 1 > len) { + *sub = NULL; + return ERROR; + } + + *sub = (char*) malloc((n + 1) * sizeof(char)); + + for(i = 0; i < n; i++) { + (*sub)[i] = s[pos + i - 1]; + } + + // ȷ³ + (*sub)[n] = '\0'; + + return OK; +} + +/* + * п + * + * жϴsǷЧݡ + */ +Status StrEmpty(char* s) { + return strlen(s) == 0 ? TRUE : FALSE; +} + +/* + * + * + * ַsеĿհףɴӡַո + */ +Status ClearBlank(char** s) { + int len; + int i, j; + char* ss; + + len = (int) strlen(*s); + if(len == 0) { + return ERROR; + } + + ss = (char*) malloc((len + 1) * sizeof(char)); + + for(i = 0, j = 0; i < len; i++) { + // հףԹ + if((*s)[i] == ' ' || !isprint((*s)[i])) { + continue; + } + + ss[j++] = (*s)[i]; + } + + ss[j] = '\0'; + + *s = ss; + + return OK; +} + +/* + * + * + * ͳַsеԪظ + * ֮ڣ֣Ὣ䵱һԪء + */ +int ElemCount(const char* s) { + int count; + float f; + char c; + char* sub; + + if(s==NULL || strlen(s) == 0) { + return 0; + } + + sub = (char*) malloc((strlen(s) + 1) * sizeof(char)); + sub[0] = '\0'; + + // + if(sscanf(s, "%f", &f) == 1) { + sscanf(s, "%f%s", &f, sub); + } else { + sscanf(s, "%c%s", &c, sub); + } + + count = ElemCount(sub); + + return 1 + count; +} + +/* + * ȡֵ + * + * ȡַsеposԪ(pos1ʼ)fա + * ֮ڣ֣Ὣ䵱һԪء + */ +Status GetElem(char* s, int pos, float* f) { + int len; + + len = (int) strlen(s); + + if(pos < 1 || pos > len) { + return ERROR; + } + + // ȳԶ֣ȡʧܵĻٳԶַ + if(sscanf(s + pos - 1, "%f", f) < 1) { + *f = s[pos - 1]; + } + + return OK; +} diff --git a/Dev-C++/ExerciseBook/05.28-05.29/StringUtil.h b/Dev-C++/ExerciseBook/05.28-05.29/StringUtil.h new file mode 100644 index 0000000..e535a5e --- /dev/null +++ b/Dev-C++/ExerciseBook/05.28-05.29/StringUtil.h @@ -0,0 +1,58 @@ +/*================ + * ַ + =================*/ + +#ifndef STRINGUTIL_H +#define STRINGUTIL_H + +#include +#include // ṩ malloc ԭ +#include // ṩ strlenstrncpy ԭ +#include // ṩ isprint ԭ +#include "Status.h" //**01 **// + +/* + * ɾ + * + * ɾs[pos, pos+len-1]pos1ʼ + */ +Status StrDelete(char** S, int pos, int n); + +/* + * Ӵ + * + * subs[pos, pos+len-1]pos1ʼ + */ +Status SubString(char** sub, char* s, int pos, int len); + +/* + * п + * + * жϴsǷЧݡ + */ +Status StrEmpty(char* s); + +/* + * + * + * ַsеĿհףɴӡַո + */ +Status ClearBlank(char** s); + +/* + * + * + * ͳַsеԪظ + * ֮ڣ֣Ὣ䵱һԪء + */ +int ElemCount(const char* s); + +/* + * ȡֵ + * + * ȡַsеposԪ(pos1ʼ)fա + * ֮ڣ֣Ὣ䵱һԪء + */ +Status GetElem(char* s, int pos, float *f); + +#endif diff --git a/Dev-C++/ExerciseBook/05.30.1/05.30.1.cpp b/Dev-C++/ExerciseBook/05.30.1/05.30.1.cpp new file mode 100644 index 0000000..00aefcc --- /dev/null +++ b/Dev-C++/ExerciseBook/05.30.1/05.30.1.cpp @@ -0,0 +1,42 @@ +#include +#include "SString.h" //**04 **// +#include "GList-HT.h" //**05 ͹**// + +// ȣͷβ洢ʾ +int Algo_5_30_1(GList L); + + +int main(int argc, char* argv[]) { + GList L; + char* s = "((),(e),(a,(b,c,d)))"; + SString S; + + printf(" L ...\n"); + StrAssign(S, s); + CreateGList(&L, S); + printf("L = "); + PrintGraph(L); + + printf("Ϊ %d\n", Algo_5_30_1(L)); + + return 0; +} + + +// ȣͷβ洢ʾ +int Algo_5_30_1(GList L) { + int m, n; + + if(L==NULL) { + return 1; // ձΪ1 + } + + if(L->tag == Atom) { + return 0; // ԭΪ0 + } + + m = Algo_5_30_1(L->Node.ptr.hp) + 1; + n = Algo_5_30_1(L->Node.ptr.tp); + + return m > n ? m : n; +} diff --git a/Dev-C++/ExerciseBook/05.30.1/05.30.1.dev b/Dev-C++/ExerciseBook/05.30.1/05.30.1.dev new file mode 100644 index 0000000..1239375 --- /dev/null +++ b/Dev-C++/ExerciseBook/05.30.1/05.30.1.dev @@ -0,0 +1,102 @@ +[Project] +FileName=05.30.1.dev +Name=05.30.1 +Type=1 +Ver=2 +ObjFiles= +Includes= +Libs= +PrivateResource= +ResourceIncludes= +MakeIncludes= +Compiler= +CppCompiler= +Linker= +IsCpp=0 +Icon= +ExeOutput= +ObjectOutput= +LogOutput= +LogOutputEnabled=0 +OverrideOutput=0 +OverrideOutputName= +HostApplication= +UseCustomMakefile=0 +CustomMakefile= +CommandLine= +Folders= +IncludeVersionInfo=0 +SupportXPThemes=0 +CompilerSet=1 +CompilerSettings=0000000000000000001000000 +UnitCount=5 + +[VersionInfo] +Major=1 +Minor=0 +Release=0 +Build=0 +LanguageID=1033 +CharsetID=1252 +CompanyName= +FileVersion= +FileDescription=Developed using the Dev-C++ IDE +InternalName= +LegalCopyright= +LegalTrademarks= +OriginalFilename= +ProductName= +ProductVersion= +AutoIncBuildNr=0 +SyncProduct=1 + +[Unit4] +FileName=SString.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit2] +FileName=GList-HT.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit1] +FileName=05.30.1.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit3] +FileName=GList-HT.h +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit5] +FileName=SString.h +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + diff --git a/Dev-C++/ExerciseBook/05.30.1/GList-HT.cpp b/Dev-C++/ExerciseBook/05.30.1/GList-HT.cpp new file mode 100644 index 0000000..bad30df --- /dev/null +++ b/Dev-C++/ExerciseBook/05.30.1/GList-HT.cpp @@ -0,0 +1,418 @@ +/*============================ + * ͷβ洢ʾ + * + * 㷨: 5.55.65.75.8 + =============================*/ + +#include "GList-HT.h" //**05 ͹**// + +/* + * ʼ + * + * ʼյĹΪ0Ϊ1 + * + *ע + * Ҫÿһȥſ + */ +Status InitGList(GList* L) { + if(L == NULL) { + return ERROR; + } + + *L = NULL; + + return OK; +} + +/* + * 㷨5.7 + * + * + * + * ַSL + */ +Status CreateGList(GList* L, SString S) { + SString emp; // չַ + SString hsub, sub; + GList p, q; + + if(L == NULL) { + return ERROR; + } + + // ַSеĿհףɴӡַո + ClearBlank(S); + + if(StrEmpty(S)) { + return ERROR; + } + + StrAssign(emp, "()"); + + /* + * 봮Ϊ()ҪյĹ + * + *ע + * ̲Ĵġ + * StrCompareķֵָʾַĴСָʾַǷȡ + * S()ȣֵӦ0 + */ + if(!StrCompare(S, emp)) { + *L = NULL; + } else { + *L = (GList) malloc(sizeof(GLNode)); + if(*L == NULL) { + exit(OVERFLOW); + } + + // ԭ + if(StrLength(S) == 1) { + (*L)->tag = Atom; + (*L)->Node.atom = S[1]; + } else { + (*L)->tag = List; + + p = *L; + + // ȥ + SubString(sub, S, 2, StrLength(S) - 2); + + // ظnӱ + do { + // subзͷhsubɺsubҲᷢ仯 + sever(hsub, sub); + + // ݹ鴴 + CreateGList(&(p->Node.ptr.hp), hsub); + + q = p; + + // βΪգҪβ + if(!StrEmpty(sub)) { + p = (GList) malloc(sizeof(GLNode)); + if(p == NULL) { + exit(OVERFLOW); + } + + p->tag = List; + + q->Node.ptr.tp = p; + } + } while(!StrEmpty(sub)); + + q->Node.ptr.tp = NULL; + } + } + + return OK; +} + +/* + * + * + * ͷŹռڴ档 + */ +Status DestroyGList(GList* L) { + GList head, tail; + + if(L == NULL || *L == NULL) { + return ERROR; + } + + // ɾԭӽ + if((*L)->tag == Atom) { + free(*L); + *L = NULL; + + // ɾӱ + } else { + head = (*L)->Node.ptr.hp; + tail = (*L)->Node.ptr.tp; + free(*L); + *L = NULL; + DestroyGList(&head); + DestroyGList(&tail); + } + + return OK; +} + +/* + * 㷨5.6 + * + * + * + * ɹLƵõT + */ +Status CopyGList(GList* T, GList L) { + if(T == NULL) { + return ERROR; + } + + if(L == NULL) { + *T = NULL; + } else { + // ½ + *T = (GList) malloc(sizeof(GLNode)); + if(*T == NULL) { + exit(OVERFLOW); + } + + (*T)->tag = L->tag; + + // Ƶԭ + if(L->tag == Atom) { + (*T)->Node.atom = L->Node.atom; + + // Ʊͷͱβ + } else { + CopyGList(&((*T)->Node.ptr.hp), L->Node.ptr.hp); + CopyGList(&((*T)->Node.ptr.tp), L->Node.ptr.tp); + } + } + + return OK; +} + +/* + * + * + * عijȡ + */ +int GListLength(GList L) { + int count; + + for(count = 0; L != NULL; count++, L = L->Node.ptr.tp) { + } + + return count; +} + +/* + * 㷨5.5 + * + * + * + * ع + */ +int GListDepth(GList L) { + int max, deep; + GList p; + + // ձΪ1 + if(L == NULL) { + return 1; + } + + // ԭΪ0 + if(L->tag == Atom) { + return 0; + } + + // ݹӱ + for(max = 0, p = L; p != NULL; p = p->Node.ptr.tp) { + deep = GListDepth(p->Node.ptr.hp); + if(deep > max) { + max = deep; + } + } + + // ǿձǸԪȼһ + return max + 1; +} + +/* + * п + * + * жϹǷΪա + */ +Status GListEmpty(GList L) { + return L == NULL ? TRUE : FALSE; +} + +/* + * ͷ + */ +GList GetHead(GList L) { + GList p; + + // ձޱͷﲻܷNULLȻֲʧ˻Ƿ˿ձ + if(L == NULL) { + exit(ERROR); + } + + CopyGList(&p, L->Node.ptr.hp); + + return p; +} + +/* + * β + */ +GList GetTail(GList L) { + GList p; + + // ձޱβﲻܷNULLȻֲʧ˻Ƿ˿ձ + if(L == NULL) { + exit(ERROR); + } + + CopyGList(&p, L->Node.ptr.tp); + + return p; +} + +/* + * + * + * ԪeΪLĵһԪء + */ +Status InsertFirst(GList* L, GList e) { + GList g; + + if(L == NULL) { + return ERROR; + } + + g = (GList) malloc(sizeof(GLNode)); + if(g == NULL) { + exit(OVERFLOW); + } + + g->tag = List; + g->Node.ptr.hp = e; + g->Node.ptr.tp = *L; + *L = g; + + return OK; +} + +/* + * ɾ + * + * LĵһԪɾeء + */ +Status DeleteFirst(GList* L, GList* e) { + GList p; + + // ձ޷ɾ + if(L == NULL || *L == NULL) { + return ERROR; + } + + p = *L; + *L = (*L)->Node.ptr.tp; + + CopyGList(e, p->Node.ptr.hp); + + free(p); + + return OK; +} + +/* + * + * + * visitʹL + */ +void Traverse(GList L, void(Visit)(AtomType)) { + + if(L == NULL) { + return; + } + + if(L->tag == Atom) { + Visit(L->Node.atom); + } else { + Traverse(L->Node.ptr.hp, Visit); + Traverse(L->Node.ptr.tp, Visit); + } + +} + +/* + * ͼλ + * + * L + */ +void PrintGraph(GList L) { + Print(L, Head); + printf("\n"); +} + +/* + * ͼλڲʵ֣markͼλǡ + */ +static void Print(GList L, Mark mark) { + // LΪ + if(L == NULL) { + if(mark == Head) { + printf("("); + } + + printf(")"); + + // LΪʱ + } else { + // ԭӽ㣬ԭ + if(L->tag == Atom) { + printf("%c", L->Node.atom); + + // ӱ㣬ҪԱͷβֱ + } else { + if(mark == Head) { + printf("("); + } else { + printf(","); + } + + Print(L->Node.ptr.hp, Head); + Print(L->Node.ptr.tp, Tail); + } + } +} + +/* + * 㷨5.8 + * + * ǿմstrָ֣hsubΪһ','֮ǰӴstrΪһ','֮Ӵ + * + *ע + * 1.ַstrȷ޿հ׷ţstrѾȥš + * 2.ɺstrҲᷢ仯 + */ +static void sever(SString hstr, SString str) { + int i, k, n; + SString ch; + + n = StrLength(str); + + i = 0; // ַʱα + k = 0; // δ + + do { + ++i; + + // ȡstrһַ + SubString(ch, str, i, 1); + + if(ch[1] == '(') { + ++k; + } + + if(ch[1] == ')') { + --k; + } + } while(i < n && (ch[1] != ',' || k != 0)); + + // ڶ + if(i < n) { + SubString(hstr, str, 1, i - 1); + SubString(str, str, i + 1, n - i); + + // ֻһ + } else { + StrCopy(hstr, str); + ClearString(str); + } +} diff --git a/Dev-C++/ExerciseBook/05.30.1/GList-HT.h b/Dev-C++/ExerciseBook/05.30.1/GList-HT.h new file mode 100644 index 0000000..508b96f --- /dev/null +++ b/Dev-C++/ExerciseBook/05.30.1/GList-HT.h @@ -0,0 +1,164 @@ +/*============================ + * ͷβ洢ʾ + * + * 㷨: 5.55.65.75.8 + =============================*/ + +#ifndef GLIST_HT_H +#define GLIST_HT_H + +#include +#include // ṩ mallocreallocfreeexit ԭ +#include "Status.h" //**01 **// +#include "SString.h" //**04 **// + +/* ԭԪ */ +typedef char AtomType; + +/* + * + * + * Atom-0ԭӽ + * List-1 + */ +typedef enum { Atom, List } ElemTag; + +/* ͷβ洢ʾͶ */ +typedef struct GLNode { + ElemTag tag; // ǣԭӽͱ + + // ԭӽͱϲ + union { + AtomType atom; // atomԭӽֵAtomTypeû + struct { + struct GLNode* hp; // ָͷ + struct GLNode* tp; // ָβ + } ptr; // ָ + } Node; +} GLNode; + +/* */ +typedef GLNode* GList; + +/* + * ͼλ + * + * HeadָԱͷ + * TailָԱβ + */ +typedef enum { Head, Tail } Mark; + + +/* + * ʼ + * + * ʼյĹΪ0Ϊ1 + * + *ע + * Ҫÿһȥſ + */ +Status InitGList(GList* L); + +/* + * 㷨5.7 + * + * + * + * ַSL + */ +Status CreateGList(GList* L, SString S); + +/* + * + * + * ͷŹռڴ档 + */ +Status DestroyGList(GList* L); + +/* + * 㷨5.6 + * + * + * + * ɹLƵõT + */ +Status CopyGList(GList* T, GList L); + +/* + * + * + * عijȡ + */ +int GListLength(GList L); + +/* + * 㷨5.5 + * + * + * + * ع + */ +int GListDepth(GList L); + +/* + * п + * + * жϹǷΪա + */ +Status GListEmpty(GList L); + +/* + * ͷ + */ +GList GetHead(GList L); + +/* + * β + */ +GList GetTail(GList L); + +/* + * + * + * ԪeΪLĵһԪء + */ +Status InsertFirst(GList* L, GList e); + +/* + * ɾ + * + * LĵһԪɾeء + */ +Status DeleteFirst(GList* L, GList* e); + +/* + * + * + * visitʹL + */ +void Traverse(GList L, void (Visit)(AtomType)); + +/* + * ͼλ + * + * L + */ +void PrintGraph(GList L); + +/* + * ͼλڲʵ֣markͼλǡ + */ +static void Print(GList L, Mark mark); + +/* + * 㷨5.8 + * + * ǿմstrָ֣hsubΪһ','֮ǰӴstrΪһ','֮Ӵ + * + *ע + * 1.ַstrȷ޿հ׷ţstrѾȥš + * 2.ɺstrҲᷢ仯 + */ +static void sever(SString hstr, SString str); + +#endif diff --git a/Dev-C++/ExerciseBook/05.30.1/SString.cpp b/Dev-C++/ExerciseBook/05.30.1/SString.cpp new file mode 100644 index 0000000..7a96fcf --- /dev/null +++ b/Dev-C++/ExerciseBook/05.30.1/SString.cpp @@ -0,0 +1,195 @@ +/*============================= + * Ķ˳洢ʾ˳򴮣 + * + * 㷨: 4.14.24.34.5 + ==============================*/ + +#include "SString.h" //**04 **// + +/* + * ʼ + * + * һֵΪcharsĴT + * + *ע + * òСӼ + */ +Status StrAssign(SString T, const char* chars) { + int i, len; + + len = (int) strlen(chars); + + // chars + if(len > MAXSTRLEN) { + return ERROR; + } + + T[0] = len; + for(i = 1; i <= len; i++) { + T[i] = chars[i - 1]; + } + + return OK; +} + +/* + * + * + * Sա + */ +Status ClearString(SString S) { + // ֻҪΪ0Ϳ + S[0] = 0; + return OK; +} + +/* + * п + * + * жϴSǷЧݡ + * + * ֵ + * TRUE : SΪ + * FALSE: SΪ + */ +Status StrEmpty(SString S) { + return S[0] == 0 ? TRUE : FALSE; +} + +/* + * + * + * شSԪصĸ + * + *ע + * òСӼ + */ +int StrLength(SString S) { + return S[0]; +} + +/* + * 㷨4.3 + * + * Ӵ + * + * SubS[pos, pos+len-1] + * ֵָʾǷȡɹ + * + *ע + * òСӼ + */ +Status SubString(SString Sub, SString S, int pos, int len) { + int i; + + if(pos < 1 || pos > S[0] || len < 0 || pos + len - 1 > S[0]) { + return ERROR; + } + + // Ԫ + for(i = 1; i <= len; i++) { + Sub[i] = S[pos + i - 1]; + } + + // ȷ³ + Sub[0] = len; + + return OK; +} + +/* + * ɾ + * + * ɾS[pos, pos+len-1] + */ +Status StrDelete(SString S, int pos, int len) { + int i; + + if(pos < 1 || pos + len - 1 > S[0] || len < 0) { + return ERROR; + } + + // ɾijΪ0ǰ + if(len == 0) { + return OK; + } + + // ѺԪŲǰ棬ǵɾԪ + for(i = pos + len; i <= S[0]; i++) { + S[i - len] = S[i]; + } + + // ȼ + S[0] -= len; + + return OK; +} + +/* + * Ƚ + * + * ȽϴSʹTرȽϽ + * + *ע + * òСӼ + */ +int StrCompare(SString S, SString T) { + int i = 1; + + while(i <= S[0] && i <= T[0]) { + // ַͬʱȽС + if(S[i] != T[i]) { + return S[i] - T[i]; + } + + i++; + } + + return S[0] - T[0]; +} + +/* + * + * + * SƵT + */ +Status StrCopy(SString T, SString S) { + int i; + + // ͬϢһ + for(i = 0; i <= S[0]; i++) { + T[i] = S[i]; + } + + return OK; +} + +/* + * ַSеĿհףɴӡַո + * + *ע + * úڱġ + */ +Status ClearBlank(SString S) { + int i, j; + + // ǿմ + if(S[0] == 0) { + return ERROR; + } + + for(i = 1, j = 0; i <= S[0]; i++) { + // հףԹ + if(S[i] == ' ' || !isprint(S[i])) { + continue; + } + + j++; + + S[j] = S[i]; + } + + S[0] = j; + + return OK; +} diff --git a/Dev-C++/ExerciseBook/05.30.1/SString.h b/Dev-C++/ExerciseBook/05.30.1/SString.h new file mode 100644 index 0000000..0632f18 --- /dev/null +++ b/Dev-C++/ExerciseBook/05.30.1/SString.h @@ -0,0 +1,117 @@ +/*============================= + * Ķ˳洢ʾ˳򴮣 + * + * 㷨: 4.14.24.34.5 + ==============================*/ + +#ifndef SSTRING_H +#define SSTRING_H + +#include +#include // ṩ strlen ԭ +#include // ṩ isprint ԭ +#include "Status.h" //**01 **// + +/* 궨 */ +#define MAXSTRLEN 255 // ˳򴮵󴮳 + +/* + * ˳洢Ͷ + * + * עЧԪشSString1ŵԪʼ洢 + * SString0ŵԪ洢䳤 + */ +typedef unsigned char SString[MAXSTRLEN + 1]; // 0ŵԪŴij + + +/* + * ʾ + * + * ѭ̲ĵдϰߣposָʾַλ()1ʼ + */ + + +/* + * ʼ + * + * һֵΪcharsĴT + * + *ע + * òСӼ + */ +Status StrAssign(SString T, const char* chars); + +/* + * + * + * Sա + */ +Status ClearString(SString S); + +/* + * п + * + * жϴSǷЧݡ + * + * ֵ + * TRUE : SΪ + * FALSE: SΪ + */ +Status StrEmpty(SString S); + +/* + * + * + * شSԪصĸ + * + *ע + * òСӼ + */ +int StrLength(SString S); + +/* + * 㷨4.3 + * + * Ӵ + * + * SubS[pos, pos+len-1] + * ֵָʾǷȡɹ + * + *ע + * òСӼ + */ +Status SubString(SString Sub, SString S, int pos, int len); + +/* + * ɾ + * + * ɾS[pos, pos+len-1] + */ +Status StrDelete(SString S, int pos, int len); + +/* + * Ƚ + * + * ȽϴSʹTرȽϽ + * + *ע + * òСӼ + */ +int StrCompare(SString S, SString T); + +/* + * + * + * SƵT + */ +Status StrCopy(SString T, SString S); + +/* + * ַSеĿհףɴӡַո + * + *ע + * úڱġ + */ +Status ClearBlank(SString S); + +#endif diff --git a/Dev-C++/ExerciseBook/05.30.2/05.30.2.cpp b/Dev-C++/ExerciseBook/05.30.2/05.30.2.cpp new file mode 100644 index 0000000..929561f --- /dev/null +++ b/Dev-C++/ExerciseBook/05.30.2/05.30.2.cpp @@ -0,0 +1,42 @@ +#include +#include "SString.h" //**04 **// +#include "GList-E.h" //**05 ͹**// + +// ȣչ洢ʾ +int Algo_5_30_2(GList L); + + +int main(int argc, char* argv[]) { + GList L; + char* s = "((),(e),(a,(b,c,d)))"; + SString S; + + printf(" L ...\n"); + StrAssign(S, s); + CreateGList(&L, S); + printf("L = "); + PrintGraph(L); + + printf("Ϊ %d\n", Algo_5_30_2(L)); + + return 0; +} + + +// ȣչ洢ʾ +int Algo_5_30_2(GList L) { + int m, n; + + if(L==NULL) { + return 1; // ձΪ1 + } + + if(L->tag == Atom) { + return 0; // ԭΪ0 + } + + m = Algo_5_30_2(L->Node.hp) + 1; + n = Algo_5_30_2(L->tp); + + return m > n ? m : n; +} diff --git a/Dev-C++/ExerciseBook/05.30.2/05.30.2.dev b/Dev-C++/ExerciseBook/05.30.2/05.30.2.dev new file mode 100644 index 0000000..e9bd2d7 --- /dev/null +++ b/Dev-C++/ExerciseBook/05.30.2/05.30.2.dev @@ -0,0 +1,102 @@ +[Project] +FileName=05.30.2.dev +Name=05.30.2 +Type=1 +Ver=2 +ObjFiles= +Includes= +Libs= +PrivateResource= +ResourceIncludes= +MakeIncludes= +Compiler= +CppCompiler= +Linker= +IsCpp=0 +Icon= +ExeOutput= +ObjectOutput= +LogOutput= +LogOutputEnabled=0 +OverrideOutput=0 +OverrideOutputName= +HostApplication= +UseCustomMakefile=0 +CustomMakefile= +CommandLine= +Folders= +IncludeVersionInfo=0 +SupportXPThemes=0 +CompilerSet=1 +CompilerSettings=0000000000000000001000000 +UnitCount=5 + +[VersionInfo] +Major=1 +Minor=0 +Release=0 +Build=0 +LanguageID=1033 +CharsetID=1252 +CompanyName= +FileVersion= +FileDescription=Developed using the Dev-C++ IDE +InternalName= +LegalCopyright= +LegalTrademarks= +OriginalFilename= +ProductName= +ProductVersion= +AutoIncBuildNr=0 +SyncProduct=1 + +[Unit4] +FileName=SString.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit2] +FileName=GList-E.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit1] +FileName=05.30.2.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit3] +FileName=GList-E.h +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit5] +FileName=SString.h +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + diff --git a/Dev-C++/ExerciseBook/05.30.2/GList-E.cpp b/Dev-C++/ExerciseBook/05.30.2/GList-E.cpp new file mode 100644 index 0000000..3fc0ad9 --- /dev/null +++ b/Dev-C++/ExerciseBook/05.30.2/GList-E.cpp @@ -0,0 +1,449 @@ +/*=========================== + * չ洢ʾ + ============================*/ + +#include "GList-E.h" //**05 ͹**// + +/* + * ʼ + * + * ʼյĹΪ0Ϊ1 + * + *ע + * Ҫÿһſ + */ +Status InitGList(GList* L) { + if(L == NULL) { + return ERROR; + } + + *L = (GList) malloc(sizeof(GLNode)); + if(!*L) { + exit(OVERFLOW); + } + + (*L)->tag = List; + (*L)->Node.hp = NULL; + (*L)->tp = NULL; + + return OK; +} + +/* + * + * + * ַSL + */ +Status CreateGList(GList* L, SString S) { + SString emp, hsub, sub, tmp; + + if(L == NULL) { + return ERROR; + } + + // ַSеĿհףɴӡַո + ClearBlank(S); + + if(StrEmpty(S)) { + return ERROR; + } + + // Ϊ˲ƻS + StrCopy(sub, S); + + /* + * ִеʱ + * ٴִеʱѾȥ + */ + sever(hsub, sub); + + *L = (GList) malloc(sizeof(GLNode)); + if(*L == NULL) { + exit(OVERFLOW); + } + + StrAssign(emp, "()"); + + if(!StrCompare(hsub, emp)) { + (*L)->tag = List; + (*L)->Node.hp = NULL; + } else { + if(StrLength(hsub) == 1) { + (*L)->tag = Atom; + (*L)->Node.atom = hsub[1]; + } else { + (*L)->tag = List; + + SubString(tmp, hsub, 2, StrLength(hsub) - 2); + + CreateGList(&((*L)->Node.hp), tmp); + } + } + + // ڶβ˳ݹ + if(StrEmpty(sub)) { + (*L)->tp = NULL; + } else { + // ݹβ + CreateGList(&((*L)->tp), sub); + } + + return OK; +} + +/* + * + * + * ͷŹռڴ档 + */ +Status DestroyGList(GList* L) { + GList head, tail; + + if(L == NULL || *L == NULL) { + return ERROR; + } + + // ӱ + if((*L)->tag == List) { + head = (*L)->Node.hp; // ͷ + tail = (*L)->tp; // β + + free(*L); + *L = NULL; + + // ݹ鴦ͷ + if(head != NULL) { + DestroyGList(&head); + } + + // ݹ鴦β + if(tail != NULL) { + DestroyGList(&tail); + } + + // ԭӽ + } else { + tail = (*L)->tp; // β + + free(*L); + *L = NULL; + + if(tail != NULL) { + DestroyGList(&tail); + } + } + + return OK; +} + +/* + * + * + * ɹLƵõT + */ +Status CopyGList(GList* T, GList L) { + + if(L == NULL) { + return ERROR; + } + + *T = (GList) malloc(sizeof(GLNode)); + if(*T == NULL) { + exit(OVERFLOW); + } + + // ԭ + if(L->tag == Atom) { + (*T)->tag = Atom; + (*T)->Node.atom = L->Node.atom; + + // ӱ + } else { + (*T)->tag = List; + + // Ʊͷ + if(L->Node.hp != NULL) { + CopyGList(&((*T)->Node.hp), L->Node.hp); + } else { + (*T)->Node.hp = NULL; + } + } + + // Ʊβ + if(L->tp != NULL) { + CopyGList(&((*T)->tp), L->tp); + } else { + (*T)->tp = NULL; + } + + return OK; +} + +/* + * + * + * عijȡ + */ +int GListLength(GList L) { + int count = 0; + GList p; + + // + if(L == NULL) { + return -1; + } + + p = L->Node.hp; + + while(p != NULL) { + ++count; + p = p->tp; + } + + return count; +} + +/* + * + * + * ع + */ +int GListDepth(GList L) { + int max, deep; + GList p; + + max = 0; + + // + if(L == NULL) { + return -1; + } + + // ձΪ1 + if(L->tag == List && !L->Node.hp) { + return 1; + } + + // ԭΪ0 + if(L->tag == Atom) { + return 0; + } + + // ݹӱ + for(p = L->Node.hp; p != NULL; p = p->tp) { + // pΪͷָӱ + deep = GListDepth(p); + if(deep > max) { + max = deep; + } + } + + return max + 1; +} + +/* + * п + * + * жϹǷΪա + */ +Status GListEmpty(GList L) { + // + if(L == NULL) { + return ERROR; + } + + if(L->tag == List && L->Node.hp == NULL && L->tp == NULL) { + return TRUE; + } else { + return ERROR; + } +} + +/* + * ͷ + */ +GList GetHead(GList L) { + GList p, q; + + // ڻΪձ޷ȡͷ + if(L == NULL || L->Node.hp == NULL) { + return NULL; + } + + q = L->Node.hp->tp; // ʱLıβϢ + L->Node.hp->tp = NULL; // ȥLıβ + + CopyGList(&p, L->Node.hp); // ƱͷϢαβ + + L->Node.hp->tp = q; // ָLıβϢ + + return p; +} + +/* + * β + */ +GList GetTail(GList L) { + GList p, q; + + // ڻΪձ޷ȡβ + if(L == NULL || L->Node.hp == NULL) { + return NULL; + } + + q = L->Node.hp; // ʱLıͷϢ + L->Node.hp = q->tp; // ժLıͷ + + CopyGList(&p, L); // ƱβϢαͷ + + q->tp = L->Node.hp; // ָLıͷϢ + L->Node.hp = q; + + return p; +} + +/* + * + * + * ԪeΪLĵһԪء + */ +Status InsertFirst(GList* L, GList e) { + + // + if(L == NULL || *L == NULL) { + return ERROR; + } + + if(e == NULL) { + return ERROR; + } + + e->tp = (*L)->Node.hp; + (*L)->Node.hp = e; + + return OK; +} + +/* + * ɾ + * + * LĵһԪɾeء + */ +Status DeleteFirst(GList* L, GList* e) { + GList p; + + // ڻΪձ޷ɾͷ + if(*L == NULL || (*L)->Node.hp == NULL) { + return ERROR; + } + + p = (*L)->Node.hp; + (*L)->Node.hp = p->tp; + p->tp = NULL; + + *e = p; + + return OK; +} + +/* + * + * + * visitʹL + */ +void Traverse(GList L, void(Visit)(AtomType)) { + if(L == NULL) { + return; + } + + if(L->tag == List) { + Traverse(L->Node.hp, Visit); + } else { + Visit(L->Node.atom); + } + + Traverse(L->tp, Visit); +} + +/* + * ͼλ + * + * L + */ +void PrintGraph(GList L) { + Print(L); + printf("\n"); +} + +/* + * ͼλڲʵ֡ + */ +static void Print(GList L) { + if(L == NULL) { + return; + } + + // + if(L->tag == List) { + printf("("); + + if(L->Node.hp) { + Print(L->Node.hp); + } + + if(L->tp) { + printf("),"); + Print(L->tp); + } else { + printf(")"); + } + + // ԭӽ + } else { + printf("%c", L->Node.atom); + if(L->tp) { + printf(","); + Print(L->tp); + } + } +} + +/* + * ǿմstrָ֣hsubΪһ','֮ǰӴstrΪһ','֮Ӵ + * + *ע + * 1.ַstrȷ޿հ׷ţ + * strſȥҲδȥ + * 2.ɺstrҲᷢ仯 + */ +static void sever(SString hstr, SString str) { + int i, k, n; + SString ch; + + n = StrLength(str); + + i = 0; // ַʱα + k = 0; // δ + + do { + ++i; + + // ȡstrһַ + SubString(ch, str, i, 1); + + if(ch[1] == '(') { + ++k; + } + if(ch[1] == ')') { + --k; + } + } while(i < n && (ch[1] != ',' || k != 0)); + + if(i < n) { + SubString(hstr, str, 1, i - 1); + SubString(str, str, i + 1, n - i); + } else { + StrCopy(hstr, str); + ClearString(str); + } +} diff --git a/Dev-C++/ExerciseBook/05.30.2/GList-E.h b/Dev-C++/ExerciseBook/05.30.2/GList-E.h new file mode 100644 index 0000000..fa9af82 --- /dev/null +++ b/Dev-C++/ExerciseBook/05.30.2/GList-E.h @@ -0,0 +1,146 @@ +/*=========================== + * չ洢ʾ + ============================*/ + +#ifndef GLIST_E_H +#define GLIST_E_H + +#include +#include // ṩ mallocreallocfreeexit ԭ +#include "Status.h" //**01 **// +#include "SString.h" //**04 **// + +/* ԭԪ */ +typedef char AtomType; //ԭ + +/* + * + * + * Atom-0ԭӽ + * List-1 + */ +typedef enum { Atom, List } ElemTag; + +/* չ洢ʾͶ */ +typedef struct GLNode { + ElemTag tag; // ǣԭӽͱ + + // ԭӽͱϲ + union + { + AtomType atom; // atomԭӽֵAtomTypeû + struct GLNode* hp; // ָͷ + } Node; + struct GLNode* tp; // ָβ +} GLNode; + +/* */ +typedef GLNode* GList; + + +/* + * ʼ + * + * ʼյĹΪ0Ϊ1 + * + *ע + * Ҫÿһſ + */ +Status InitGList(GList* L); + +/* + * + * + * ַSL + */ +Status CreateGList(GList* L, SString S); + +/* + * + * + * ͷŹռڴ档 + */ +Status DestroyGList(GList* L); + +/* + * + * + * ɹLƵõT + */ +Status CopyGList(GList* T, GList L); + +/* + * + * + * عijȡ + */ +int GListLength(GList L); + +/* + * + * + * ع + */ +int GListDepth(GList L); + +/* + * п + * + * жϹǷΪա + */ +Status GListEmpty(GList L); + +/* + * ͷ + */ +GList GetHead(GList L); + +/* + * β + */ +GList GetTail(GList L); + +/* + * + * + * ԪeΪLĵһԪء + */ +Status InsertFirst(GList* L, GList e); + +/* + * ɾ + * + * LĵһԪɾeء + */ +Status DeleteFirst(GList* L, GList* e); + +/* + * + * + * visitʹL + */ +void Traverse(GList L, void(Visit)(AtomType)); + +/* + * ͼλ + * + * L + */ +void PrintGraph(GList L); + +/* + * ͼλڲʵ֡ + */ +static void Print(GList L); + +/* + * ǿմstrָ֣hsubΪһ','֮ǰӴstrΪһ','֮Ӵ + * + *ע + * 1.ַstrȷ޿հ׷ţ + * strſȥҲδȥ + * 2.ɺstrҲᷢ仯 + */ +static void sever(SString hstr, SString str); + +#endif diff --git a/Dev-C++/ExerciseBook/05.30.2/SString.cpp b/Dev-C++/ExerciseBook/05.30.2/SString.cpp new file mode 100644 index 0000000..7a96fcf --- /dev/null +++ b/Dev-C++/ExerciseBook/05.30.2/SString.cpp @@ -0,0 +1,195 @@ +/*============================= + * Ķ˳洢ʾ˳򴮣 + * + * 㷨: 4.14.24.34.5 + ==============================*/ + +#include "SString.h" //**04 **// + +/* + * ʼ + * + * һֵΪcharsĴT + * + *ע + * òСӼ + */ +Status StrAssign(SString T, const char* chars) { + int i, len; + + len = (int) strlen(chars); + + // chars + if(len > MAXSTRLEN) { + return ERROR; + } + + T[0] = len; + for(i = 1; i <= len; i++) { + T[i] = chars[i - 1]; + } + + return OK; +} + +/* + * + * + * Sա + */ +Status ClearString(SString S) { + // ֻҪΪ0Ϳ + S[0] = 0; + return OK; +} + +/* + * п + * + * жϴSǷЧݡ + * + * ֵ + * TRUE : SΪ + * FALSE: SΪ + */ +Status StrEmpty(SString S) { + return S[0] == 0 ? TRUE : FALSE; +} + +/* + * + * + * شSԪصĸ + * + *ע + * òСӼ + */ +int StrLength(SString S) { + return S[0]; +} + +/* + * 㷨4.3 + * + * Ӵ + * + * SubS[pos, pos+len-1] + * ֵָʾǷȡɹ + * + *ע + * òСӼ + */ +Status SubString(SString Sub, SString S, int pos, int len) { + int i; + + if(pos < 1 || pos > S[0] || len < 0 || pos + len - 1 > S[0]) { + return ERROR; + } + + // Ԫ + for(i = 1; i <= len; i++) { + Sub[i] = S[pos + i - 1]; + } + + // ȷ³ + Sub[0] = len; + + return OK; +} + +/* + * ɾ + * + * ɾS[pos, pos+len-1] + */ +Status StrDelete(SString S, int pos, int len) { + int i; + + if(pos < 1 || pos + len - 1 > S[0] || len < 0) { + return ERROR; + } + + // ɾijΪ0ǰ + if(len == 0) { + return OK; + } + + // ѺԪŲǰ棬ǵɾԪ + for(i = pos + len; i <= S[0]; i++) { + S[i - len] = S[i]; + } + + // ȼ + S[0] -= len; + + return OK; +} + +/* + * Ƚ + * + * ȽϴSʹTرȽϽ + * + *ע + * òСӼ + */ +int StrCompare(SString S, SString T) { + int i = 1; + + while(i <= S[0] && i <= T[0]) { + // ַͬʱȽС + if(S[i] != T[i]) { + return S[i] - T[i]; + } + + i++; + } + + return S[0] - T[0]; +} + +/* + * + * + * SƵT + */ +Status StrCopy(SString T, SString S) { + int i; + + // ͬϢһ + for(i = 0; i <= S[0]; i++) { + T[i] = S[i]; + } + + return OK; +} + +/* + * ַSеĿհףɴӡַո + * + *ע + * úڱġ + */ +Status ClearBlank(SString S) { + int i, j; + + // ǿմ + if(S[0] == 0) { + return ERROR; + } + + for(i = 1, j = 0; i <= S[0]; i++) { + // հףԹ + if(S[i] == ' ' || !isprint(S[i])) { + continue; + } + + j++; + + S[j] = S[i]; + } + + S[0] = j; + + return OK; +} diff --git a/Dev-C++/ExerciseBook/05.30.2/SString.h b/Dev-C++/ExerciseBook/05.30.2/SString.h new file mode 100644 index 0000000..0632f18 --- /dev/null +++ b/Dev-C++/ExerciseBook/05.30.2/SString.h @@ -0,0 +1,117 @@ +/*============================= + * Ķ˳洢ʾ˳򴮣 + * + * 㷨: 4.14.24.34.5 + ==============================*/ + +#ifndef SSTRING_H +#define SSTRING_H + +#include +#include // ṩ strlen ԭ +#include // ṩ isprint ԭ +#include "Status.h" //**01 **// + +/* 궨 */ +#define MAXSTRLEN 255 // ˳򴮵󴮳 + +/* + * ˳洢Ͷ + * + * עЧԪشSString1ŵԪʼ洢 + * SString0ŵԪ洢䳤 + */ +typedef unsigned char SString[MAXSTRLEN + 1]; // 0ŵԪŴij + + +/* + * ʾ + * + * ѭ̲ĵдϰߣposָʾַλ()1ʼ + */ + + +/* + * ʼ + * + * һֵΪcharsĴT + * + *ע + * òСӼ + */ +Status StrAssign(SString T, const char* chars); + +/* + * + * + * Sա + */ +Status ClearString(SString S); + +/* + * п + * + * жϴSǷЧݡ + * + * ֵ + * TRUE : SΪ + * FALSE: SΪ + */ +Status StrEmpty(SString S); + +/* + * + * + * شSԪصĸ + * + *ע + * òСӼ + */ +int StrLength(SString S); + +/* + * 㷨4.3 + * + * Ӵ + * + * SubS[pos, pos+len-1] + * ֵָʾǷȡɹ + * + *ע + * òСӼ + */ +Status SubString(SString Sub, SString S, int pos, int len); + +/* + * ɾ + * + * ɾS[pos, pos+len-1] + */ +Status StrDelete(SString S, int pos, int len); + +/* + * Ƚ + * + * ȽϴSʹTرȽϽ + * + *ע + * òСӼ + */ +int StrCompare(SString S, SString T); + +/* + * + * + * SƵT + */ +Status StrCopy(SString T, SString S); + +/* + * ַSеĿհףɴӡַո + * + *ע + * úڱġ + */ +Status ClearBlank(SString S); + +#endif diff --git a/Dev-C++/ExerciseBook/05.31/05.31.cpp b/Dev-C++/ExerciseBook/05.31/05.31.cpp new file mode 100644 index 0000000..da70a36 --- /dev/null +++ b/Dev-C++/ExerciseBook/05.31/05.31.cpp @@ -0,0 +1,43 @@ +#include +#include "Status.h" //**01 **// +#include "SString.h" //**04 **// +#include "GList-E.h" //**05 ͹**// + +/* + * ƣչ洢ʾ + * + *ע + * úGList-Eļж + */ +Status Algo_5_31(GList* T, GList L); + + +int main(int argc, char* argv[]) { + GList L, T; + char* s = "((),(e),(a,(b,c,d)))"; + SString S; + + printf(" L ...\n"); + StrAssign(S, s); + CreateGList(&L, S); + printf("L = "); + PrintGraph(L); + + printf("ƹ L T...\n"); + Algo_5_31(&T, L); + printf("T = "); + PrintGraph(T); + + return 0; +} + + +/* + * ƣչ洢ʾ + * + *ע + * úGList-Eļж + */ +Status Algo_5_31(GList* T, GList L) { + return CopyGList(T, L); +} diff --git a/Dev-C++/ExerciseBook/05.31/05.31.dev b/Dev-C++/ExerciseBook/05.31/05.31.dev new file mode 100644 index 0000000..4424705 --- /dev/null +++ b/Dev-C++/ExerciseBook/05.31/05.31.dev @@ -0,0 +1,102 @@ +[Project] +FileName=05.31.dev +Name=05.31 +Type=1 +Ver=2 +ObjFiles= +Includes= +Libs= +PrivateResource= +ResourceIncludes= +MakeIncludes= +Compiler= +CppCompiler= +Linker= +IsCpp=0 +Icon= +ExeOutput= +ObjectOutput= +LogOutput= +LogOutputEnabled=0 +OverrideOutput=0 +OverrideOutputName= +HostApplication= +UseCustomMakefile=0 +CustomMakefile= +CommandLine= +Folders= +IncludeVersionInfo=0 +SupportXPThemes=0 +CompilerSet=1 +CompilerSettings=0000000000000000001000000 +UnitCount=5 + +[VersionInfo] +Major=1 +Minor=0 +Release=0 +Build=0 +LanguageID=1033 +CharsetID=1252 +CompanyName= +FileVersion= +FileDescription=Developed using the Dev-C++ IDE +InternalName= +LegalCopyright= +LegalTrademarks= +OriginalFilename= +ProductName= +ProductVersion= +AutoIncBuildNr=0 +SyncProduct=1 + +[Unit4] +FileName=SString.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit2] +FileName=GList-E.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit1] +FileName=05.31.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit3] +FileName=GList-E.h +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit5] +FileName=SString.h +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + diff --git a/Dev-C++/ExerciseBook/05.31/GList-E.cpp b/Dev-C++/ExerciseBook/05.31/GList-E.cpp new file mode 100644 index 0000000..3fc0ad9 --- /dev/null +++ b/Dev-C++/ExerciseBook/05.31/GList-E.cpp @@ -0,0 +1,449 @@ +/*=========================== + * չ洢ʾ + ============================*/ + +#include "GList-E.h" //**05 ͹**// + +/* + * ʼ + * + * ʼյĹΪ0Ϊ1 + * + *ע + * Ҫÿһſ + */ +Status InitGList(GList* L) { + if(L == NULL) { + return ERROR; + } + + *L = (GList) malloc(sizeof(GLNode)); + if(!*L) { + exit(OVERFLOW); + } + + (*L)->tag = List; + (*L)->Node.hp = NULL; + (*L)->tp = NULL; + + return OK; +} + +/* + * + * + * ַSL + */ +Status CreateGList(GList* L, SString S) { + SString emp, hsub, sub, tmp; + + if(L == NULL) { + return ERROR; + } + + // ַSеĿհףɴӡַո + ClearBlank(S); + + if(StrEmpty(S)) { + return ERROR; + } + + // Ϊ˲ƻS + StrCopy(sub, S); + + /* + * ִеʱ + * ٴִеʱѾȥ + */ + sever(hsub, sub); + + *L = (GList) malloc(sizeof(GLNode)); + if(*L == NULL) { + exit(OVERFLOW); + } + + StrAssign(emp, "()"); + + if(!StrCompare(hsub, emp)) { + (*L)->tag = List; + (*L)->Node.hp = NULL; + } else { + if(StrLength(hsub) == 1) { + (*L)->tag = Atom; + (*L)->Node.atom = hsub[1]; + } else { + (*L)->tag = List; + + SubString(tmp, hsub, 2, StrLength(hsub) - 2); + + CreateGList(&((*L)->Node.hp), tmp); + } + } + + // ڶβ˳ݹ + if(StrEmpty(sub)) { + (*L)->tp = NULL; + } else { + // ݹβ + CreateGList(&((*L)->tp), sub); + } + + return OK; +} + +/* + * + * + * ͷŹռڴ档 + */ +Status DestroyGList(GList* L) { + GList head, tail; + + if(L == NULL || *L == NULL) { + return ERROR; + } + + // ӱ + if((*L)->tag == List) { + head = (*L)->Node.hp; // ͷ + tail = (*L)->tp; // β + + free(*L); + *L = NULL; + + // ݹ鴦ͷ + if(head != NULL) { + DestroyGList(&head); + } + + // ݹ鴦β + if(tail != NULL) { + DestroyGList(&tail); + } + + // ԭӽ + } else { + tail = (*L)->tp; // β + + free(*L); + *L = NULL; + + if(tail != NULL) { + DestroyGList(&tail); + } + } + + return OK; +} + +/* + * + * + * ɹLƵõT + */ +Status CopyGList(GList* T, GList L) { + + if(L == NULL) { + return ERROR; + } + + *T = (GList) malloc(sizeof(GLNode)); + if(*T == NULL) { + exit(OVERFLOW); + } + + // ԭ + if(L->tag == Atom) { + (*T)->tag = Atom; + (*T)->Node.atom = L->Node.atom; + + // ӱ + } else { + (*T)->tag = List; + + // Ʊͷ + if(L->Node.hp != NULL) { + CopyGList(&((*T)->Node.hp), L->Node.hp); + } else { + (*T)->Node.hp = NULL; + } + } + + // Ʊβ + if(L->tp != NULL) { + CopyGList(&((*T)->tp), L->tp); + } else { + (*T)->tp = NULL; + } + + return OK; +} + +/* + * + * + * عijȡ + */ +int GListLength(GList L) { + int count = 0; + GList p; + + // + if(L == NULL) { + return -1; + } + + p = L->Node.hp; + + while(p != NULL) { + ++count; + p = p->tp; + } + + return count; +} + +/* + * + * + * ع + */ +int GListDepth(GList L) { + int max, deep; + GList p; + + max = 0; + + // + if(L == NULL) { + return -1; + } + + // ձΪ1 + if(L->tag == List && !L->Node.hp) { + return 1; + } + + // ԭΪ0 + if(L->tag == Atom) { + return 0; + } + + // ݹӱ + for(p = L->Node.hp; p != NULL; p = p->tp) { + // pΪͷָӱ + deep = GListDepth(p); + if(deep > max) { + max = deep; + } + } + + return max + 1; +} + +/* + * п + * + * жϹǷΪա + */ +Status GListEmpty(GList L) { + // + if(L == NULL) { + return ERROR; + } + + if(L->tag == List && L->Node.hp == NULL && L->tp == NULL) { + return TRUE; + } else { + return ERROR; + } +} + +/* + * ͷ + */ +GList GetHead(GList L) { + GList p, q; + + // ڻΪձ޷ȡͷ + if(L == NULL || L->Node.hp == NULL) { + return NULL; + } + + q = L->Node.hp->tp; // ʱLıβϢ + L->Node.hp->tp = NULL; // ȥLıβ + + CopyGList(&p, L->Node.hp); // ƱͷϢαβ + + L->Node.hp->tp = q; // ָLıβϢ + + return p; +} + +/* + * β + */ +GList GetTail(GList L) { + GList p, q; + + // ڻΪձ޷ȡβ + if(L == NULL || L->Node.hp == NULL) { + return NULL; + } + + q = L->Node.hp; // ʱLıͷϢ + L->Node.hp = q->tp; // ժLıͷ + + CopyGList(&p, L); // ƱβϢαͷ + + q->tp = L->Node.hp; // ָLıͷϢ + L->Node.hp = q; + + return p; +} + +/* + * + * + * ԪeΪLĵһԪء + */ +Status InsertFirst(GList* L, GList e) { + + // + if(L == NULL || *L == NULL) { + return ERROR; + } + + if(e == NULL) { + return ERROR; + } + + e->tp = (*L)->Node.hp; + (*L)->Node.hp = e; + + return OK; +} + +/* + * ɾ + * + * LĵһԪɾeء + */ +Status DeleteFirst(GList* L, GList* e) { + GList p; + + // ڻΪձ޷ɾͷ + if(*L == NULL || (*L)->Node.hp == NULL) { + return ERROR; + } + + p = (*L)->Node.hp; + (*L)->Node.hp = p->tp; + p->tp = NULL; + + *e = p; + + return OK; +} + +/* + * + * + * visitʹL + */ +void Traverse(GList L, void(Visit)(AtomType)) { + if(L == NULL) { + return; + } + + if(L->tag == List) { + Traverse(L->Node.hp, Visit); + } else { + Visit(L->Node.atom); + } + + Traverse(L->tp, Visit); +} + +/* + * ͼλ + * + * L + */ +void PrintGraph(GList L) { + Print(L); + printf("\n"); +} + +/* + * ͼλڲʵ֡ + */ +static void Print(GList L) { + if(L == NULL) { + return; + } + + // + if(L->tag == List) { + printf("("); + + if(L->Node.hp) { + Print(L->Node.hp); + } + + if(L->tp) { + printf("),"); + Print(L->tp); + } else { + printf(")"); + } + + // ԭӽ + } else { + printf("%c", L->Node.atom); + if(L->tp) { + printf(","); + Print(L->tp); + } + } +} + +/* + * ǿմstrָ֣hsubΪһ','֮ǰӴstrΪһ','֮Ӵ + * + *ע + * 1.ַstrȷ޿հ׷ţ + * strſȥҲδȥ + * 2.ɺstrҲᷢ仯 + */ +static void sever(SString hstr, SString str) { + int i, k, n; + SString ch; + + n = StrLength(str); + + i = 0; // ַʱα + k = 0; // δ + + do { + ++i; + + // ȡstrһַ + SubString(ch, str, i, 1); + + if(ch[1] == '(') { + ++k; + } + if(ch[1] == ')') { + --k; + } + } while(i < n && (ch[1] != ',' || k != 0)); + + if(i < n) { + SubString(hstr, str, 1, i - 1); + SubString(str, str, i + 1, n - i); + } else { + StrCopy(hstr, str); + ClearString(str); + } +} diff --git a/Dev-C++/ExerciseBook/05.31/GList-E.h b/Dev-C++/ExerciseBook/05.31/GList-E.h new file mode 100644 index 0000000..fa9af82 --- /dev/null +++ b/Dev-C++/ExerciseBook/05.31/GList-E.h @@ -0,0 +1,146 @@ +/*=========================== + * չ洢ʾ + ============================*/ + +#ifndef GLIST_E_H +#define GLIST_E_H + +#include +#include // ṩ mallocreallocfreeexit ԭ +#include "Status.h" //**01 **// +#include "SString.h" //**04 **// + +/* ԭԪ */ +typedef char AtomType; //ԭ + +/* + * + * + * Atom-0ԭӽ + * List-1 + */ +typedef enum { Atom, List } ElemTag; + +/* չ洢ʾͶ */ +typedef struct GLNode { + ElemTag tag; // ǣԭӽͱ + + // ԭӽͱϲ + union + { + AtomType atom; // atomԭӽֵAtomTypeû + struct GLNode* hp; // ָͷ + } Node; + struct GLNode* tp; // ָβ +} GLNode; + +/* */ +typedef GLNode* GList; + + +/* + * ʼ + * + * ʼյĹΪ0Ϊ1 + * + *ע + * Ҫÿһſ + */ +Status InitGList(GList* L); + +/* + * + * + * ַSL + */ +Status CreateGList(GList* L, SString S); + +/* + * + * + * ͷŹռڴ档 + */ +Status DestroyGList(GList* L); + +/* + * + * + * ɹLƵõT + */ +Status CopyGList(GList* T, GList L); + +/* + * + * + * عijȡ + */ +int GListLength(GList L); + +/* + * + * + * ع + */ +int GListDepth(GList L); + +/* + * п + * + * жϹǷΪա + */ +Status GListEmpty(GList L); + +/* + * ͷ + */ +GList GetHead(GList L); + +/* + * β + */ +GList GetTail(GList L); + +/* + * + * + * ԪeΪLĵһԪء + */ +Status InsertFirst(GList* L, GList e); + +/* + * ɾ + * + * LĵһԪɾeء + */ +Status DeleteFirst(GList* L, GList* e); + +/* + * + * + * visitʹL + */ +void Traverse(GList L, void(Visit)(AtomType)); + +/* + * ͼλ + * + * L + */ +void PrintGraph(GList L); + +/* + * ͼλڲʵ֡ + */ +static void Print(GList L); + +/* + * ǿմstrָ֣hsubΪһ','֮ǰӴstrΪһ','֮Ӵ + * + *ע + * 1.ַstrȷ޿հ׷ţ + * strſȥҲδȥ + * 2.ɺstrҲᷢ仯 + */ +static void sever(SString hstr, SString str); + +#endif diff --git a/Dev-C++/ExerciseBook/05.31/SString.cpp b/Dev-C++/ExerciseBook/05.31/SString.cpp new file mode 100644 index 0000000..7a96fcf --- /dev/null +++ b/Dev-C++/ExerciseBook/05.31/SString.cpp @@ -0,0 +1,195 @@ +/*============================= + * Ķ˳洢ʾ˳򴮣 + * + * 㷨: 4.14.24.34.5 + ==============================*/ + +#include "SString.h" //**04 **// + +/* + * ʼ + * + * һֵΪcharsĴT + * + *ע + * òСӼ + */ +Status StrAssign(SString T, const char* chars) { + int i, len; + + len = (int) strlen(chars); + + // chars + if(len > MAXSTRLEN) { + return ERROR; + } + + T[0] = len; + for(i = 1; i <= len; i++) { + T[i] = chars[i - 1]; + } + + return OK; +} + +/* + * + * + * Sա + */ +Status ClearString(SString S) { + // ֻҪΪ0Ϳ + S[0] = 0; + return OK; +} + +/* + * п + * + * жϴSǷЧݡ + * + * ֵ + * TRUE : SΪ + * FALSE: SΪ + */ +Status StrEmpty(SString S) { + return S[0] == 0 ? TRUE : FALSE; +} + +/* + * + * + * شSԪصĸ + * + *ע + * òСӼ + */ +int StrLength(SString S) { + return S[0]; +} + +/* + * 㷨4.3 + * + * Ӵ + * + * SubS[pos, pos+len-1] + * ֵָʾǷȡɹ + * + *ע + * òСӼ + */ +Status SubString(SString Sub, SString S, int pos, int len) { + int i; + + if(pos < 1 || pos > S[0] || len < 0 || pos + len - 1 > S[0]) { + return ERROR; + } + + // Ԫ + for(i = 1; i <= len; i++) { + Sub[i] = S[pos + i - 1]; + } + + // ȷ³ + Sub[0] = len; + + return OK; +} + +/* + * ɾ + * + * ɾS[pos, pos+len-1] + */ +Status StrDelete(SString S, int pos, int len) { + int i; + + if(pos < 1 || pos + len - 1 > S[0] || len < 0) { + return ERROR; + } + + // ɾijΪ0ǰ + if(len == 0) { + return OK; + } + + // ѺԪŲǰ棬ǵɾԪ + for(i = pos + len; i <= S[0]; i++) { + S[i - len] = S[i]; + } + + // ȼ + S[0] -= len; + + return OK; +} + +/* + * Ƚ + * + * ȽϴSʹTرȽϽ + * + *ע + * òСӼ + */ +int StrCompare(SString S, SString T) { + int i = 1; + + while(i <= S[0] && i <= T[0]) { + // ַͬʱȽС + if(S[i] != T[i]) { + return S[i] - T[i]; + } + + i++; + } + + return S[0] - T[0]; +} + +/* + * + * + * SƵT + */ +Status StrCopy(SString T, SString S) { + int i; + + // ͬϢһ + for(i = 0; i <= S[0]; i++) { + T[i] = S[i]; + } + + return OK; +} + +/* + * ַSеĿհףɴӡַո + * + *ע + * úڱġ + */ +Status ClearBlank(SString S) { + int i, j; + + // ǿմ + if(S[0] == 0) { + return ERROR; + } + + for(i = 1, j = 0; i <= S[0]; i++) { + // հףԹ + if(S[i] == ' ' || !isprint(S[i])) { + continue; + } + + j++; + + S[j] = S[i]; + } + + S[0] = j; + + return OK; +} diff --git a/Dev-C++/ExerciseBook/05.31/SString.h b/Dev-C++/ExerciseBook/05.31/SString.h new file mode 100644 index 0000000..0632f18 --- /dev/null +++ b/Dev-C++/ExerciseBook/05.31/SString.h @@ -0,0 +1,117 @@ +/*============================= + * Ķ˳洢ʾ˳򴮣 + * + * 㷨: 4.14.24.34.5 + ==============================*/ + +#ifndef SSTRING_H +#define SSTRING_H + +#include +#include // ṩ strlen ԭ +#include // ṩ isprint ԭ +#include "Status.h" //**01 **// + +/* 궨 */ +#define MAXSTRLEN 255 // ˳򴮵󴮳 + +/* + * ˳洢Ͷ + * + * עЧԪشSString1ŵԪʼ洢 + * SString0ŵԪ洢䳤 + */ +typedef unsigned char SString[MAXSTRLEN + 1]; // 0ŵԪŴij + + +/* + * ʾ + * + * ѭ̲ĵдϰߣposָʾַλ()1ʼ + */ + + +/* + * ʼ + * + * һֵΪcharsĴT + * + *ע + * òСӼ + */ +Status StrAssign(SString T, const char* chars); + +/* + * + * + * Sա + */ +Status ClearString(SString S); + +/* + * п + * + * жϴSǷЧݡ + * + * ֵ + * TRUE : SΪ + * FALSE: SΪ + */ +Status StrEmpty(SString S); + +/* + * + * + * شSԪصĸ + * + *ע + * òСӼ + */ +int StrLength(SString S); + +/* + * 㷨4.3 + * + * Ӵ + * + * SubS[pos, pos+len-1] + * ֵָʾǷȡɹ + * + *ע + * òСӼ + */ +Status SubString(SString Sub, SString S, int pos, int len); + +/* + * ɾ + * + * ɾS[pos, pos+len-1] + */ +Status StrDelete(SString S, int pos, int len); + +/* + * Ƚ + * + * ȽϴSʹTرȽϽ + * + *ע + * òСӼ + */ +int StrCompare(SString S, SString T); + +/* + * + * + * SƵT + */ +Status StrCopy(SString T, SString S); + +/* + * ַSеĿհףɴӡַո + * + *ע + * úڱġ + */ +Status ClearBlank(SString S); + +#endif diff --git a/Dev-C++/ExerciseBook/05.32.1/05.32.1.cpp b/Dev-C++/ExerciseBook/05.32.1/05.32.1.cpp new file mode 100644 index 0000000..49d7e91 --- /dev/null +++ b/Dev-C++/ExerciseBook/05.32.1/05.32.1.cpp @@ -0,0 +1,64 @@ +#include +#include "Status.h" //**01 **// +#include "SString.h" //**04 **// +#include "GList-HT.h" //**05 ͹**// + +/* + * жϹǷȣͷβ洢ʾ + */ +Status Algo_5_32_1(GList A, GList B); + + +int main(int argc, char* argv[]) { + GList A, B; + char* a = "((),(e),(a,(b,c,d)))"; + char* b = "((),(e),(a,(b,c,f)))"; + SString Sa, Sb; + + printf(" AB ...\n"); + StrAssign(Sa, a); + CreateGList(&A, Sa); + StrAssign(Sb, b); + CreateGList(&B, Sb); + printf("A = "); + PrintGraph(A); + printf("B = "); + PrintGraph(B); + + Algo_5_32_1(A, B) ? printf("ȣ\n") : printf("ȣ\n"); + + return 0; +} + + +/* + * жϹǷȣͷβ洢ʾ + */ +Status Algo_5_32_1(GList A, GList B) { + if(!A && !B) { + return TRUE; // ձ + } + + // Ϊ + if(A && B) { + // Ԫͬ + if(A->tag == B->tag) { + // ԭӽ + if(A->tag == Atom) { + if(A->Node.atom == B->Node.atom) { + return TRUE; + } + + // + } else { + if(Algo_5_32_1(A->Node.ptr.hp, B->Node.ptr.hp) == TRUE) { + if(Algo_5_32_1(A->Node.ptr.tp, B->Node.ptr.tp) == TRUE) { + return TRUE; + } + } + } + } + } + + return FALSE; +} diff --git a/Dev-C++/ExerciseBook/05.32.1/05.32.1.dev b/Dev-C++/ExerciseBook/05.32.1/05.32.1.dev new file mode 100644 index 0000000..85de419 --- /dev/null +++ b/Dev-C++/ExerciseBook/05.32.1/05.32.1.dev @@ -0,0 +1,102 @@ +[Project] +FileName=05.32.1.dev +Name=05.32.1 +Type=1 +Ver=2 +ObjFiles= +Includes= +Libs= +PrivateResource= +ResourceIncludes= +MakeIncludes= +Compiler= +CppCompiler= +Linker= +IsCpp=0 +Icon= +ExeOutput= +ObjectOutput= +LogOutput= +LogOutputEnabled=0 +OverrideOutput=0 +OverrideOutputName= +HostApplication= +UseCustomMakefile=0 +CustomMakefile= +CommandLine= +Folders= +IncludeVersionInfo=0 +SupportXPThemes=0 +CompilerSet=1 +CompilerSettings=0000000000000000001000000 +UnitCount=5 + +[VersionInfo] +Major=1 +Minor=0 +Release=0 +Build=0 +LanguageID=1033 +CharsetID=1252 +CompanyName= +FileVersion= +FileDescription=Developed using the Dev-C++ IDE +InternalName= +LegalCopyright= +LegalTrademarks= +OriginalFilename= +ProductName= +ProductVersion= +AutoIncBuildNr=0 +SyncProduct=1 + +[Unit4] +FileName=SString.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit2] +FileName=GList-HT.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit1] +FileName=05.32.1.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit3] +FileName=GList-HT.h +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit5] +FileName=SString.h +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + diff --git a/Dev-C++/ExerciseBook/05.32.1/GList-HT.cpp b/Dev-C++/ExerciseBook/05.32.1/GList-HT.cpp new file mode 100644 index 0000000..bad30df --- /dev/null +++ b/Dev-C++/ExerciseBook/05.32.1/GList-HT.cpp @@ -0,0 +1,418 @@ +/*============================ + * ͷβ洢ʾ + * + * 㷨: 5.55.65.75.8 + =============================*/ + +#include "GList-HT.h" //**05 ͹**// + +/* + * ʼ + * + * ʼյĹΪ0Ϊ1 + * + *ע + * Ҫÿһȥſ + */ +Status InitGList(GList* L) { + if(L == NULL) { + return ERROR; + } + + *L = NULL; + + return OK; +} + +/* + * 㷨5.7 + * + * + * + * ַSL + */ +Status CreateGList(GList* L, SString S) { + SString emp; // չַ + SString hsub, sub; + GList p, q; + + if(L == NULL) { + return ERROR; + } + + // ַSеĿհףɴӡַո + ClearBlank(S); + + if(StrEmpty(S)) { + return ERROR; + } + + StrAssign(emp, "()"); + + /* + * 봮Ϊ()ҪյĹ + * + *ע + * ̲Ĵġ + * StrCompareķֵָʾַĴСָʾַǷȡ + * S()ȣֵӦ0 + */ + if(!StrCompare(S, emp)) { + *L = NULL; + } else { + *L = (GList) malloc(sizeof(GLNode)); + if(*L == NULL) { + exit(OVERFLOW); + } + + // ԭ + if(StrLength(S) == 1) { + (*L)->tag = Atom; + (*L)->Node.atom = S[1]; + } else { + (*L)->tag = List; + + p = *L; + + // ȥ + SubString(sub, S, 2, StrLength(S) - 2); + + // ظnӱ + do { + // subзͷhsubɺsubҲᷢ仯 + sever(hsub, sub); + + // ݹ鴴 + CreateGList(&(p->Node.ptr.hp), hsub); + + q = p; + + // βΪգҪβ + if(!StrEmpty(sub)) { + p = (GList) malloc(sizeof(GLNode)); + if(p == NULL) { + exit(OVERFLOW); + } + + p->tag = List; + + q->Node.ptr.tp = p; + } + } while(!StrEmpty(sub)); + + q->Node.ptr.tp = NULL; + } + } + + return OK; +} + +/* + * + * + * ͷŹռڴ档 + */ +Status DestroyGList(GList* L) { + GList head, tail; + + if(L == NULL || *L == NULL) { + return ERROR; + } + + // ɾԭӽ + if((*L)->tag == Atom) { + free(*L); + *L = NULL; + + // ɾӱ + } else { + head = (*L)->Node.ptr.hp; + tail = (*L)->Node.ptr.tp; + free(*L); + *L = NULL; + DestroyGList(&head); + DestroyGList(&tail); + } + + return OK; +} + +/* + * 㷨5.6 + * + * + * + * ɹLƵõT + */ +Status CopyGList(GList* T, GList L) { + if(T == NULL) { + return ERROR; + } + + if(L == NULL) { + *T = NULL; + } else { + // ½ + *T = (GList) malloc(sizeof(GLNode)); + if(*T == NULL) { + exit(OVERFLOW); + } + + (*T)->tag = L->tag; + + // Ƶԭ + if(L->tag == Atom) { + (*T)->Node.atom = L->Node.atom; + + // Ʊͷͱβ + } else { + CopyGList(&((*T)->Node.ptr.hp), L->Node.ptr.hp); + CopyGList(&((*T)->Node.ptr.tp), L->Node.ptr.tp); + } + } + + return OK; +} + +/* + * + * + * عijȡ + */ +int GListLength(GList L) { + int count; + + for(count = 0; L != NULL; count++, L = L->Node.ptr.tp) { + } + + return count; +} + +/* + * 㷨5.5 + * + * + * + * ع + */ +int GListDepth(GList L) { + int max, deep; + GList p; + + // ձΪ1 + if(L == NULL) { + return 1; + } + + // ԭΪ0 + if(L->tag == Atom) { + return 0; + } + + // ݹӱ + for(max = 0, p = L; p != NULL; p = p->Node.ptr.tp) { + deep = GListDepth(p->Node.ptr.hp); + if(deep > max) { + max = deep; + } + } + + // ǿձǸԪȼһ + return max + 1; +} + +/* + * п + * + * жϹǷΪա + */ +Status GListEmpty(GList L) { + return L == NULL ? TRUE : FALSE; +} + +/* + * ͷ + */ +GList GetHead(GList L) { + GList p; + + // ձޱͷﲻܷNULLȻֲʧ˻Ƿ˿ձ + if(L == NULL) { + exit(ERROR); + } + + CopyGList(&p, L->Node.ptr.hp); + + return p; +} + +/* + * β + */ +GList GetTail(GList L) { + GList p; + + // ձޱβﲻܷNULLȻֲʧ˻Ƿ˿ձ + if(L == NULL) { + exit(ERROR); + } + + CopyGList(&p, L->Node.ptr.tp); + + return p; +} + +/* + * + * + * ԪeΪLĵһԪء + */ +Status InsertFirst(GList* L, GList e) { + GList g; + + if(L == NULL) { + return ERROR; + } + + g = (GList) malloc(sizeof(GLNode)); + if(g == NULL) { + exit(OVERFLOW); + } + + g->tag = List; + g->Node.ptr.hp = e; + g->Node.ptr.tp = *L; + *L = g; + + return OK; +} + +/* + * ɾ + * + * LĵһԪɾeء + */ +Status DeleteFirst(GList* L, GList* e) { + GList p; + + // ձ޷ɾ + if(L == NULL || *L == NULL) { + return ERROR; + } + + p = *L; + *L = (*L)->Node.ptr.tp; + + CopyGList(e, p->Node.ptr.hp); + + free(p); + + return OK; +} + +/* + * + * + * visitʹL + */ +void Traverse(GList L, void(Visit)(AtomType)) { + + if(L == NULL) { + return; + } + + if(L->tag == Atom) { + Visit(L->Node.atom); + } else { + Traverse(L->Node.ptr.hp, Visit); + Traverse(L->Node.ptr.tp, Visit); + } + +} + +/* + * ͼλ + * + * L + */ +void PrintGraph(GList L) { + Print(L, Head); + printf("\n"); +} + +/* + * ͼλڲʵ֣markͼλǡ + */ +static void Print(GList L, Mark mark) { + // LΪ + if(L == NULL) { + if(mark == Head) { + printf("("); + } + + printf(")"); + + // LΪʱ + } else { + // ԭӽ㣬ԭ + if(L->tag == Atom) { + printf("%c", L->Node.atom); + + // ӱ㣬ҪԱͷβֱ + } else { + if(mark == Head) { + printf("("); + } else { + printf(","); + } + + Print(L->Node.ptr.hp, Head); + Print(L->Node.ptr.tp, Tail); + } + } +} + +/* + * 㷨5.8 + * + * ǿմstrָ֣hsubΪһ','֮ǰӴstrΪһ','֮Ӵ + * + *ע + * 1.ַstrȷ޿հ׷ţstrѾȥš + * 2.ɺstrҲᷢ仯 + */ +static void sever(SString hstr, SString str) { + int i, k, n; + SString ch; + + n = StrLength(str); + + i = 0; // ַʱα + k = 0; // δ + + do { + ++i; + + // ȡstrһַ + SubString(ch, str, i, 1); + + if(ch[1] == '(') { + ++k; + } + + if(ch[1] == ')') { + --k; + } + } while(i < n && (ch[1] != ',' || k != 0)); + + // ڶ + if(i < n) { + SubString(hstr, str, 1, i - 1); + SubString(str, str, i + 1, n - i); + + // ֻһ + } else { + StrCopy(hstr, str); + ClearString(str); + } +} diff --git a/Dev-C++/ExerciseBook/05.32.1/GList-HT.h b/Dev-C++/ExerciseBook/05.32.1/GList-HT.h new file mode 100644 index 0000000..508b96f --- /dev/null +++ b/Dev-C++/ExerciseBook/05.32.1/GList-HT.h @@ -0,0 +1,164 @@ +/*============================ + * ͷβ洢ʾ + * + * 㷨: 5.55.65.75.8 + =============================*/ + +#ifndef GLIST_HT_H +#define GLIST_HT_H + +#include +#include // ṩ mallocreallocfreeexit ԭ +#include "Status.h" //**01 **// +#include "SString.h" //**04 **// + +/* ԭԪ */ +typedef char AtomType; + +/* + * + * + * Atom-0ԭӽ + * List-1 + */ +typedef enum { Atom, List } ElemTag; + +/* ͷβ洢ʾͶ */ +typedef struct GLNode { + ElemTag tag; // ǣԭӽͱ + + // ԭӽͱϲ + union { + AtomType atom; // atomԭӽֵAtomTypeû + struct { + struct GLNode* hp; // ָͷ + struct GLNode* tp; // ָβ + } ptr; // ָ + } Node; +} GLNode; + +/* */ +typedef GLNode* GList; + +/* + * ͼλ + * + * HeadָԱͷ + * TailָԱβ + */ +typedef enum { Head, Tail } Mark; + + +/* + * ʼ + * + * ʼյĹΪ0Ϊ1 + * + *ע + * Ҫÿһȥſ + */ +Status InitGList(GList* L); + +/* + * 㷨5.7 + * + * + * + * ַSL + */ +Status CreateGList(GList* L, SString S); + +/* + * + * + * ͷŹռڴ档 + */ +Status DestroyGList(GList* L); + +/* + * 㷨5.6 + * + * + * + * ɹLƵõT + */ +Status CopyGList(GList* T, GList L); + +/* + * + * + * عijȡ + */ +int GListLength(GList L); + +/* + * 㷨5.5 + * + * + * + * ع + */ +int GListDepth(GList L); + +/* + * п + * + * жϹǷΪա + */ +Status GListEmpty(GList L); + +/* + * ͷ + */ +GList GetHead(GList L); + +/* + * β + */ +GList GetTail(GList L); + +/* + * + * + * ԪeΪLĵһԪء + */ +Status InsertFirst(GList* L, GList e); + +/* + * ɾ + * + * LĵһԪɾeء + */ +Status DeleteFirst(GList* L, GList* e); + +/* + * + * + * visitʹL + */ +void Traverse(GList L, void (Visit)(AtomType)); + +/* + * ͼλ + * + * L + */ +void PrintGraph(GList L); + +/* + * ͼλڲʵ֣markͼλǡ + */ +static void Print(GList L, Mark mark); + +/* + * 㷨5.8 + * + * ǿմstrָ֣hsubΪһ','֮ǰӴstrΪһ','֮Ӵ + * + *ע + * 1.ַstrȷ޿հ׷ţstrѾȥš + * 2.ɺstrҲᷢ仯 + */ +static void sever(SString hstr, SString str); + +#endif diff --git a/Dev-C++/ExerciseBook/05.32.1/SString.cpp b/Dev-C++/ExerciseBook/05.32.1/SString.cpp new file mode 100644 index 0000000..7a96fcf --- /dev/null +++ b/Dev-C++/ExerciseBook/05.32.1/SString.cpp @@ -0,0 +1,195 @@ +/*============================= + * Ķ˳洢ʾ˳򴮣 + * + * 㷨: 4.14.24.34.5 + ==============================*/ + +#include "SString.h" //**04 **// + +/* + * ʼ + * + * һֵΪcharsĴT + * + *ע + * òСӼ + */ +Status StrAssign(SString T, const char* chars) { + int i, len; + + len = (int) strlen(chars); + + // chars + if(len > MAXSTRLEN) { + return ERROR; + } + + T[0] = len; + for(i = 1; i <= len; i++) { + T[i] = chars[i - 1]; + } + + return OK; +} + +/* + * + * + * Sա + */ +Status ClearString(SString S) { + // ֻҪΪ0Ϳ + S[0] = 0; + return OK; +} + +/* + * п + * + * жϴSǷЧݡ + * + * ֵ + * TRUE : SΪ + * FALSE: SΪ + */ +Status StrEmpty(SString S) { + return S[0] == 0 ? TRUE : FALSE; +} + +/* + * + * + * شSԪصĸ + * + *ע + * òСӼ + */ +int StrLength(SString S) { + return S[0]; +} + +/* + * 㷨4.3 + * + * Ӵ + * + * SubS[pos, pos+len-1] + * ֵָʾǷȡɹ + * + *ע + * òСӼ + */ +Status SubString(SString Sub, SString S, int pos, int len) { + int i; + + if(pos < 1 || pos > S[0] || len < 0 || pos + len - 1 > S[0]) { + return ERROR; + } + + // Ԫ + for(i = 1; i <= len; i++) { + Sub[i] = S[pos + i - 1]; + } + + // ȷ³ + Sub[0] = len; + + return OK; +} + +/* + * ɾ + * + * ɾS[pos, pos+len-1] + */ +Status StrDelete(SString S, int pos, int len) { + int i; + + if(pos < 1 || pos + len - 1 > S[0] || len < 0) { + return ERROR; + } + + // ɾijΪ0ǰ + if(len == 0) { + return OK; + } + + // ѺԪŲǰ棬ǵɾԪ + for(i = pos + len; i <= S[0]; i++) { + S[i - len] = S[i]; + } + + // ȼ + S[0] -= len; + + return OK; +} + +/* + * Ƚ + * + * ȽϴSʹTرȽϽ + * + *ע + * òСӼ + */ +int StrCompare(SString S, SString T) { + int i = 1; + + while(i <= S[0] && i <= T[0]) { + // ַͬʱȽС + if(S[i] != T[i]) { + return S[i] - T[i]; + } + + i++; + } + + return S[0] - T[0]; +} + +/* + * + * + * SƵT + */ +Status StrCopy(SString T, SString S) { + int i; + + // ͬϢһ + for(i = 0; i <= S[0]; i++) { + T[i] = S[i]; + } + + return OK; +} + +/* + * ַSеĿհףɴӡַո + * + *ע + * úڱġ + */ +Status ClearBlank(SString S) { + int i, j; + + // ǿմ + if(S[0] == 0) { + return ERROR; + } + + for(i = 1, j = 0; i <= S[0]; i++) { + // հףԹ + if(S[i] == ' ' || !isprint(S[i])) { + continue; + } + + j++; + + S[j] = S[i]; + } + + S[0] = j; + + return OK; +} diff --git a/Dev-C++/ExerciseBook/05.32.1/SString.h b/Dev-C++/ExerciseBook/05.32.1/SString.h new file mode 100644 index 0000000..0632f18 --- /dev/null +++ b/Dev-C++/ExerciseBook/05.32.1/SString.h @@ -0,0 +1,117 @@ +/*============================= + * Ķ˳洢ʾ˳򴮣 + * + * 㷨: 4.14.24.34.5 + ==============================*/ + +#ifndef SSTRING_H +#define SSTRING_H + +#include +#include // ṩ strlen ԭ +#include // ṩ isprint ԭ +#include "Status.h" //**01 **// + +/* 궨 */ +#define MAXSTRLEN 255 // ˳򴮵󴮳 + +/* + * ˳洢Ͷ + * + * עЧԪشSString1ŵԪʼ洢 + * SString0ŵԪ洢䳤 + */ +typedef unsigned char SString[MAXSTRLEN + 1]; // 0ŵԪŴij + + +/* + * ʾ + * + * ѭ̲ĵдϰߣposָʾַλ()1ʼ + */ + + +/* + * ʼ + * + * һֵΪcharsĴT + * + *ע + * òСӼ + */ +Status StrAssign(SString T, const char* chars); + +/* + * + * + * Sա + */ +Status ClearString(SString S); + +/* + * п + * + * жϴSǷЧݡ + * + * ֵ + * TRUE : SΪ + * FALSE: SΪ + */ +Status StrEmpty(SString S); + +/* + * + * + * شSԪصĸ + * + *ע + * òСӼ + */ +int StrLength(SString S); + +/* + * 㷨4.3 + * + * Ӵ + * + * SubS[pos, pos+len-1] + * ֵָʾǷȡɹ + * + *ע + * òСӼ + */ +Status SubString(SString Sub, SString S, int pos, int len); + +/* + * ɾ + * + * ɾS[pos, pos+len-1] + */ +Status StrDelete(SString S, int pos, int len); + +/* + * Ƚ + * + * ȽϴSʹTرȽϽ + * + *ע + * òСӼ + */ +int StrCompare(SString S, SString T); + +/* + * + * + * SƵT + */ +Status StrCopy(SString T, SString S); + +/* + * ַSеĿհףɴӡַո + * + *ע + * úڱġ + */ +Status ClearBlank(SString S); + +#endif diff --git a/Dev-C++/ExerciseBook/05.32.2/05.32.2.cpp b/Dev-C++/ExerciseBook/05.32.2/05.32.2.cpp new file mode 100644 index 0000000..adc2453 --- /dev/null +++ b/Dev-C++/ExerciseBook/05.32.2/05.32.2.cpp @@ -0,0 +1,66 @@ +#include +#include "Status.h" //**01 **// +#include "SString.h" //**04 **// +#include "GList-E.h" //**05 ͹**// + +/* + * жϹǷȣչ洢ʾ + */ +Status Algo_5_32_2(GList A, GList B); + + +int main(int argc, char* argv[]) { + GList A, B; + char* a = "((),(e),(a,(b,c,d)))"; + char* b = "((),(e),(a,(b,c,f)))"; + SString Sa, Sb; + + printf(" AB ...\n"); + StrAssign(Sa, a); + CreateGList(&A, Sa); + StrAssign(Sb, b); + CreateGList(&B, Sb); + printf("A = "); + PrintGraph(A); + printf("B = "); + PrintGraph(B); + + Algo_5_32_2(A, B) ? printf("ȣ\n") : printf("ȣ\n"); + + return 0; +} + + +/* + * жϹǷȣչ洢ʾ + */ +Status Algo_5_32_2(GList A, GList B) { + if(!A && !B) { + return TRUE; // ձ + } + + // Ϊ + if(A && B) { + // Ԫͬ + if(A->tag == B->tag) { + // ԭӽ + if(A->tag == Atom) { + if(A->Node.atom == B->Node.atom) { + if(Algo_5_32_2(A->tp, B->tp) == TRUE) { + return TRUE; + } + } + + // + } else { + if(Algo_5_32_2(A->Node.hp, B->Node.hp) == TRUE) { + if(Algo_5_32_2(A->tp, B->tp) == TRUE) { + return TRUE; + } + } + } + } + } + + return FALSE; +} diff --git a/Dev-C++/ExerciseBook/05.32.2/05.32.2.dev b/Dev-C++/ExerciseBook/05.32.2/05.32.2.dev new file mode 100644 index 0000000..7117946 --- /dev/null +++ b/Dev-C++/ExerciseBook/05.32.2/05.32.2.dev @@ -0,0 +1,102 @@ +[Project] +FileName=05.32.2.dev +Name=05.32.2 +Type=1 +Ver=2 +ObjFiles= +Includes= +Libs= +PrivateResource= +ResourceIncludes= +MakeIncludes= +Compiler= +CppCompiler= +Linker= +IsCpp=0 +Icon= +ExeOutput= +ObjectOutput= +LogOutput= +LogOutputEnabled=0 +OverrideOutput=0 +OverrideOutputName= +HostApplication= +UseCustomMakefile=0 +CustomMakefile= +CommandLine= +Folders= +IncludeVersionInfo=0 +SupportXPThemes=0 +CompilerSet=1 +CompilerSettings=0000000000000000001000000 +UnitCount=5 + +[VersionInfo] +Major=1 +Minor=0 +Release=0 +Build=0 +LanguageID=1033 +CharsetID=1252 +CompanyName= +FileVersion= +FileDescription=Developed using the Dev-C++ IDE +InternalName= +LegalCopyright= +LegalTrademarks= +OriginalFilename= +ProductName= +ProductVersion= +AutoIncBuildNr=0 +SyncProduct=1 + +[Unit4] +FileName=SString.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit2] +FileName=GList-E.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit1] +FileName=05.32.2.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit3] +FileName=GList-E.h +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit5] +FileName=SString.h +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + diff --git a/Dev-C++/ExerciseBook/05.32.2/GList-E.cpp b/Dev-C++/ExerciseBook/05.32.2/GList-E.cpp new file mode 100644 index 0000000..3fc0ad9 --- /dev/null +++ b/Dev-C++/ExerciseBook/05.32.2/GList-E.cpp @@ -0,0 +1,449 @@ +/*=========================== + * չ洢ʾ + ============================*/ + +#include "GList-E.h" //**05 ͹**// + +/* + * ʼ + * + * ʼյĹΪ0Ϊ1 + * + *ע + * Ҫÿһſ + */ +Status InitGList(GList* L) { + if(L == NULL) { + return ERROR; + } + + *L = (GList) malloc(sizeof(GLNode)); + if(!*L) { + exit(OVERFLOW); + } + + (*L)->tag = List; + (*L)->Node.hp = NULL; + (*L)->tp = NULL; + + return OK; +} + +/* + * + * + * ַSL + */ +Status CreateGList(GList* L, SString S) { + SString emp, hsub, sub, tmp; + + if(L == NULL) { + return ERROR; + } + + // ַSеĿհףɴӡַո + ClearBlank(S); + + if(StrEmpty(S)) { + return ERROR; + } + + // Ϊ˲ƻS + StrCopy(sub, S); + + /* + * ִеʱ + * ٴִеʱѾȥ + */ + sever(hsub, sub); + + *L = (GList) malloc(sizeof(GLNode)); + if(*L == NULL) { + exit(OVERFLOW); + } + + StrAssign(emp, "()"); + + if(!StrCompare(hsub, emp)) { + (*L)->tag = List; + (*L)->Node.hp = NULL; + } else { + if(StrLength(hsub) == 1) { + (*L)->tag = Atom; + (*L)->Node.atom = hsub[1]; + } else { + (*L)->tag = List; + + SubString(tmp, hsub, 2, StrLength(hsub) - 2); + + CreateGList(&((*L)->Node.hp), tmp); + } + } + + // ڶβ˳ݹ + if(StrEmpty(sub)) { + (*L)->tp = NULL; + } else { + // ݹβ + CreateGList(&((*L)->tp), sub); + } + + return OK; +} + +/* + * + * + * ͷŹռڴ档 + */ +Status DestroyGList(GList* L) { + GList head, tail; + + if(L == NULL || *L == NULL) { + return ERROR; + } + + // ӱ + if((*L)->tag == List) { + head = (*L)->Node.hp; // ͷ + tail = (*L)->tp; // β + + free(*L); + *L = NULL; + + // ݹ鴦ͷ + if(head != NULL) { + DestroyGList(&head); + } + + // ݹ鴦β + if(tail != NULL) { + DestroyGList(&tail); + } + + // ԭӽ + } else { + tail = (*L)->tp; // β + + free(*L); + *L = NULL; + + if(tail != NULL) { + DestroyGList(&tail); + } + } + + return OK; +} + +/* + * + * + * ɹLƵõT + */ +Status CopyGList(GList* T, GList L) { + + if(L == NULL) { + return ERROR; + } + + *T = (GList) malloc(sizeof(GLNode)); + if(*T == NULL) { + exit(OVERFLOW); + } + + // ԭ + if(L->tag == Atom) { + (*T)->tag = Atom; + (*T)->Node.atom = L->Node.atom; + + // ӱ + } else { + (*T)->tag = List; + + // Ʊͷ + if(L->Node.hp != NULL) { + CopyGList(&((*T)->Node.hp), L->Node.hp); + } else { + (*T)->Node.hp = NULL; + } + } + + // Ʊβ + if(L->tp != NULL) { + CopyGList(&((*T)->tp), L->tp); + } else { + (*T)->tp = NULL; + } + + return OK; +} + +/* + * + * + * عijȡ + */ +int GListLength(GList L) { + int count = 0; + GList p; + + // + if(L == NULL) { + return -1; + } + + p = L->Node.hp; + + while(p != NULL) { + ++count; + p = p->tp; + } + + return count; +} + +/* + * + * + * ع + */ +int GListDepth(GList L) { + int max, deep; + GList p; + + max = 0; + + // + if(L == NULL) { + return -1; + } + + // ձΪ1 + if(L->tag == List && !L->Node.hp) { + return 1; + } + + // ԭΪ0 + if(L->tag == Atom) { + return 0; + } + + // ݹӱ + for(p = L->Node.hp; p != NULL; p = p->tp) { + // pΪͷָӱ + deep = GListDepth(p); + if(deep > max) { + max = deep; + } + } + + return max + 1; +} + +/* + * п + * + * жϹǷΪա + */ +Status GListEmpty(GList L) { + // + if(L == NULL) { + return ERROR; + } + + if(L->tag == List && L->Node.hp == NULL && L->tp == NULL) { + return TRUE; + } else { + return ERROR; + } +} + +/* + * ͷ + */ +GList GetHead(GList L) { + GList p, q; + + // ڻΪձ޷ȡͷ + if(L == NULL || L->Node.hp == NULL) { + return NULL; + } + + q = L->Node.hp->tp; // ʱLıβϢ + L->Node.hp->tp = NULL; // ȥLıβ + + CopyGList(&p, L->Node.hp); // ƱͷϢαβ + + L->Node.hp->tp = q; // ָLıβϢ + + return p; +} + +/* + * β + */ +GList GetTail(GList L) { + GList p, q; + + // ڻΪձ޷ȡβ + if(L == NULL || L->Node.hp == NULL) { + return NULL; + } + + q = L->Node.hp; // ʱLıͷϢ + L->Node.hp = q->tp; // ժLıͷ + + CopyGList(&p, L); // ƱβϢαͷ + + q->tp = L->Node.hp; // ָLıͷϢ + L->Node.hp = q; + + return p; +} + +/* + * + * + * ԪeΪLĵһԪء + */ +Status InsertFirst(GList* L, GList e) { + + // + if(L == NULL || *L == NULL) { + return ERROR; + } + + if(e == NULL) { + return ERROR; + } + + e->tp = (*L)->Node.hp; + (*L)->Node.hp = e; + + return OK; +} + +/* + * ɾ + * + * LĵһԪɾeء + */ +Status DeleteFirst(GList* L, GList* e) { + GList p; + + // ڻΪձ޷ɾͷ + if(*L == NULL || (*L)->Node.hp == NULL) { + return ERROR; + } + + p = (*L)->Node.hp; + (*L)->Node.hp = p->tp; + p->tp = NULL; + + *e = p; + + return OK; +} + +/* + * + * + * visitʹL + */ +void Traverse(GList L, void(Visit)(AtomType)) { + if(L == NULL) { + return; + } + + if(L->tag == List) { + Traverse(L->Node.hp, Visit); + } else { + Visit(L->Node.atom); + } + + Traverse(L->tp, Visit); +} + +/* + * ͼλ + * + * L + */ +void PrintGraph(GList L) { + Print(L); + printf("\n"); +} + +/* + * ͼλڲʵ֡ + */ +static void Print(GList L) { + if(L == NULL) { + return; + } + + // + if(L->tag == List) { + printf("("); + + if(L->Node.hp) { + Print(L->Node.hp); + } + + if(L->tp) { + printf("),"); + Print(L->tp); + } else { + printf(")"); + } + + // ԭӽ + } else { + printf("%c", L->Node.atom); + if(L->tp) { + printf(","); + Print(L->tp); + } + } +} + +/* + * ǿմstrָ֣hsubΪһ','֮ǰӴstrΪһ','֮Ӵ + * + *ע + * 1.ַstrȷ޿հ׷ţ + * strſȥҲδȥ + * 2.ɺstrҲᷢ仯 + */ +static void sever(SString hstr, SString str) { + int i, k, n; + SString ch; + + n = StrLength(str); + + i = 0; // ַʱα + k = 0; // δ + + do { + ++i; + + // ȡstrһַ + SubString(ch, str, i, 1); + + if(ch[1] == '(') { + ++k; + } + if(ch[1] == ')') { + --k; + } + } while(i < n && (ch[1] != ',' || k != 0)); + + if(i < n) { + SubString(hstr, str, 1, i - 1); + SubString(str, str, i + 1, n - i); + } else { + StrCopy(hstr, str); + ClearString(str); + } +} diff --git a/Dev-C++/ExerciseBook/05.32.2/GList-E.h b/Dev-C++/ExerciseBook/05.32.2/GList-E.h new file mode 100644 index 0000000..fa9af82 --- /dev/null +++ b/Dev-C++/ExerciseBook/05.32.2/GList-E.h @@ -0,0 +1,146 @@ +/*=========================== + * չ洢ʾ + ============================*/ + +#ifndef GLIST_E_H +#define GLIST_E_H + +#include +#include // ṩ mallocreallocfreeexit ԭ +#include "Status.h" //**01 **// +#include "SString.h" //**04 **// + +/* ԭԪ */ +typedef char AtomType; //ԭ + +/* + * + * + * Atom-0ԭӽ + * List-1 + */ +typedef enum { Atom, List } ElemTag; + +/* չ洢ʾͶ */ +typedef struct GLNode { + ElemTag tag; // ǣԭӽͱ + + // ԭӽͱϲ + union + { + AtomType atom; // atomԭӽֵAtomTypeû + struct GLNode* hp; // ָͷ + } Node; + struct GLNode* tp; // ָβ +} GLNode; + +/* */ +typedef GLNode* GList; + + +/* + * ʼ + * + * ʼյĹΪ0Ϊ1 + * + *ע + * Ҫÿһſ + */ +Status InitGList(GList* L); + +/* + * + * + * ַSL + */ +Status CreateGList(GList* L, SString S); + +/* + * + * + * ͷŹռڴ档 + */ +Status DestroyGList(GList* L); + +/* + * + * + * ɹLƵõT + */ +Status CopyGList(GList* T, GList L); + +/* + * + * + * عijȡ + */ +int GListLength(GList L); + +/* + * + * + * ع + */ +int GListDepth(GList L); + +/* + * п + * + * жϹǷΪա + */ +Status GListEmpty(GList L); + +/* + * ͷ + */ +GList GetHead(GList L); + +/* + * β + */ +GList GetTail(GList L); + +/* + * + * + * ԪeΪLĵһԪء + */ +Status InsertFirst(GList* L, GList e); + +/* + * ɾ + * + * LĵһԪɾeء + */ +Status DeleteFirst(GList* L, GList* e); + +/* + * + * + * visitʹL + */ +void Traverse(GList L, void(Visit)(AtomType)); + +/* + * ͼλ + * + * L + */ +void PrintGraph(GList L); + +/* + * ͼλڲʵ֡ + */ +static void Print(GList L); + +/* + * ǿմstrָ֣hsubΪһ','֮ǰӴstrΪһ','֮Ӵ + * + *ע + * 1.ַstrȷ޿հ׷ţ + * strſȥҲδȥ + * 2.ɺstrҲᷢ仯 + */ +static void sever(SString hstr, SString str); + +#endif diff --git a/Dev-C++/ExerciseBook/05.32.2/SString.cpp b/Dev-C++/ExerciseBook/05.32.2/SString.cpp new file mode 100644 index 0000000..7a96fcf --- /dev/null +++ b/Dev-C++/ExerciseBook/05.32.2/SString.cpp @@ -0,0 +1,195 @@ +/*============================= + * Ķ˳洢ʾ˳򴮣 + * + * 㷨: 4.14.24.34.5 + ==============================*/ + +#include "SString.h" //**04 **// + +/* + * ʼ + * + * һֵΪcharsĴT + * + *ע + * òСӼ + */ +Status StrAssign(SString T, const char* chars) { + int i, len; + + len = (int) strlen(chars); + + // chars + if(len > MAXSTRLEN) { + return ERROR; + } + + T[0] = len; + for(i = 1; i <= len; i++) { + T[i] = chars[i - 1]; + } + + return OK; +} + +/* + * + * + * Sա + */ +Status ClearString(SString S) { + // ֻҪΪ0Ϳ + S[0] = 0; + return OK; +} + +/* + * п + * + * жϴSǷЧݡ + * + * ֵ + * TRUE : SΪ + * FALSE: SΪ + */ +Status StrEmpty(SString S) { + return S[0] == 0 ? TRUE : FALSE; +} + +/* + * + * + * شSԪصĸ + * + *ע + * òСӼ + */ +int StrLength(SString S) { + return S[0]; +} + +/* + * 㷨4.3 + * + * Ӵ + * + * SubS[pos, pos+len-1] + * ֵָʾǷȡɹ + * + *ע + * òСӼ + */ +Status SubString(SString Sub, SString S, int pos, int len) { + int i; + + if(pos < 1 || pos > S[0] || len < 0 || pos + len - 1 > S[0]) { + return ERROR; + } + + // Ԫ + for(i = 1; i <= len; i++) { + Sub[i] = S[pos + i - 1]; + } + + // ȷ³ + Sub[0] = len; + + return OK; +} + +/* + * ɾ + * + * ɾS[pos, pos+len-1] + */ +Status StrDelete(SString S, int pos, int len) { + int i; + + if(pos < 1 || pos + len - 1 > S[0] || len < 0) { + return ERROR; + } + + // ɾijΪ0ǰ + if(len == 0) { + return OK; + } + + // ѺԪŲǰ棬ǵɾԪ + for(i = pos + len; i <= S[0]; i++) { + S[i - len] = S[i]; + } + + // ȼ + S[0] -= len; + + return OK; +} + +/* + * Ƚ + * + * ȽϴSʹTرȽϽ + * + *ע + * òСӼ + */ +int StrCompare(SString S, SString T) { + int i = 1; + + while(i <= S[0] && i <= T[0]) { + // ַͬʱȽС + if(S[i] != T[i]) { + return S[i] - T[i]; + } + + i++; + } + + return S[0] - T[0]; +} + +/* + * + * + * SƵT + */ +Status StrCopy(SString T, SString S) { + int i; + + // ͬϢһ + for(i = 0; i <= S[0]; i++) { + T[i] = S[i]; + } + + return OK; +} + +/* + * ַSеĿհףɴӡַո + * + *ע + * úڱġ + */ +Status ClearBlank(SString S) { + int i, j; + + // ǿմ + if(S[0] == 0) { + return ERROR; + } + + for(i = 1, j = 0; i <= S[0]; i++) { + // հףԹ + if(S[i] == ' ' || !isprint(S[i])) { + continue; + } + + j++; + + S[j] = S[i]; + } + + S[0] = j; + + return OK; +} diff --git a/Dev-C++/ExerciseBook/05.32.2/SString.h b/Dev-C++/ExerciseBook/05.32.2/SString.h new file mode 100644 index 0000000..0632f18 --- /dev/null +++ b/Dev-C++/ExerciseBook/05.32.2/SString.h @@ -0,0 +1,117 @@ +/*============================= + * Ķ˳洢ʾ˳򴮣 + * + * 㷨: 4.14.24.34.5 + ==============================*/ + +#ifndef SSTRING_H +#define SSTRING_H + +#include +#include // ṩ strlen ԭ +#include // ṩ isprint ԭ +#include "Status.h" //**01 **// + +/* 궨 */ +#define MAXSTRLEN 255 // ˳򴮵󴮳 + +/* + * ˳洢Ͷ + * + * עЧԪشSString1ŵԪʼ洢 + * SString0ŵԪ洢䳤 + */ +typedef unsigned char SString[MAXSTRLEN + 1]; // 0ŵԪŴij + + +/* + * ʾ + * + * ѭ̲ĵдϰߣposָʾַλ()1ʼ + */ + + +/* + * ʼ + * + * һֵΪcharsĴT + * + *ע + * òСӼ + */ +Status StrAssign(SString T, const char* chars); + +/* + * + * + * Sա + */ +Status ClearString(SString S); + +/* + * п + * + * жϴSǷЧݡ + * + * ֵ + * TRUE : SΪ + * FALSE: SΪ + */ +Status StrEmpty(SString S); + +/* + * + * + * شSԪصĸ + * + *ע + * òСӼ + */ +int StrLength(SString S); + +/* + * 㷨4.3 + * + * Ӵ + * + * SubS[pos, pos+len-1] + * ֵָʾǷȡɹ + * + *ע + * òСӼ + */ +Status SubString(SString Sub, SString S, int pos, int len); + +/* + * ɾ + * + * ɾS[pos, pos+len-1] + */ +Status StrDelete(SString S, int pos, int len); + +/* + * Ƚ + * + * ȽϴSʹTرȽϽ + * + *ע + * òСӼ + */ +int StrCompare(SString S, SString T); + +/* + * + * + * SƵT + */ +Status StrCopy(SString T, SString S); + +/* + * ַSеĿհףɴӡַո + * + *ע + * úڱġ + */ +Status ClearBlank(SString S); + +#endif diff --git a/Dev-C++/ExerciseBook/05.33.1/05.33.1.cpp b/Dev-C++/ExerciseBook/05.33.1/05.33.1.cpp new file mode 100644 index 0000000..0ee6f53 --- /dev/null +++ b/Dev-C++/ExerciseBook/05.33.1/05.33.1.cpp @@ -0,0 +1,47 @@ +#include +#include "SString.h" //**04 **// +#include "GList-HT.h" //**05 ͹**// + +/* + * ԭڲΣͷβ洢ʾ + */ +void Algo_5_33_1(GList L, int d); + + +int main(int argc, char* argv[]) { + GList L; + char* s = "((),(e),(a,(b,c,d)))"; + SString S; + + printf(" L ...\n"); + StrAssign(S, s); + CreateGList(&L, S); + printf("L = "); + PrintGraph(L); + + Algo_5_33_1(L, 0); + + return 0; +} + + +/* + * ԭڲΣͷβ洢ʾ + */ +void Algo_5_33_1(GList L, int d) { + int i = d; // dijֵֵΪ0 + + if(L == NULL) { + return; + } + + if(L->tag == Atom) { + printf("%c -> %d\n", L->Node.atom, i); + } + + // ͷָָĻһ + if(L->tag == List) { + Algo_5_33_1(L->Node.ptr.hp, i + 1); + Algo_5_33_1(L->Node.ptr.tp, i); + } +} diff --git a/Dev-C++/ExerciseBook/05.33.1/05.33.1.dev b/Dev-C++/ExerciseBook/05.33.1/05.33.1.dev new file mode 100644 index 0000000..b1c9505 --- /dev/null +++ b/Dev-C++/ExerciseBook/05.33.1/05.33.1.dev @@ -0,0 +1,102 @@ +[Project] +FileName=05.33.1.dev +Name=05.33.1 +Type=1 +Ver=2 +ObjFiles= +Includes= +Libs= +PrivateResource= +ResourceIncludes= +MakeIncludes= +Compiler= +CppCompiler= +Linker= +IsCpp=0 +Icon= +ExeOutput= +ObjectOutput= +LogOutput= +LogOutputEnabled=0 +OverrideOutput=0 +OverrideOutputName= +HostApplication= +UseCustomMakefile=0 +CustomMakefile= +CommandLine= +Folders= +IncludeVersionInfo=0 +SupportXPThemes=0 +CompilerSet=1 +CompilerSettings=0000000000000000001000000 +UnitCount=5 + +[VersionInfo] +Major=1 +Minor=0 +Release=0 +Build=0 +LanguageID=1033 +CharsetID=1252 +CompanyName= +FileVersion= +FileDescription=Developed using the Dev-C++ IDE +InternalName= +LegalCopyright= +LegalTrademarks= +OriginalFilename= +ProductName= +ProductVersion= +AutoIncBuildNr=0 +SyncProduct=1 + +[Unit4] +FileName=SString.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit2] +FileName=GList-HT.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit1] +FileName=05.33.1.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit3] +FileName=GList-HT.h +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit5] +FileName=SString.h +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + diff --git a/Dev-C++/ExerciseBook/05.33.1/GList-HT.cpp b/Dev-C++/ExerciseBook/05.33.1/GList-HT.cpp new file mode 100644 index 0000000..bad30df --- /dev/null +++ b/Dev-C++/ExerciseBook/05.33.1/GList-HT.cpp @@ -0,0 +1,418 @@ +/*============================ + * ͷβ洢ʾ + * + * 㷨: 5.55.65.75.8 + =============================*/ + +#include "GList-HT.h" //**05 ͹**// + +/* + * ʼ + * + * ʼյĹΪ0Ϊ1 + * + *ע + * Ҫÿһȥſ + */ +Status InitGList(GList* L) { + if(L == NULL) { + return ERROR; + } + + *L = NULL; + + return OK; +} + +/* + * 㷨5.7 + * + * + * + * ַSL + */ +Status CreateGList(GList* L, SString S) { + SString emp; // չַ + SString hsub, sub; + GList p, q; + + if(L == NULL) { + return ERROR; + } + + // ַSеĿհףɴӡַո + ClearBlank(S); + + if(StrEmpty(S)) { + return ERROR; + } + + StrAssign(emp, "()"); + + /* + * 봮Ϊ()ҪյĹ + * + *ע + * ̲Ĵġ + * StrCompareķֵָʾַĴСָʾַǷȡ + * S()ȣֵӦ0 + */ + if(!StrCompare(S, emp)) { + *L = NULL; + } else { + *L = (GList) malloc(sizeof(GLNode)); + if(*L == NULL) { + exit(OVERFLOW); + } + + // ԭ + if(StrLength(S) == 1) { + (*L)->tag = Atom; + (*L)->Node.atom = S[1]; + } else { + (*L)->tag = List; + + p = *L; + + // ȥ + SubString(sub, S, 2, StrLength(S) - 2); + + // ظnӱ + do { + // subзͷhsubɺsubҲᷢ仯 + sever(hsub, sub); + + // ݹ鴴 + CreateGList(&(p->Node.ptr.hp), hsub); + + q = p; + + // βΪգҪβ + if(!StrEmpty(sub)) { + p = (GList) malloc(sizeof(GLNode)); + if(p == NULL) { + exit(OVERFLOW); + } + + p->tag = List; + + q->Node.ptr.tp = p; + } + } while(!StrEmpty(sub)); + + q->Node.ptr.tp = NULL; + } + } + + return OK; +} + +/* + * + * + * ͷŹռڴ档 + */ +Status DestroyGList(GList* L) { + GList head, tail; + + if(L == NULL || *L == NULL) { + return ERROR; + } + + // ɾԭӽ + if((*L)->tag == Atom) { + free(*L); + *L = NULL; + + // ɾӱ + } else { + head = (*L)->Node.ptr.hp; + tail = (*L)->Node.ptr.tp; + free(*L); + *L = NULL; + DestroyGList(&head); + DestroyGList(&tail); + } + + return OK; +} + +/* + * 㷨5.6 + * + * + * + * ɹLƵõT + */ +Status CopyGList(GList* T, GList L) { + if(T == NULL) { + return ERROR; + } + + if(L == NULL) { + *T = NULL; + } else { + // ½ + *T = (GList) malloc(sizeof(GLNode)); + if(*T == NULL) { + exit(OVERFLOW); + } + + (*T)->tag = L->tag; + + // Ƶԭ + if(L->tag == Atom) { + (*T)->Node.atom = L->Node.atom; + + // Ʊͷͱβ + } else { + CopyGList(&((*T)->Node.ptr.hp), L->Node.ptr.hp); + CopyGList(&((*T)->Node.ptr.tp), L->Node.ptr.tp); + } + } + + return OK; +} + +/* + * + * + * عijȡ + */ +int GListLength(GList L) { + int count; + + for(count = 0; L != NULL; count++, L = L->Node.ptr.tp) { + } + + return count; +} + +/* + * 㷨5.5 + * + * + * + * ع + */ +int GListDepth(GList L) { + int max, deep; + GList p; + + // ձΪ1 + if(L == NULL) { + return 1; + } + + // ԭΪ0 + if(L->tag == Atom) { + return 0; + } + + // ݹӱ + for(max = 0, p = L; p != NULL; p = p->Node.ptr.tp) { + deep = GListDepth(p->Node.ptr.hp); + if(deep > max) { + max = deep; + } + } + + // ǿձǸԪȼһ + return max + 1; +} + +/* + * п + * + * жϹǷΪա + */ +Status GListEmpty(GList L) { + return L == NULL ? TRUE : FALSE; +} + +/* + * ͷ + */ +GList GetHead(GList L) { + GList p; + + // ձޱͷﲻܷNULLȻֲʧ˻Ƿ˿ձ + if(L == NULL) { + exit(ERROR); + } + + CopyGList(&p, L->Node.ptr.hp); + + return p; +} + +/* + * β + */ +GList GetTail(GList L) { + GList p; + + // ձޱβﲻܷNULLȻֲʧ˻Ƿ˿ձ + if(L == NULL) { + exit(ERROR); + } + + CopyGList(&p, L->Node.ptr.tp); + + return p; +} + +/* + * + * + * ԪeΪLĵһԪء + */ +Status InsertFirst(GList* L, GList e) { + GList g; + + if(L == NULL) { + return ERROR; + } + + g = (GList) malloc(sizeof(GLNode)); + if(g == NULL) { + exit(OVERFLOW); + } + + g->tag = List; + g->Node.ptr.hp = e; + g->Node.ptr.tp = *L; + *L = g; + + return OK; +} + +/* + * ɾ + * + * LĵһԪɾeء + */ +Status DeleteFirst(GList* L, GList* e) { + GList p; + + // ձ޷ɾ + if(L == NULL || *L == NULL) { + return ERROR; + } + + p = *L; + *L = (*L)->Node.ptr.tp; + + CopyGList(e, p->Node.ptr.hp); + + free(p); + + return OK; +} + +/* + * + * + * visitʹL + */ +void Traverse(GList L, void(Visit)(AtomType)) { + + if(L == NULL) { + return; + } + + if(L->tag == Atom) { + Visit(L->Node.atom); + } else { + Traverse(L->Node.ptr.hp, Visit); + Traverse(L->Node.ptr.tp, Visit); + } + +} + +/* + * ͼλ + * + * L + */ +void PrintGraph(GList L) { + Print(L, Head); + printf("\n"); +} + +/* + * ͼλڲʵ֣markͼλǡ + */ +static void Print(GList L, Mark mark) { + // LΪ + if(L == NULL) { + if(mark == Head) { + printf("("); + } + + printf(")"); + + // LΪʱ + } else { + // ԭӽ㣬ԭ + if(L->tag == Atom) { + printf("%c", L->Node.atom); + + // ӱ㣬ҪԱͷβֱ + } else { + if(mark == Head) { + printf("("); + } else { + printf(","); + } + + Print(L->Node.ptr.hp, Head); + Print(L->Node.ptr.tp, Tail); + } + } +} + +/* + * 㷨5.8 + * + * ǿմstrָ֣hsubΪһ','֮ǰӴstrΪһ','֮Ӵ + * + *ע + * 1.ַstrȷ޿հ׷ţstrѾȥš + * 2.ɺstrҲᷢ仯 + */ +static void sever(SString hstr, SString str) { + int i, k, n; + SString ch; + + n = StrLength(str); + + i = 0; // ַʱα + k = 0; // δ + + do { + ++i; + + // ȡstrһַ + SubString(ch, str, i, 1); + + if(ch[1] == '(') { + ++k; + } + + if(ch[1] == ')') { + --k; + } + } while(i < n && (ch[1] != ',' || k != 0)); + + // ڶ + if(i < n) { + SubString(hstr, str, 1, i - 1); + SubString(str, str, i + 1, n - i); + + // ֻһ + } else { + StrCopy(hstr, str); + ClearString(str); + } +} diff --git a/Dev-C++/ExerciseBook/05.33.1/GList-HT.h b/Dev-C++/ExerciseBook/05.33.1/GList-HT.h new file mode 100644 index 0000000..508b96f --- /dev/null +++ b/Dev-C++/ExerciseBook/05.33.1/GList-HT.h @@ -0,0 +1,164 @@ +/*============================ + * ͷβ洢ʾ + * + * 㷨: 5.55.65.75.8 + =============================*/ + +#ifndef GLIST_HT_H +#define GLIST_HT_H + +#include +#include // ṩ mallocreallocfreeexit ԭ +#include "Status.h" //**01 **// +#include "SString.h" //**04 **// + +/* ԭԪ */ +typedef char AtomType; + +/* + * + * + * Atom-0ԭӽ + * List-1 + */ +typedef enum { Atom, List } ElemTag; + +/* ͷβ洢ʾͶ */ +typedef struct GLNode { + ElemTag tag; // ǣԭӽͱ + + // ԭӽͱϲ + union { + AtomType atom; // atomԭӽֵAtomTypeû + struct { + struct GLNode* hp; // ָͷ + struct GLNode* tp; // ָβ + } ptr; // ָ + } Node; +} GLNode; + +/* */ +typedef GLNode* GList; + +/* + * ͼλ + * + * HeadָԱͷ + * TailָԱβ + */ +typedef enum { Head, Tail } Mark; + + +/* + * ʼ + * + * ʼյĹΪ0Ϊ1 + * + *ע + * Ҫÿһȥſ + */ +Status InitGList(GList* L); + +/* + * 㷨5.7 + * + * + * + * ַSL + */ +Status CreateGList(GList* L, SString S); + +/* + * + * + * ͷŹռڴ档 + */ +Status DestroyGList(GList* L); + +/* + * 㷨5.6 + * + * + * + * ɹLƵõT + */ +Status CopyGList(GList* T, GList L); + +/* + * + * + * عijȡ + */ +int GListLength(GList L); + +/* + * 㷨5.5 + * + * + * + * ع + */ +int GListDepth(GList L); + +/* + * п + * + * жϹǷΪա + */ +Status GListEmpty(GList L); + +/* + * ͷ + */ +GList GetHead(GList L); + +/* + * β + */ +GList GetTail(GList L); + +/* + * + * + * ԪeΪLĵһԪء + */ +Status InsertFirst(GList* L, GList e); + +/* + * ɾ + * + * LĵһԪɾeء + */ +Status DeleteFirst(GList* L, GList* e); + +/* + * + * + * visitʹL + */ +void Traverse(GList L, void (Visit)(AtomType)); + +/* + * ͼλ + * + * L + */ +void PrintGraph(GList L); + +/* + * ͼλڲʵ֣markͼλǡ + */ +static void Print(GList L, Mark mark); + +/* + * 㷨5.8 + * + * ǿմstrָ֣hsubΪһ','֮ǰӴstrΪһ','֮Ӵ + * + *ע + * 1.ַstrȷ޿հ׷ţstrѾȥš + * 2.ɺstrҲᷢ仯 + */ +static void sever(SString hstr, SString str); + +#endif diff --git a/Dev-C++/ExerciseBook/05.33.1/SString.cpp b/Dev-C++/ExerciseBook/05.33.1/SString.cpp new file mode 100644 index 0000000..7a96fcf --- /dev/null +++ b/Dev-C++/ExerciseBook/05.33.1/SString.cpp @@ -0,0 +1,195 @@ +/*============================= + * Ķ˳洢ʾ˳򴮣 + * + * 㷨: 4.14.24.34.5 + ==============================*/ + +#include "SString.h" //**04 **// + +/* + * ʼ + * + * һֵΪcharsĴT + * + *ע + * òСӼ + */ +Status StrAssign(SString T, const char* chars) { + int i, len; + + len = (int) strlen(chars); + + // chars + if(len > MAXSTRLEN) { + return ERROR; + } + + T[0] = len; + for(i = 1; i <= len; i++) { + T[i] = chars[i - 1]; + } + + return OK; +} + +/* + * + * + * Sա + */ +Status ClearString(SString S) { + // ֻҪΪ0Ϳ + S[0] = 0; + return OK; +} + +/* + * п + * + * жϴSǷЧݡ + * + * ֵ + * TRUE : SΪ + * FALSE: SΪ + */ +Status StrEmpty(SString S) { + return S[0] == 0 ? TRUE : FALSE; +} + +/* + * + * + * شSԪصĸ + * + *ע + * òСӼ + */ +int StrLength(SString S) { + return S[0]; +} + +/* + * 㷨4.3 + * + * Ӵ + * + * SubS[pos, pos+len-1] + * ֵָʾǷȡɹ + * + *ע + * òСӼ + */ +Status SubString(SString Sub, SString S, int pos, int len) { + int i; + + if(pos < 1 || pos > S[0] || len < 0 || pos + len - 1 > S[0]) { + return ERROR; + } + + // Ԫ + for(i = 1; i <= len; i++) { + Sub[i] = S[pos + i - 1]; + } + + // ȷ³ + Sub[0] = len; + + return OK; +} + +/* + * ɾ + * + * ɾS[pos, pos+len-1] + */ +Status StrDelete(SString S, int pos, int len) { + int i; + + if(pos < 1 || pos + len - 1 > S[0] || len < 0) { + return ERROR; + } + + // ɾijΪ0ǰ + if(len == 0) { + return OK; + } + + // ѺԪŲǰ棬ǵɾԪ + for(i = pos + len; i <= S[0]; i++) { + S[i - len] = S[i]; + } + + // ȼ + S[0] -= len; + + return OK; +} + +/* + * Ƚ + * + * ȽϴSʹTرȽϽ + * + *ע + * òСӼ + */ +int StrCompare(SString S, SString T) { + int i = 1; + + while(i <= S[0] && i <= T[0]) { + // ַͬʱȽС + if(S[i] != T[i]) { + return S[i] - T[i]; + } + + i++; + } + + return S[0] - T[0]; +} + +/* + * + * + * SƵT + */ +Status StrCopy(SString T, SString S) { + int i; + + // ͬϢһ + for(i = 0; i <= S[0]; i++) { + T[i] = S[i]; + } + + return OK; +} + +/* + * ַSеĿհףɴӡַո + * + *ע + * úڱġ + */ +Status ClearBlank(SString S) { + int i, j; + + // ǿմ + if(S[0] == 0) { + return ERROR; + } + + for(i = 1, j = 0; i <= S[0]; i++) { + // հףԹ + if(S[i] == ' ' || !isprint(S[i])) { + continue; + } + + j++; + + S[j] = S[i]; + } + + S[0] = j; + + return OK; +} diff --git a/Dev-C++/ExerciseBook/05.33.1/SString.h b/Dev-C++/ExerciseBook/05.33.1/SString.h new file mode 100644 index 0000000..0632f18 --- /dev/null +++ b/Dev-C++/ExerciseBook/05.33.1/SString.h @@ -0,0 +1,117 @@ +/*============================= + * Ķ˳洢ʾ˳򴮣 + * + * 㷨: 4.14.24.34.5 + ==============================*/ + +#ifndef SSTRING_H +#define SSTRING_H + +#include +#include // ṩ strlen ԭ +#include // ṩ isprint ԭ +#include "Status.h" //**01 **// + +/* 궨 */ +#define MAXSTRLEN 255 // ˳򴮵󴮳 + +/* + * ˳洢Ͷ + * + * עЧԪشSString1ŵԪʼ洢 + * SString0ŵԪ洢䳤 + */ +typedef unsigned char SString[MAXSTRLEN + 1]; // 0ŵԪŴij + + +/* + * ʾ + * + * ѭ̲ĵдϰߣposָʾַλ()1ʼ + */ + + +/* + * ʼ + * + * һֵΪcharsĴT + * + *ע + * òСӼ + */ +Status StrAssign(SString T, const char* chars); + +/* + * + * + * Sա + */ +Status ClearString(SString S); + +/* + * п + * + * жϴSǷЧݡ + * + * ֵ + * TRUE : SΪ + * FALSE: SΪ + */ +Status StrEmpty(SString S); + +/* + * + * + * شSԪصĸ + * + *ע + * òСӼ + */ +int StrLength(SString S); + +/* + * 㷨4.3 + * + * Ӵ + * + * SubS[pos, pos+len-1] + * ֵָʾǷȡɹ + * + *ע + * òСӼ + */ +Status SubString(SString Sub, SString S, int pos, int len); + +/* + * ɾ + * + * ɾS[pos, pos+len-1] + */ +Status StrDelete(SString S, int pos, int len); + +/* + * Ƚ + * + * ȽϴSʹTرȽϽ + * + *ע + * òСӼ + */ +int StrCompare(SString S, SString T); + +/* + * + * + * SƵT + */ +Status StrCopy(SString T, SString S); + +/* + * ַSеĿհףɴӡַո + * + *ע + * úڱġ + */ +Status ClearBlank(SString S); + +#endif diff --git a/Dev-C++/ExerciseBook/05.33.2/05.33.2.cpp b/Dev-C++/ExerciseBook/05.33.2/05.33.2.cpp new file mode 100644 index 0000000..11aa567 --- /dev/null +++ b/Dev-C++/ExerciseBook/05.33.2/05.33.2.cpp @@ -0,0 +1,48 @@ +#include +#include "SString.h" //**04 **// +#include "GList-E.h" //**05 ͹**// + +/* + * ԭڲΣչ洢ʾ + */ +void Algo_5_33_2(GList L, int d); + + +int main(int argc, char* argv[]) { + GList L; + char* s = "((),(e),(a,(b,c,d)))"; + SString S; + + printf(" L ...\n"); + StrAssign(S, s); + CreateGList(&L, S); + printf("L = "); + PrintGraph(L); + + Algo_5_33_2(L, 0); + + return 0; +} + + +/* + * ԭڲΣչ洢ʾ + */ +void Algo_5_33_2(GList L, int d) { + int i = d; // dֵΪ0 + + if(L == NULL) { + return; + } + + if(L->tag == Atom) { + printf("%c -> %d\n", L->Node.atom, i); + } + + + if(L->tag == List) { + Algo_5_33_2(L->Node.hp, i + 1); // ͷָָĻһ + } + + Algo_5_33_2(L->tp, i); +} diff --git a/Dev-C++/ExerciseBook/05.33.2/05.33.2.dev b/Dev-C++/ExerciseBook/05.33.2/05.33.2.dev new file mode 100644 index 0000000..d81b8a2 --- /dev/null +++ b/Dev-C++/ExerciseBook/05.33.2/05.33.2.dev @@ -0,0 +1,102 @@ +[Project] +FileName=05.33.2.dev +Name=05.33.2 +Type=1 +Ver=2 +ObjFiles= +Includes= +Libs= +PrivateResource= +ResourceIncludes= +MakeIncludes= +Compiler= +CppCompiler= +Linker= +IsCpp=0 +Icon= +ExeOutput= +ObjectOutput= +LogOutput= +LogOutputEnabled=0 +OverrideOutput=0 +OverrideOutputName= +HostApplication= +UseCustomMakefile=0 +CustomMakefile= +CommandLine= +Folders= +IncludeVersionInfo=0 +SupportXPThemes=0 +CompilerSet=1 +CompilerSettings=0000000000000000001000000 +UnitCount=5 + +[VersionInfo] +Major=1 +Minor=0 +Release=0 +Build=0 +LanguageID=1033 +CharsetID=1252 +CompanyName= +FileVersion= +FileDescription=Developed using the Dev-C++ IDE +InternalName= +LegalCopyright= +LegalTrademarks= +OriginalFilename= +ProductName= +ProductVersion= +AutoIncBuildNr=0 +SyncProduct=1 + +[Unit4] +FileName=SString.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit2] +FileName=GList-E.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit1] +FileName=05.33.2.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit3] +FileName=GList-E.h +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit5] +FileName=SString.h +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + diff --git a/Dev-C++/ExerciseBook/05.33.2/GList-E.cpp b/Dev-C++/ExerciseBook/05.33.2/GList-E.cpp new file mode 100644 index 0000000..3fc0ad9 --- /dev/null +++ b/Dev-C++/ExerciseBook/05.33.2/GList-E.cpp @@ -0,0 +1,449 @@ +/*=========================== + * չ洢ʾ + ============================*/ + +#include "GList-E.h" //**05 ͹**// + +/* + * ʼ + * + * ʼյĹΪ0Ϊ1 + * + *ע + * Ҫÿһſ + */ +Status InitGList(GList* L) { + if(L == NULL) { + return ERROR; + } + + *L = (GList) malloc(sizeof(GLNode)); + if(!*L) { + exit(OVERFLOW); + } + + (*L)->tag = List; + (*L)->Node.hp = NULL; + (*L)->tp = NULL; + + return OK; +} + +/* + * + * + * ַSL + */ +Status CreateGList(GList* L, SString S) { + SString emp, hsub, sub, tmp; + + if(L == NULL) { + return ERROR; + } + + // ַSеĿհףɴӡַո + ClearBlank(S); + + if(StrEmpty(S)) { + return ERROR; + } + + // Ϊ˲ƻS + StrCopy(sub, S); + + /* + * ִеʱ + * ٴִеʱѾȥ + */ + sever(hsub, sub); + + *L = (GList) malloc(sizeof(GLNode)); + if(*L == NULL) { + exit(OVERFLOW); + } + + StrAssign(emp, "()"); + + if(!StrCompare(hsub, emp)) { + (*L)->tag = List; + (*L)->Node.hp = NULL; + } else { + if(StrLength(hsub) == 1) { + (*L)->tag = Atom; + (*L)->Node.atom = hsub[1]; + } else { + (*L)->tag = List; + + SubString(tmp, hsub, 2, StrLength(hsub) - 2); + + CreateGList(&((*L)->Node.hp), tmp); + } + } + + // ڶβ˳ݹ + if(StrEmpty(sub)) { + (*L)->tp = NULL; + } else { + // ݹβ + CreateGList(&((*L)->tp), sub); + } + + return OK; +} + +/* + * + * + * ͷŹռڴ档 + */ +Status DestroyGList(GList* L) { + GList head, tail; + + if(L == NULL || *L == NULL) { + return ERROR; + } + + // ӱ + if((*L)->tag == List) { + head = (*L)->Node.hp; // ͷ + tail = (*L)->tp; // β + + free(*L); + *L = NULL; + + // ݹ鴦ͷ + if(head != NULL) { + DestroyGList(&head); + } + + // ݹ鴦β + if(tail != NULL) { + DestroyGList(&tail); + } + + // ԭӽ + } else { + tail = (*L)->tp; // β + + free(*L); + *L = NULL; + + if(tail != NULL) { + DestroyGList(&tail); + } + } + + return OK; +} + +/* + * + * + * ɹLƵõT + */ +Status CopyGList(GList* T, GList L) { + + if(L == NULL) { + return ERROR; + } + + *T = (GList) malloc(sizeof(GLNode)); + if(*T == NULL) { + exit(OVERFLOW); + } + + // ԭ + if(L->tag == Atom) { + (*T)->tag = Atom; + (*T)->Node.atom = L->Node.atom; + + // ӱ + } else { + (*T)->tag = List; + + // Ʊͷ + if(L->Node.hp != NULL) { + CopyGList(&((*T)->Node.hp), L->Node.hp); + } else { + (*T)->Node.hp = NULL; + } + } + + // Ʊβ + if(L->tp != NULL) { + CopyGList(&((*T)->tp), L->tp); + } else { + (*T)->tp = NULL; + } + + return OK; +} + +/* + * + * + * عijȡ + */ +int GListLength(GList L) { + int count = 0; + GList p; + + // + if(L == NULL) { + return -1; + } + + p = L->Node.hp; + + while(p != NULL) { + ++count; + p = p->tp; + } + + return count; +} + +/* + * + * + * ع + */ +int GListDepth(GList L) { + int max, deep; + GList p; + + max = 0; + + // + if(L == NULL) { + return -1; + } + + // ձΪ1 + if(L->tag == List && !L->Node.hp) { + return 1; + } + + // ԭΪ0 + if(L->tag == Atom) { + return 0; + } + + // ݹӱ + for(p = L->Node.hp; p != NULL; p = p->tp) { + // pΪͷָӱ + deep = GListDepth(p); + if(deep > max) { + max = deep; + } + } + + return max + 1; +} + +/* + * п + * + * жϹǷΪա + */ +Status GListEmpty(GList L) { + // + if(L == NULL) { + return ERROR; + } + + if(L->tag == List && L->Node.hp == NULL && L->tp == NULL) { + return TRUE; + } else { + return ERROR; + } +} + +/* + * ͷ + */ +GList GetHead(GList L) { + GList p, q; + + // ڻΪձ޷ȡͷ + if(L == NULL || L->Node.hp == NULL) { + return NULL; + } + + q = L->Node.hp->tp; // ʱLıβϢ + L->Node.hp->tp = NULL; // ȥLıβ + + CopyGList(&p, L->Node.hp); // ƱͷϢαβ + + L->Node.hp->tp = q; // ָLıβϢ + + return p; +} + +/* + * β + */ +GList GetTail(GList L) { + GList p, q; + + // ڻΪձ޷ȡβ + if(L == NULL || L->Node.hp == NULL) { + return NULL; + } + + q = L->Node.hp; // ʱLıͷϢ + L->Node.hp = q->tp; // ժLıͷ + + CopyGList(&p, L); // ƱβϢαͷ + + q->tp = L->Node.hp; // ָLıͷϢ + L->Node.hp = q; + + return p; +} + +/* + * + * + * ԪeΪLĵһԪء + */ +Status InsertFirst(GList* L, GList e) { + + // + if(L == NULL || *L == NULL) { + return ERROR; + } + + if(e == NULL) { + return ERROR; + } + + e->tp = (*L)->Node.hp; + (*L)->Node.hp = e; + + return OK; +} + +/* + * ɾ + * + * LĵһԪɾeء + */ +Status DeleteFirst(GList* L, GList* e) { + GList p; + + // ڻΪձ޷ɾͷ + if(*L == NULL || (*L)->Node.hp == NULL) { + return ERROR; + } + + p = (*L)->Node.hp; + (*L)->Node.hp = p->tp; + p->tp = NULL; + + *e = p; + + return OK; +} + +/* + * + * + * visitʹL + */ +void Traverse(GList L, void(Visit)(AtomType)) { + if(L == NULL) { + return; + } + + if(L->tag == List) { + Traverse(L->Node.hp, Visit); + } else { + Visit(L->Node.atom); + } + + Traverse(L->tp, Visit); +} + +/* + * ͼλ + * + * L + */ +void PrintGraph(GList L) { + Print(L); + printf("\n"); +} + +/* + * ͼλڲʵ֡ + */ +static void Print(GList L) { + if(L == NULL) { + return; + } + + // + if(L->tag == List) { + printf("("); + + if(L->Node.hp) { + Print(L->Node.hp); + } + + if(L->tp) { + printf("),"); + Print(L->tp); + } else { + printf(")"); + } + + // ԭӽ + } else { + printf("%c", L->Node.atom); + if(L->tp) { + printf(","); + Print(L->tp); + } + } +} + +/* + * ǿմstrָ֣hsubΪһ','֮ǰӴstrΪһ','֮Ӵ + * + *ע + * 1.ַstrȷ޿հ׷ţ + * strſȥҲδȥ + * 2.ɺstrҲᷢ仯 + */ +static void sever(SString hstr, SString str) { + int i, k, n; + SString ch; + + n = StrLength(str); + + i = 0; // ַʱα + k = 0; // δ + + do { + ++i; + + // ȡstrһַ + SubString(ch, str, i, 1); + + if(ch[1] == '(') { + ++k; + } + if(ch[1] == ')') { + --k; + } + } while(i < n && (ch[1] != ',' || k != 0)); + + if(i < n) { + SubString(hstr, str, 1, i - 1); + SubString(str, str, i + 1, n - i); + } else { + StrCopy(hstr, str); + ClearString(str); + } +} diff --git a/Dev-C++/ExerciseBook/05.33.2/GList-E.h b/Dev-C++/ExerciseBook/05.33.2/GList-E.h new file mode 100644 index 0000000..fa9af82 --- /dev/null +++ b/Dev-C++/ExerciseBook/05.33.2/GList-E.h @@ -0,0 +1,146 @@ +/*=========================== + * չ洢ʾ + ============================*/ + +#ifndef GLIST_E_H +#define GLIST_E_H + +#include +#include // ṩ mallocreallocfreeexit ԭ +#include "Status.h" //**01 **// +#include "SString.h" //**04 **// + +/* ԭԪ */ +typedef char AtomType; //ԭ + +/* + * + * + * Atom-0ԭӽ + * List-1 + */ +typedef enum { Atom, List } ElemTag; + +/* չ洢ʾͶ */ +typedef struct GLNode { + ElemTag tag; // ǣԭӽͱ + + // ԭӽͱϲ + union + { + AtomType atom; // atomԭӽֵAtomTypeû + struct GLNode* hp; // ָͷ + } Node; + struct GLNode* tp; // ָβ +} GLNode; + +/* */ +typedef GLNode* GList; + + +/* + * ʼ + * + * ʼյĹΪ0Ϊ1 + * + *ע + * Ҫÿһſ + */ +Status InitGList(GList* L); + +/* + * + * + * ַSL + */ +Status CreateGList(GList* L, SString S); + +/* + * + * + * ͷŹռڴ档 + */ +Status DestroyGList(GList* L); + +/* + * + * + * ɹLƵõT + */ +Status CopyGList(GList* T, GList L); + +/* + * + * + * عijȡ + */ +int GListLength(GList L); + +/* + * + * + * ع + */ +int GListDepth(GList L); + +/* + * п + * + * жϹǷΪա + */ +Status GListEmpty(GList L); + +/* + * ͷ + */ +GList GetHead(GList L); + +/* + * β + */ +GList GetTail(GList L); + +/* + * + * + * ԪeΪLĵһԪء + */ +Status InsertFirst(GList* L, GList e); + +/* + * ɾ + * + * LĵһԪɾeء + */ +Status DeleteFirst(GList* L, GList* e); + +/* + * + * + * visitʹL + */ +void Traverse(GList L, void(Visit)(AtomType)); + +/* + * ͼλ + * + * L + */ +void PrintGraph(GList L); + +/* + * ͼλڲʵ֡ + */ +static void Print(GList L); + +/* + * ǿմstrָ֣hsubΪһ','֮ǰӴstrΪһ','֮Ӵ + * + *ע + * 1.ַstrȷ޿հ׷ţ + * strſȥҲδȥ + * 2.ɺstrҲᷢ仯 + */ +static void sever(SString hstr, SString str); + +#endif diff --git a/Dev-C++/ExerciseBook/05.33.2/SString.cpp b/Dev-C++/ExerciseBook/05.33.2/SString.cpp new file mode 100644 index 0000000..7a96fcf --- /dev/null +++ b/Dev-C++/ExerciseBook/05.33.2/SString.cpp @@ -0,0 +1,195 @@ +/*============================= + * Ķ˳洢ʾ˳򴮣 + * + * 㷨: 4.14.24.34.5 + ==============================*/ + +#include "SString.h" //**04 **// + +/* + * ʼ + * + * һֵΪcharsĴT + * + *ע + * òСӼ + */ +Status StrAssign(SString T, const char* chars) { + int i, len; + + len = (int) strlen(chars); + + // chars + if(len > MAXSTRLEN) { + return ERROR; + } + + T[0] = len; + for(i = 1; i <= len; i++) { + T[i] = chars[i - 1]; + } + + return OK; +} + +/* + * + * + * Sա + */ +Status ClearString(SString S) { + // ֻҪΪ0Ϳ + S[0] = 0; + return OK; +} + +/* + * п + * + * жϴSǷЧݡ + * + * ֵ + * TRUE : SΪ + * FALSE: SΪ + */ +Status StrEmpty(SString S) { + return S[0] == 0 ? TRUE : FALSE; +} + +/* + * + * + * شSԪصĸ + * + *ע + * òСӼ + */ +int StrLength(SString S) { + return S[0]; +} + +/* + * 㷨4.3 + * + * Ӵ + * + * SubS[pos, pos+len-1] + * ֵָʾǷȡɹ + * + *ע + * òСӼ + */ +Status SubString(SString Sub, SString S, int pos, int len) { + int i; + + if(pos < 1 || pos > S[0] || len < 0 || pos + len - 1 > S[0]) { + return ERROR; + } + + // Ԫ + for(i = 1; i <= len; i++) { + Sub[i] = S[pos + i - 1]; + } + + // ȷ³ + Sub[0] = len; + + return OK; +} + +/* + * ɾ + * + * ɾS[pos, pos+len-1] + */ +Status StrDelete(SString S, int pos, int len) { + int i; + + if(pos < 1 || pos + len - 1 > S[0] || len < 0) { + return ERROR; + } + + // ɾijΪ0ǰ + if(len == 0) { + return OK; + } + + // ѺԪŲǰ棬ǵɾԪ + for(i = pos + len; i <= S[0]; i++) { + S[i - len] = S[i]; + } + + // ȼ + S[0] -= len; + + return OK; +} + +/* + * Ƚ + * + * ȽϴSʹTرȽϽ + * + *ע + * òСӼ + */ +int StrCompare(SString S, SString T) { + int i = 1; + + while(i <= S[0] && i <= T[0]) { + // ַͬʱȽС + if(S[i] != T[i]) { + return S[i] - T[i]; + } + + i++; + } + + return S[0] - T[0]; +} + +/* + * + * + * SƵT + */ +Status StrCopy(SString T, SString S) { + int i; + + // ͬϢһ + for(i = 0; i <= S[0]; i++) { + T[i] = S[i]; + } + + return OK; +} + +/* + * ַSеĿհףɴӡַո + * + *ע + * úڱġ + */ +Status ClearBlank(SString S) { + int i, j; + + // ǿմ + if(S[0] == 0) { + return ERROR; + } + + for(i = 1, j = 0; i <= S[0]; i++) { + // հףԹ + if(S[i] == ' ' || !isprint(S[i])) { + continue; + } + + j++; + + S[j] = S[i]; + } + + S[0] = j; + + return OK; +} diff --git a/Dev-C++/ExerciseBook/05.33.2/SString.h b/Dev-C++/ExerciseBook/05.33.2/SString.h new file mode 100644 index 0000000..0632f18 --- /dev/null +++ b/Dev-C++/ExerciseBook/05.33.2/SString.h @@ -0,0 +1,117 @@ +/*============================= + * Ķ˳洢ʾ˳򴮣 + * + * 㷨: 4.14.24.34.5 + ==============================*/ + +#ifndef SSTRING_H +#define SSTRING_H + +#include +#include // ṩ strlen ԭ +#include // ṩ isprint ԭ +#include "Status.h" //**01 **// + +/* 궨 */ +#define MAXSTRLEN 255 // ˳򴮵󴮳 + +/* + * ˳洢Ͷ + * + * עЧԪشSString1ŵԪʼ洢 + * SString0ŵԪ洢䳤 + */ +typedef unsigned char SString[MAXSTRLEN + 1]; // 0ŵԪŴij + + +/* + * ʾ + * + * ѭ̲ĵдϰߣposָʾַλ()1ʼ + */ + + +/* + * ʼ + * + * һֵΪcharsĴT + * + *ע + * òСӼ + */ +Status StrAssign(SString T, const char* chars); + +/* + * + * + * Sա + */ +Status ClearString(SString S); + +/* + * п + * + * жϴSǷЧݡ + * + * ֵ + * TRUE : SΪ + * FALSE: SΪ + */ +Status StrEmpty(SString S); + +/* + * + * + * شSԪصĸ + * + *ע + * òСӼ + */ +int StrLength(SString S); + +/* + * 㷨4.3 + * + * Ӵ + * + * SubS[pos, pos+len-1] + * ֵָʾǷȡɹ + * + *ע + * òСӼ + */ +Status SubString(SString Sub, SString S, int pos, int len); + +/* + * ɾ + * + * ɾS[pos, pos+len-1] + */ +Status StrDelete(SString S, int pos, int len); + +/* + * Ƚ + * + * ȽϴSʹTرȽϽ + * + *ע + * òСӼ + */ +int StrCompare(SString S, SString T); + +/* + * + * + * SƵT + */ +Status StrCopy(SString T, SString S); + +/* + * ַSеĿհףɴӡַո + * + *ע + * úڱġ + */ +Status ClearBlank(SString S); + +#endif diff --git a/Dev-C++/ExerciseBook/05.34.1/05.34.1.cpp b/Dev-C++/ExerciseBook/05.34.1/05.34.1.cpp new file mode 100644 index 0000000..b3a2013 --- /dev/null +++ b/Dev-C++/ExerciseBook/05.34.1/05.34.1.cpp @@ -0,0 +1,62 @@ +#include +#include "Status.h" //**01 **// +#include "SString.h" //**04 **// +#include "GList-HT.h" //**05 ͹**// + +/* + * ùͷβ洢ʾ + */ +Status Algo_5_34_1(GList* L); + + +int main(int argc, char* argv[]) { + GList L; + char* s = "(a,((b,c),()),(((d),e),f))"; + SString S; + + printf(" L ...\n"); + StrAssign(S, s); + CreateGList(&L, S); + printf("L = "); + PrintGraph(L); + + printf("ù...\n"); + Algo_5_34_1(&L); + printf("L = "); + PrintGraph(L); + + return 0; +} + + +/* + * ùͷβ洢ʾ + */ +Status Algo_5_34_1(GList* L) { + GList head, tail; + + if(L == NULL || *L == NULL) { + return ERROR; + } + + // Ӻǰﵽ + head = *L; + tail = (*L)->Node.ptr.tp; + + // Աͷ + if(head->Node.ptr.hp != NULL && head->Node.ptr.hp->tag == List) { + Algo_5_34_1(&(head->Node.ptr.hp)); + } + + // Աβ + if(tail != NULL) { + Algo_5_34_1(&((*L)->Node.ptr.tp)); + + // ͷβ + *L = (*L)->Node.ptr.tp; + tail->Node.ptr.tp = head; + head->Node.ptr.tp = NULL; + } + + return OK; +} diff --git a/Dev-C++/ExerciseBook/05.34.1/05.34.1.dev b/Dev-C++/ExerciseBook/05.34.1/05.34.1.dev new file mode 100644 index 0000000..5b17ca2 --- /dev/null +++ b/Dev-C++/ExerciseBook/05.34.1/05.34.1.dev @@ -0,0 +1,102 @@ +[Project] +FileName=05.34.1.dev +Name=05.34.1 +Type=1 +Ver=2 +ObjFiles= +Includes= +Libs= +PrivateResource= +ResourceIncludes= +MakeIncludes= +Compiler= +CppCompiler= +Linker= +IsCpp=0 +Icon= +ExeOutput= +ObjectOutput= +LogOutput= +LogOutputEnabled=0 +OverrideOutput=0 +OverrideOutputName= +HostApplication= +UseCustomMakefile=0 +CustomMakefile= +CommandLine= +Folders= +IncludeVersionInfo=0 +SupportXPThemes=0 +CompilerSet=1 +CompilerSettings=0000000000000000001000000 +UnitCount=5 + +[VersionInfo] +Major=1 +Minor=0 +Release=0 +Build=0 +LanguageID=1033 +CharsetID=1252 +CompanyName= +FileVersion= +FileDescription=Developed using the Dev-C++ IDE +InternalName= +LegalCopyright= +LegalTrademarks= +OriginalFilename= +ProductName= +ProductVersion= +AutoIncBuildNr=0 +SyncProduct=1 + +[Unit4] +FileName=SString.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit2] +FileName=GList-HT.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit1] +FileName=05.34.1.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit3] +FileName=GList-HT.h +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit5] +FileName=SString.h +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + diff --git a/Dev-C++/ExerciseBook/05.34.1/GList-HT.cpp b/Dev-C++/ExerciseBook/05.34.1/GList-HT.cpp new file mode 100644 index 0000000..bad30df --- /dev/null +++ b/Dev-C++/ExerciseBook/05.34.1/GList-HT.cpp @@ -0,0 +1,418 @@ +/*============================ + * ͷβ洢ʾ + * + * 㷨: 5.55.65.75.8 + =============================*/ + +#include "GList-HT.h" //**05 ͹**// + +/* + * ʼ + * + * ʼյĹΪ0Ϊ1 + * + *ע + * Ҫÿһȥſ + */ +Status InitGList(GList* L) { + if(L == NULL) { + return ERROR; + } + + *L = NULL; + + return OK; +} + +/* + * 㷨5.7 + * + * + * + * ַSL + */ +Status CreateGList(GList* L, SString S) { + SString emp; // չַ + SString hsub, sub; + GList p, q; + + if(L == NULL) { + return ERROR; + } + + // ַSеĿհףɴӡַո + ClearBlank(S); + + if(StrEmpty(S)) { + return ERROR; + } + + StrAssign(emp, "()"); + + /* + * 봮Ϊ()ҪյĹ + * + *ע + * ̲Ĵġ + * StrCompareķֵָʾַĴСָʾַǷȡ + * S()ȣֵӦ0 + */ + if(!StrCompare(S, emp)) { + *L = NULL; + } else { + *L = (GList) malloc(sizeof(GLNode)); + if(*L == NULL) { + exit(OVERFLOW); + } + + // ԭ + if(StrLength(S) == 1) { + (*L)->tag = Atom; + (*L)->Node.atom = S[1]; + } else { + (*L)->tag = List; + + p = *L; + + // ȥ + SubString(sub, S, 2, StrLength(S) - 2); + + // ظnӱ + do { + // subзͷhsubɺsubҲᷢ仯 + sever(hsub, sub); + + // ݹ鴴 + CreateGList(&(p->Node.ptr.hp), hsub); + + q = p; + + // βΪգҪβ + if(!StrEmpty(sub)) { + p = (GList) malloc(sizeof(GLNode)); + if(p == NULL) { + exit(OVERFLOW); + } + + p->tag = List; + + q->Node.ptr.tp = p; + } + } while(!StrEmpty(sub)); + + q->Node.ptr.tp = NULL; + } + } + + return OK; +} + +/* + * + * + * ͷŹռڴ档 + */ +Status DestroyGList(GList* L) { + GList head, tail; + + if(L == NULL || *L == NULL) { + return ERROR; + } + + // ɾԭӽ + if((*L)->tag == Atom) { + free(*L); + *L = NULL; + + // ɾӱ + } else { + head = (*L)->Node.ptr.hp; + tail = (*L)->Node.ptr.tp; + free(*L); + *L = NULL; + DestroyGList(&head); + DestroyGList(&tail); + } + + return OK; +} + +/* + * 㷨5.6 + * + * + * + * ɹLƵõT + */ +Status CopyGList(GList* T, GList L) { + if(T == NULL) { + return ERROR; + } + + if(L == NULL) { + *T = NULL; + } else { + // ½ + *T = (GList) malloc(sizeof(GLNode)); + if(*T == NULL) { + exit(OVERFLOW); + } + + (*T)->tag = L->tag; + + // Ƶԭ + if(L->tag == Atom) { + (*T)->Node.atom = L->Node.atom; + + // Ʊͷͱβ + } else { + CopyGList(&((*T)->Node.ptr.hp), L->Node.ptr.hp); + CopyGList(&((*T)->Node.ptr.tp), L->Node.ptr.tp); + } + } + + return OK; +} + +/* + * + * + * عijȡ + */ +int GListLength(GList L) { + int count; + + for(count = 0; L != NULL; count++, L = L->Node.ptr.tp) { + } + + return count; +} + +/* + * 㷨5.5 + * + * + * + * ع + */ +int GListDepth(GList L) { + int max, deep; + GList p; + + // ձΪ1 + if(L == NULL) { + return 1; + } + + // ԭΪ0 + if(L->tag == Atom) { + return 0; + } + + // ݹӱ + for(max = 0, p = L; p != NULL; p = p->Node.ptr.tp) { + deep = GListDepth(p->Node.ptr.hp); + if(deep > max) { + max = deep; + } + } + + // ǿձǸԪȼһ + return max + 1; +} + +/* + * п + * + * жϹǷΪա + */ +Status GListEmpty(GList L) { + return L == NULL ? TRUE : FALSE; +} + +/* + * ͷ + */ +GList GetHead(GList L) { + GList p; + + // ձޱͷﲻܷNULLȻֲʧ˻Ƿ˿ձ + if(L == NULL) { + exit(ERROR); + } + + CopyGList(&p, L->Node.ptr.hp); + + return p; +} + +/* + * β + */ +GList GetTail(GList L) { + GList p; + + // ձޱβﲻܷNULLȻֲʧ˻Ƿ˿ձ + if(L == NULL) { + exit(ERROR); + } + + CopyGList(&p, L->Node.ptr.tp); + + return p; +} + +/* + * + * + * ԪeΪLĵһԪء + */ +Status InsertFirst(GList* L, GList e) { + GList g; + + if(L == NULL) { + return ERROR; + } + + g = (GList) malloc(sizeof(GLNode)); + if(g == NULL) { + exit(OVERFLOW); + } + + g->tag = List; + g->Node.ptr.hp = e; + g->Node.ptr.tp = *L; + *L = g; + + return OK; +} + +/* + * ɾ + * + * LĵһԪɾeء + */ +Status DeleteFirst(GList* L, GList* e) { + GList p; + + // ձ޷ɾ + if(L == NULL || *L == NULL) { + return ERROR; + } + + p = *L; + *L = (*L)->Node.ptr.tp; + + CopyGList(e, p->Node.ptr.hp); + + free(p); + + return OK; +} + +/* + * + * + * visitʹL + */ +void Traverse(GList L, void(Visit)(AtomType)) { + + if(L == NULL) { + return; + } + + if(L->tag == Atom) { + Visit(L->Node.atom); + } else { + Traverse(L->Node.ptr.hp, Visit); + Traverse(L->Node.ptr.tp, Visit); + } + +} + +/* + * ͼλ + * + * L + */ +void PrintGraph(GList L) { + Print(L, Head); + printf("\n"); +} + +/* + * ͼλڲʵ֣markͼλǡ + */ +static void Print(GList L, Mark mark) { + // LΪ + if(L == NULL) { + if(mark == Head) { + printf("("); + } + + printf(")"); + + // LΪʱ + } else { + // ԭӽ㣬ԭ + if(L->tag == Atom) { + printf("%c", L->Node.atom); + + // ӱ㣬ҪԱͷβֱ + } else { + if(mark == Head) { + printf("("); + } else { + printf(","); + } + + Print(L->Node.ptr.hp, Head); + Print(L->Node.ptr.tp, Tail); + } + } +} + +/* + * 㷨5.8 + * + * ǿմstrָ֣hsubΪһ','֮ǰӴstrΪһ','֮Ӵ + * + *ע + * 1.ַstrȷ޿հ׷ţstrѾȥš + * 2.ɺstrҲᷢ仯 + */ +static void sever(SString hstr, SString str) { + int i, k, n; + SString ch; + + n = StrLength(str); + + i = 0; // ַʱα + k = 0; // δ + + do { + ++i; + + // ȡstrһַ + SubString(ch, str, i, 1); + + if(ch[1] == '(') { + ++k; + } + + if(ch[1] == ')') { + --k; + } + } while(i < n && (ch[1] != ',' || k != 0)); + + // ڶ + if(i < n) { + SubString(hstr, str, 1, i - 1); + SubString(str, str, i + 1, n - i); + + // ֻһ + } else { + StrCopy(hstr, str); + ClearString(str); + } +} diff --git a/Dev-C++/ExerciseBook/05.34.1/GList-HT.h b/Dev-C++/ExerciseBook/05.34.1/GList-HT.h new file mode 100644 index 0000000..508b96f --- /dev/null +++ b/Dev-C++/ExerciseBook/05.34.1/GList-HT.h @@ -0,0 +1,164 @@ +/*============================ + * ͷβ洢ʾ + * + * 㷨: 5.55.65.75.8 + =============================*/ + +#ifndef GLIST_HT_H +#define GLIST_HT_H + +#include +#include // ṩ mallocreallocfreeexit ԭ +#include "Status.h" //**01 **// +#include "SString.h" //**04 **// + +/* ԭԪ */ +typedef char AtomType; + +/* + * + * + * Atom-0ԭӽ + * List-1 + */ +typedef enum { Atom, List } ElemTag; + +/* ͷβ洢ʾͶ */ +typedef struct GLNode { + ElemTag tag; // ǣԭӽͱ + + // ԭӽͱϲ + union { + AtomType atom; // atomԭӽֵAtomTypeû + struct { + struct GLNode* hp; // ָͷ + struct GLNode* tp; // ָβ + } ptr; // ָ + } Node; +} GLNode; + +/* */ +typedef GLNode* GList; + +/* + * ͼλ + * + * HeadָԱͷ + * TailָԱβ + */ +typedef enum { Head, Tail } Mark; + + +/* + * ʼ + * + * ʼյĹΪ0Ϊ1 + * + *ע + * Ҫÿһȥſ + */ +Status InitGList(GList* L); + +/* + * 㷨5.7 + * + * + * + * ַSL + */ +Status CreateGList(GList* L, SString S); + +/* + * + * + * ͷŹռڴ档 + */ +Status DestroyGList(GList* L); + +/* + * 㷨5.6 + * + * + * + * ɹLƵõT + */ +Status CopyGList(GList* T, GList L); + +/* + * + * + * عijȡ + */ +int GListLength(GList L); + +/* + * 㷨5.5 + * + * + * + * ع + */ +int GListDepth(GList L); + +/* + * п + * + * жϹǷΪա + */ +Status GListEmpty(GList L); + +/* + * ͷ + */ +GList GetHead(GList L); + +/* + * β + */ +GList GetTail(GList L); + +/* + * + * + * ԪeΪLĵһԪء + */ +Status InsertFirst(GList* L, GList e); + +/* + * ɾ + * + * LĵһԪɾeء + */ +Status DeleteFirst(GList* L, GList* e); + +/* + * + * + * visitʹL + */ +void Traverse(GList L, void (Visit)(AtomType)); + +/* + * ͼλ + * + * L + */ +void PrintGraph(GList L); + +/* + * ͼλڲʵ֣markͼλǡ + */ +static void Print(GList L, Mark mark); + +/* + * 㷨5.8 + * + * ǿմstrָ֣hsubΪһ','֮ǰӴstrΪһ','֮Ӵ + * + *ע + * 1.ַstrȷ޿հ׷ţstrѾȥš + * 2.ɺstrҲᷢ仯 + */ +static void sever(SString hstr, SString str); + +#endif diff --git a/Dev-C++/ExerciseBook/05.34.1/SString.cpp b/Dev-C++/ExerciseBook/05.34.1/SString.cpp new file mode 100644 index 0000000..7a96fcf --- /dev/null +++ b/Dev-C++/ExerciseBook/05.34.1/SString.cpp @@ -0,0 +1,195 @@ +/*============================= + * Ķ˳洢ʾ˳򴮣 + * + * 㷨: 4.14.24.34.5 + ==============================*/ + +#include "SString.h" //**04 **// + +/* + * ʼ + * + * һֵΪcharsĴT + * + *ע + * òСӼ + */ +Status StrAssign(SString T, const char* chars) { + int i, len; + + len = (int) strlen(chars); + + // chars + if(len > MAXSTRLEN) { + return ERROR; + } + + T[0] = len; + for(i = 1; i <= len; i++) { + T[i] = chars[i - 1]; + } + + return OK; +} + +/* + * + * + * Sա + */ +Status ClearString(SString S) { + // ֻҪΪ0Ϳ + S[0] = 0; + return OK; +} + +/* + * п + * + * жϴSǷЧݡ + * + * ֵ + * TRUE : SΪ + * FALSE: SΪ + */ +Status StrEmpty(SString S) { + return S[0] == 0 ? TRUE : FALSE; +} + +/* + * + * + * شSԪصĸ + * + *ע + * òСӼ + */ +int StrLength(SString S) { + return S[0]; +} + +/* + * 㷨4.3 + * + * Ӵ + * + * SubS[pos, pos+len-1] + * ֵָʾǷȡɹ + * + *ע + * òСӼ + */ +Status SubString(SString Sub, SString S, int pos, int len) { + int i; + + if(pos < 1 || pos > S[0] || len < 0 || pos + len - 1 > S[0]) { + return ERROR; + } + + // Ԫ + for(i = 1; i <= len; i++) { + Sub[i] = S[pos + i - 1]; + } + + // ȷ³ + Sub[0] = len; + + return OK; +} + +/* + * ɾ + * + * ɾS[pos, pos+len-1] + */ +Status StrDelete(SString S, int pos, int len) { + int i; + + if(pos < 1 || pos + len - 1 > S[0] || len < 0) { + return ERROR; + } + + // ɾijΪ0ǰ + if(len == 0) { + return OK; + } + + // ѺԪŲǰ棬ǵɾԪ + for(i = pos + len; i <= S[0]; i++) { + S[i - len] = S[i]; + } + + // ȼ + S[0] -= len; + + return OK; +} + +/* + * Ƚ + * + * ȽϴSʹTرȽϽ + * + *ע + * òСӼ + */ +int StrCompare(SString S, SString T) { + int i = 1; + + while(i <= S[0] && i <= T[0]) { + // ַͬʱȽС + if(S[i] != T[i]) { + return S[i] - T[i]; + } + + i++; + } + + return S[0] - T[0]; +} + +/* + * + * + * SƵT + */ +Status StrCopy(SString T, SString S) { + int i; + + // ͬϢһ + for(i = 0; i <= S[0]; i++) { + T[i] = S[i]; + } + + return OK; +} + +/* + * ַSеĿհףɴӡַո + * + *ע + * úڱġ + */ +Status ClearBlank(SString S) { + int i, j; + + // ǿմ + if(S[0] == 0) { + return ERROR; + } + + for(i = 1, j = 0; i <= S[0]; i++) { + // հףԹ + if(S[i] == ' ' || !isprint(S[i])) { + continue; + } + + j++; + + S[j] = S[i]; + } + + S[0] = j; + + return OK; +} diff --git a/Dev-C++/ExerciseBook/05.34.1/SString.h b/Dev-C++/ExerciseBook/05.34.1/SString.h new file mode 100644 index 0000000..0632f18 --- /dev/null +++ b/Dev-C++/ExerciseBook/05.34.1/SString.h @@ -0,0 +1,117 @@ +/*============================= + * Ķ˳洢ʾ˳򴮣 + * + * 㷨: 4.14.24.34.5 + ==============================*/ + +#ifndef SSTRING_H +#define SSTRING_H + +#include +#include // ṩ strlen ԭ +#include // ṩ isprint ԭ +#include "Status.h" //**01 **// + +/* 궨 */ +#define MAXSTRLEN 255 // ˳򴮵󴮳 + +/* + * ˳洢Ͷ + * + * עЧԪشSString1ŵԪʼ洢 + * SString0ŵԪ洢䳤 + */ +typedef unsigned char SString[MAXSTRLEN + 1]; // 0ŵԪŴij + + +/* + * ʾ + * + * ѭ̲ĵдϰߣposָʾַλ()1ʼ + */ + + +/* + * ʼ + * + * һֵΪcharsĴT + * + *ע + * òСӼ + */ +Status StrAssign(SString T, const char* chars); + +/* + * + * + * Sա + */ +Status ClearString(SString S); + +/* + * п + * + * жϴSǷЧݡ + * + * ֵ + * TRUE : SΪ + * FALSE: SΪ + */ +Status StrEmpty(SString S); + +/* + * + * + * شSԪصĸ + * + *ע + * òСӼ + */ +int StrLength(SString S); + +/* + * 㷨4.3 + * + * Ӵ + * + * SubS[pos, pos+len-1] + * ֵָʾǷȡɹ + * + *ע + * òСӼ + */ +Status SubString(SString Sub, SString S, int pos, int len); + +/* + * ɾ + * + * ɾS[pos, pos+len-1] + */ +Status StrDelete(SString S, int pos, int len); + +/* + * Ƚ + * + * ȽϴSʹTرȽϽ + * + *ע + * òСӼ + */ +int StrCompare(SString S, SString T); + +/* + * + * + * SƵT + */ +Status StrCopy(SString T, SString S); + +/* + * ַSеĿհףɴӡַո + * + *ע + * úڱġ + */ +Status ClearBlank(SString S); + +#endif diff --git a/Dev-C++/ExerciseBook/05.34.2/05.34.2.cpp b/Dev-C++/ExerciseBook/05.34.2/05.34.2.cpp new file mode 100644 index 0000000..c72e80d --- /dev/null +++ b/Dev-C++/ExerciseBook/05.34.2/05.34.2.cpp @@ -0,0 +1,61 @@ +#include +#include "Status.h" //**01 **// +#include "SString.h" //**04 **// +#include "GList-E.h" //**05 ͹**// + +/* + * ùչ洢ʾ + */ +Status Algo_5_34_2(GList* L); + + +int main(int argc, char* argv[]) { + GList L; + char* s = "(a,((b,c),()),(((d),e),f))"; + SString S; + + printf(" L ...\n"); + StrAssign(S, s); + CreateGList(&L, S); + printf("L = "); + PrintGraph(L); + + printf("ù...\n"); + Algo_5_34_2(&L); + printf("L = "); + PrintGraph(L); + + return 0; +} + + +/* + * ùչ洢ʾ + */ +Status Algo_5_34_2(GList* L) { + GList head, tail; + + if(L == NULL || *L == NULL) { + return ERROR; + } + + // Ӻǰﵽ + head = *L; + tail = (*L)->tp; + + if(head->tag == List && head->Node.hp != NULL) { + Algo_5_34_2(&(head->Node.hp)); + } + + // Աβ + if(tail != NULL) { + Algo_5_34_2(&((*L)->tp)); + + // ͷβ + *L = (*L)->tp; + tail->tp = head; + head->tp = NULL; + } + + return OK; +} diff --git a/Dev-C++/ExerciseBook/05.34.2/05.34.2.dev b/Dev-C++/ExerciseBook/05.34.2/05.34.2.dev new file mode 100644 index 0000000..8808872 --- /dev/null +++ b/Dev-C++/ExerciseBook/05.34.2/05.34.2.dev @@ -0,0 +1,102 @@ +[Project] +FileName=05.34.2.dev +Name=05.34.2 +Type=1 +Ver=2 +ObjFiles= +Includes= +Libs= +PrivateResource= +ResourceIncludes= +MakeIncludes= +Compiler= +CppCompiler= +Linker= +IsCpp=0 +Icon= +ExeOutput= +ObjectOutput= +LogOutput= +LogOutputEnabled=0 +OverrideOutput=0 +OverrideOutputName= +HostApplication= +UseCustomMakefile=0 +CustomMakefile= +CommandLine= +Folders= +IncludeVersionInfo=0 +SupportXPThemes=0 +CompilerSet=1 +CompilerSettings=0000000000000000001000000 +UnitCount=5 + +[VersionInfo] +Major=1 +Minor=0 +Release=0 +Build=0 +LanguageID=1033 +CharsetID=1252 +CompanyName= +FileVersion= +FileDescription=Developed using the Dev-C++ IDE +InternalName= +LegalCopyright= +LegalTrademarks= +OriginalFilename= +ProductName= +ProductVersion= +AutoIncBuildNr=0 +SyncProduct=1 + +[Unit4] +FileName=SString.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit2] +FileName=GList-E.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit1] +FileName=05.34.2.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit3] +FileName=GList-E.h +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit5] +FileName=SString.h +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + diff --git a/Dev-C++/ExerciseBook/05.34.2/GList-E.cpp b/Dev-C++/ExerciseBook/05.34.2/GList-E.cpp new file mode 100644 index 0000000..3fc0ad9 --- /dev/null +++ b/Dev-C++/ExerciseBook/05.34.2/GList-E.cpp @@ -0,0 +1,449 @@ +/*=========================== + * չ洢ʾ + ============================*/ + +#include "GList-E.h" //**05 ͹**// + +/* + * ʼ + * + * ʼյĹΪ0Ϊ1 + * + *ע + * Ҫÿһſ + */ +Status InitGList(GList* L) { + if(L == NULL) { + return ERROR; + } + + *L = (GList) malloc(sizeof(GLNode)); + if(!*L) { + exit(OVERFLOW); + } + + (*L)->tag = List; + (*L)->Node.hp = NULL; + (*L)->tp = NULL; + + return OK; +} + +/* + * + * + * ַSL + */ +Status CreateGList(GList* L, SString S) { + SString emp, hsub, sub, tmp; + + if(L == NULL) { + return ERROR; + } + + // ַSеĿհףɴӡַո + ClearBlank(S); + + if(StrEmpty(S)) { + return ERROR; + } + + // Ϊ˲ƻS + StrCopy(sub, S); + + /* + * ִеʱ + * ٴִеʱѾȥ + */ + sever(hsub, sub); + + *L = (GList) malloc(sizeof(GLNode)); + if(*L == NULL) { + exit(OVERFLOW); + } + + StrAssign(emp, "()"); + + if(!StrCompare(hsub, emp)) { + (*L)->tag = List; + (*L)->Node.hp = NULL; + } else { + if(StrLength(hsub) == 1) { + (*L)->tag = Atom; + (*L)->Node.atom = hsub[1]; + } else { + (*L)->tag = List; + + SubString(tmp, hsub, 2, StrLength(hsub) - 2); + + CreateGList(&((*L)->Node.hp), tmp); + } + } + + // ڶβ˳ݹ + if(StrEmpty(sub)) { + (*L)->tp = NULL; + } else { + // ݹβ + CreateGList(&((*L)->tp), sub); + } + + return OK; +} + +/* + * + * + * ͷŹռڴ档 + */ +Status DestroyGList(GList* L) { + GList head, tail; + + if(L == NULL || *L == NULL) { + return ERROR; + } + + // ӱ + if((*L)->tag == List) { + head = (*L)->Node.hp; // ͷ + tail = (*L)->tp; // β + + free(*L); + *L = NULL; + + // ݹ鴦ͷ + if(head != NULL) { + DestroyGList(&head); + } + + // ݹ鴦β + if(tail != NULL) { + DestroyGList(&tail); + } + + // ԭӽ + } else { + tail = (*L)->tp; // β + + free(*L); + *L = NULL; + + if(tail != NULL) { + DestroyGList(&tail); + } + } + + return OK; +} + +/* + * + * + * ɹLƵõT + */ +Status CopyGList(GList* T, GList L) { + + if(L == NULL) { + return ERROR; + } + + *T = (GList) malloc(sizeof(GLNode)); + if(*T == NULL) { + exit(OVERFLOW); + } + + // ԭ + if(L->tag == Atom) { + (*T)->tag = Atom; + (*T)->Node.atom = L->Node.atom; + + // ӱ + } else { + (*T)->tag = List; + + // Ʊͷ + if(L->Node.hp != NULL) { + CopyGList(&((*T)->Node.hp), L->Node.hp); + } else { + (*T)->Node.hp = NULL; + } + } + + // Ʊβ + if(L->tp != NULL) { + CopyGList(&((*T)->tp), L->tp); + } else { + (*T)->tp = NULL; + } + + return OK; +} + +/* + * + * + * عijȡ + */ +int GListLength(GList L) { + int count = 0; + GList p; + + // + if(L == NULL) { + return -1; + } + + p = L->Node.hp; + + while(p != NULL) { + ++count; + p = p->tp; + } + + return count; +} + +/* + * + * + * ع + */ +int GListDepth(GList L) { + int max, deep; + GList p; + + max = 0; + + // + if(L == NULL) { + return -1; + } + + // ձΪ1 + if(L->tag == List && !L->Node.hp) { + return 1; + } + + // ԭΪ0 + if(L->tag == Atom) { + return 0; + } + + // ݹӱ + for(p = L->Node.hp; p != NULL; p = p->tp) { + // pΪͷָӱ + deep = GListDepth(p); + if(deep > max) { + max = deep; + } + } + + return max + 1; +} + +/* + * п + * + * жϹǷΪա + */ +Status GListEmpty(GList L) { + // + if(L == NULL) { + return ERROR; + } + + if(L->tag == List && L->Node.hp == NULL && L->tp == NULL) { + return TRUE; + } else { + return ERROR; + } +} + +/* + * ͷ + */ +GList GetHead(GList L) { + GList p, q; + + // ڻΪձ޷ȡͷ + if(L == NULL || L->Node.hp == NULL) { + return NULL; + } + + q = L->Node.hp->tp; // ʱLıβϢ + L->Node.hp->tp = NULL; // ȥLıβ + + CopyGList(&p, L->Node.hp); // ƱͷϢαβ + + L->Node.hp->tp = q; // ָLıβϢ + + return p; +} + +/* + * β + */ +GList GetTail(GList L) { + GList p, q; + + // ڻΪձ޷ȡβ + if(L == NULL || L->Node.hp == NULL) { + return NULL; + } + + q = L->Node.hp; // ʱLıͷϢ + L->Node.hp = q->tp; // ժLıͷ + + CopyGList(&p, L); // ƱβϢαͷ + + q->tp = L->Node.hp; // ָLıͷϢ + L->Node.hp = q; + + return p; +} + +/* + * + * + * ԪeΪLĵһԪء + */ +Status InsertFirst(GList* L, GList e) { + + // + if(L == NULL || *L == NULL) { + return ERROR; + } + + if(e == NULL) { + return ERROR; + } + + e->tp = (*L)->Node.hp; + (*L)->Node.hp = e; + + return OK; +} + +/* + * ɾ + * + * LĵһԪɾeء + */ +Status DeleteFirst(GList* L, GList* e) { + GList p; + + // ڻΪձ޷ɾͷ + if(*L == NULL || (*L)->Node.hp == NULL) { + return ERROR; + } + + p = (*L)->Node.hp; + (*L)->Node.hp = p->tp; + p->tp = NULL; + + *e = p; + + return OK; +} + +/* + * + * + * visitʹL + */ +void Traverse(GList L, void(Visit)(AtomType)) { + if(L == NULL) { + return; + } + + if(L->tag == List) { + Traverse(L->Node.hp, Visit); + } else { + Visit(L->Node.atom); + } + + Traverse(L->tp, Visit); +} + +/* + * ͼλ + * + * L + */ +void PrintGraph(GList L) { + Print(L); + printf("\n"); +} + +/* + * ͼλڲʵ֡ + */ +static void Print(GList L) { + if(L == NULL) { + return; + } + + // + if(L->tag == List) { + printf("("); + + if(L->Node.hp) { + Print(L->Node.hp); + } + + if(L->tp) { + printf("),"); + Print(L->tp); + } else { + printf(")"); + } + + // ԭӽ + } else { + printf("%c", L->Node.atom); + if(L->tp) { + printf(","); + Print(L->tp); + } + } +} + +/* + * ǿմstrָ֣hsubΪһ','֮ǰӴstrΪһ','֮Ӵ + * + *ע + * 1.ַstrȷ޿հ׷ţ + * strſȥҲδȥ + * 2.ɺstrҲᷢ仯 + */ +static void sever(SString hstr, SString str) { + int i, k, n; + SString ch; + + n = StrLength(str); + + i = 0; // ַʱα + k = 0; // δ + + do { + ++i; + + // ȡstrһַ + SubString(ch, str, i, 1); + + if(ch[1] == '(') { + ++k; + } + if(ch[1] == ')') { + --k; + } + } while(i < n && (ch[1] != ',' || k != 0)); + + if(i < n) { + SubString(hstr, str, 1, i - 1); + SubString(str, str, i + 1, n - i); + } else { + StrCopy(hstr, str); + ClearString(str); + } +} diff --git a/Dev-C++/ExerciseBook/05.34.2/GList-E.h b/Dev-C++/ExerciseBook/05.34.2/GList-E.h new file mode 100644 index 0000000..fa9af82 --- /dev/null +++ b/Dev-C++/ExerciseBook/05.34.2/GList-E.h @@ -0,0 +1,146 @@ +/*=========================== + * չ洢ʾ + ============================*/ + +#ifndef GLIST_E_H +#define GLIST_E_H + +#include +#include // ṩ mallocreallocfreeexit ԭ +#include "Status.h" //**01 **// +#include "SString.h" //**04 **// + +/* ԭԪ */ +typedef char AtomType; //ԭ + +/* + * + * + * Atom-0ԭӽ + * List-1 + */ +typedef enum { Atom, List } ElemTag; + +/* չ洢ʾͶ */ +typedef struct GLNode { + ElemTag tag; // ǣԭӽͱ + + // ԭӽͱϲ + union + { + AtomType atom; // atomԭӽֵAtomTypeû + struct GLNode* hp; // ָͷ + } Node; + struct GLNode* tp; // ָβ +} GLNode; + +/* */ +typedef GLNode* GList; + + +/* + * ʼ + * + * ʼյĹΪ0Ϊ1 + * + *ע + * Ҫÿһſ + */ +Status InitGList(GList* L); + +/* + * + * + * ַSL + */ +Status CreateGList(GList* L, SString S); + +/* + * + * + * ͷŹռڴ档 + */ +Status DestroyGList(GList* L); + +/* + * + * + * ɹLƵõT + */ +Status CopyGList(GList* T, GList L); + +/* + * + * + * عijȡ + */ +int GListLength(GList L); + +/* + * + * + * ع + */ +int GListDepth(GList L); + +/* + * п + * + * жϹǷΪա + */ +Status GListEmpty(GList L); + +/* + * ͷ + */ +GList GetHead(GList L); + +/* + * β + */ +GList GetTail(GList L); + +/* + * + * + * ԪeΪLĵһԪء + */ +Status InsertFirst(GList* L, GList e); + +/* + * ɾ + * + * LĵһԪɾeء + */ +Status DeleteFirst(GList* L, GList* e); + +/* + * + * + * visitʹL + */ +void Traverse(GList L, void(Visit)(AtomType)); + +/* + * ͼλ + * + * L + */ +void PrintGraph(GList L); + +/* + * ͼλڲʵ֡ + */ +static void Print(GList L); + +/* + * ǿմstrָ֣hsubΪһ','֮ǰӴstrΪһ','֮Ӵ + * + *ע + * 1.ַstrȷ޿հ׷ţ + * strſȥҲδȥ + * 2.ɺstrҲᷢ仯 + */ +static void sever(SString hstr, SString str); + +#endif diff --git a/Dev-C++/ExerciseBook/05.34.2/SString.cpp b/Dev-C++/ExerciseBook/05.34.2/SString.cpp new file mode 100644 index 0000000..7a96fcf --- /dev/null +++ b/Dev-C++/ExerciseBook/05.34.2/SString.cpp @@ -0,0 +1,195 @@ +/*============================= + * Ķ˳洢ʾ˳򴮣 + * + * 㷨: 4.14.24.34.5 + ==============================*/ + +#include "SString.h" //**04 **// + +/* + * ʼ + * + * һֵΪcharsĴT + * + *ע + * òСӼ + */ +Status StrAssign(SString T, const char* chars) { + int i, len; + + len = (int) strlen(chars); + + // chars + if(len > MAXSTRLEN) { + return ERROR; + } + + T[0] = len; + for(i = 1; i <= len; i++) { + T[i] = chars[i - 1]; + } + + return OK; +} + +/* + * + * + * Sա + */ +Status ClearString(SString S) { + // ֻҪΪ0Ϳ + S[0] = 0; + return OK; +} + +/* + * п + * + * жϴSǷЧݡ + * + * ֵ + * TRUE : SΪ + * FALSE: SΪ + */ +Status StrEmpty(SString S) { + return S[0] == 0 ? TRUE : FALSE; +} + +/* + * + * + * شSԪصĸ + * + *ע + * òСӼ + */ +int StrLength(SString S) { + return S[0]; +} + +/* + * 㷨4.3 + * + * Ӵ + * + * SubS[pos, pos+len-1] + * ֵָʾǷȡɹ + * + *ע + * òСӼ + */ +Status SubString(SString Sub, SString S, int pos, int len) { + int i; + + if(pos < 1 || pos > S[0] || len < 0 || pos + len - 1 > S[0]) { + return ERROR; + } + + // Ԫ + for(i = 1; i <= len; i++) { + Sub[i] = S[pos + i - 1]; + } + + // ȷ³ + Sub[0] = len; + + return OK; +} + +/* + * ɾ + * + * ɾS[pos, pos+len-1] + */ +Status StrDelete(SString S, int pos, int len) { + int i; + + if(pos < 1 || pos + len - 1 > S[0] || len < 0) { + return ERROR; + } + + // ɾijΪ0ǰ + if(len == 0) { + return OK; + } + + // ѺԪŲǰ棬ǵɾԪ + for(i = pos + len; i <= S[0]; i++) { + S[i - len] = S[i]; + } + + // ȼ + S[0] -= len; + + return OK; +} + +/* + * Ƚ + * + * ȽϴSʹTرȽϽ + * + *ע + * òСӼ + */ +int StrCompare(SString S, SString T) { + int i = 1; + + while(i <= S[0] && i <= T[0]) { + // ַͬʱȽС + if(S[i] != T[i]) { + return S[i] - T[i]; + } + + i++; + } + + return S[0] - T[0]; +} + +/* + * + * + * SƵT + */ +Status StrCopy(SString T, SString S) { + int i; + + // ͬϢһ + for(i = 0; i <= S[0]; i++) { + T[i] = S[i]; + } + + return OK; +} + +/* + * ַSеĿհףɴӡַո + * + *ע + * úڱġ + */ +Status ClearBlank(SString S) { + int i, j; + + // ǿմ + if(S[0] == 0) { + return ERROR; + } + + for(i = 1, j = 0; i <= S[0]; i++) { + // հףԹ + if(S[i] == ' ' || !isprint(S[i])) { + continue; + } + + j++; + + S[j] = S[i]; + } + + S[0] = j; + + return OK; +} diff --git a/Dev-C++/ExerciseBook/05.34.2/SString.h b/Dev-C++/ExerciseBook/05.34.2/SString.h new file mode 100644 index 0000000..0632f18 --- /dev/null +++ b/Dev-C++/ExerciseBook/05.34.2/SString.h @@ -0,0 +1,117 @@ +/*============================= + * Ķ˳洢ʾ˳򴮣 + * + * 㷨: 4.14.24.34.5 + ==============================*/ + +#ifndef SSTRING_H +#define SSTRING_H + +#include +#include // ṩ strlen ԭ +#include // ṩ isprint ԭ +#include "Status.h" //**01 **// + +/* 궨 */ +#define MAXSTRLEN 255 // ˳򴮵󴮳 + +/* + * ˳洢Ͷ + * + * עЧԪشSString1ŵԪʼ洢 + * SString0ŵԪ洢䳤 + */ +typedef unsigned char SString[MAXSTRLEN + 1]; // 0ŵԪŴij + + +/* + * ʾ + * + * ѭ̲ĵдϰߣposָʾַλ()1ʼ + */ + + +/* + * ʼ + * + * һֵΪcharsĴT + * + *ע + * òСӼ + */ +Status StrAssign(SString T, const char* chars); + +/* + * + * + * Sա + */ +Status ClearString(SString S); + +/* + * п + * + * жϴSǷЧݡ + * + * ֵ + * TRUE : SΪ + * FALSE: SΪ + */ +Status StrEmpty(SString S); + +/* + * + * + * شSԪصĸ + * + *ע + * òСӼ + */ +int StrLength(SString S); + +/* + * 㷨4.3 + * + * Ӵ + * + * SubS[pos, pos+len-1] + * ֵָʾǷȡɹ + * + *ע + * òСӼ + */ +Status SubString(SString Sub, SString S, int pos, int len); + +/* + * ɾ + * + * ɾS[pos, pos+len-1] + */ +Status StrDelete(SString S, int pos, int len); + +/* + * Ƚ + * + * ȽϴSʹTرȽϽ + * + *ע + * òСӼ + */ +int StrCompare(SString S, SString T); + +/* + * + * + * SƵT + */ +Status StrCopy(SString T, SString S); + +/* + * ַSеĿհףɴӡַո + * + *ע + * úڱġ + */ +Status ClearBlank(SString S); + +#endif diff --git a/Dev-C++/ExerciseBook/05.35-05.36/05.35-05.36.cpp b/Dev-C++/ExerciseBook/05.35-05.36/05.35-05.36.cpp new file mode 100644 index 0000000..615ee5e --- /dev/null +++ b/Dev-C++/ExerciseBook/05.35-05.36/05.35-05.36.cpp @@ -0,0 +1,45 @@ +#include +#include "Status.h" //**01 **// +#include "SString.h" //**04 **// +#include "GList.h" //**05 ͹**// + +/* + * Lォ"( )"ΪΪյ״̬ + */ +Status Algo_5_35(GList* L, SString S); + +/* + * Lォ"( )"ΪΪյ״̬ + */ +void Algo_5_36(GList L); + + +int main(int argc, char* argv[]) { + GList L; + char* s = "(( ),(e),(a,(b,c,d)))"; + SString S; + + printf(" L ...\n"); + StrAssign(S, s); + Algo_5_35(&L, S); + + printf("L = "); + Algo_5_36(L); + + return 0; +} + + +/* + * Lォ"( )"ΪΪյ״̬ + */ +Status Algo_5_35(GList* L, SString S) { + return CreateGList(L, S); +} + +/* + * Lォ"( )"ΪΪյ״̬ + */ +void Algo_5_36(GList L) { + PrintGraph(L); +} diff --git a/Dev-C++/ExerciseBook/05.35-05.36/05.35-05.36.dev b/Dev-C++/ExerciseBook/05.35-05.36/05.35-05.36.dev new file mode 100644 index 0000000..5f68ebb --- /dev/null +++ b/Dev-C++/ExerciseBook/05.35-05.36/05.35-05.36.dev @@ -0,0 +1,102 @@ +[Project] +FileName=05.35-05.36.dev +Name=05.35-05.36 +Type=1 +Ver=2 +ObjFiles= +Includes= +Libs= +PrivateResource= +ResourceIncludes= +MakeIncludes= +Compiler= +CppCompiler= +Linker= +IsCpp=0 +Icon= +ExeOutput= +ObjectOutput= +LogOutput= +LogOutputEnabled=0 +OverrideOutput=0 +OverrideOutputName= +HostApplication= +UseCustomMakefile=0 +CustomMakefile= +CommandLine= +Folders= +IncludeVersionInfo=0 +SupportXPThemes=0 +CompilerSet=1 +CompilerSettings=0000000000000000001000000 +UnitCount=5 + +[VersionInfo] +Major=1 +Minor=0 +Release=0 +Build=0 +LanguageID=1033 +CharsetID=1252 +CompanyName= +FileVersion= +FileDescription=Developed using the Dev-C++ IDE +InternalName= +LegalCopyright= +LegalTrademarks= +OriginalFilename= +ProductName= +ProductVersion= +AutoIncBuildNr=0 +SyncProduct=1 + +[Unit4] +FileName=SString.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit2] +FileName=GList.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit1] +FileName=05.35-05.36.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit3] +FileName=GList.h +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit5] +FileName=SString.h +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + diff --git a/Dev-C++/ExerciseBook/05.35-05.36/GList.cpp b/Dev-C++/ExerciseBook/05.35-05.36/GList.cpp new file mode 100644 index 0000000..3956155 --- /dev/null +++ b/Dev-C++/ExerciseBook/05.35-05.36/GList.cpp @@ -0,0 +1,179 @@ +/*============================ + * ͷβ洢ʾ + =============================*/ + +#include "GList.h" + +/* + * + * + * ַSL + * + *ע + * ォ"( )"ΪΪյ״̬ + */ +Status CreateGList(GList* L, SString S) { + SString emp; // չַ + SString hsub, sub; + GList p, q; + + if(L == NULL) { + return ERROR; + } + + // ַSеĿհףɴӡַո + ClearBlank(S); + + if(StrEmpty(S)) { + return ERROR; + } + + StrAssign(emp, "( )"); + + /* + * 봮Ϊ()ҪյĹ + * + *ע + * ̲Ĵġ + * StrCompareķֵָʾַĴСָʾַǷȡ + * S()ȣֵӦ0 + */ + if(!StrCompare(S, emp)) { + *L = NULL; + } else { + *L = (GList) malloc(sizeof(GLNode)); + if(*L == NULL) { + exit(OVERFLOW); + } + + // ԭ + if(StrLength(S) == 1) { + (*L)->tag = Atom; + (*L)->Node.atom = S[1]; + } else { + (*L)->tag = List; + + p = *L; + + // ȥ + SubString(sub, S, 2, StrLength(S) - 2); + + // ظnӱ + do { + // subзͷhsubɺsubҲᷢ仯 + sever(hsub, sub); + + // ݹ鴴 + CreateGList(&(p->Node.ptr.hp), hsub); + + q = p; + + // βΪգҪβ + if(!StrEmpty(sub)) { + p = (GList) malloc(sizeof(GLNode)); + if(p == NULL) { + exit(OVERFLOW); + } + + p->tag = List; + + q->Node.ptr.tp = p; + } + } while(!StrEmpty(sub)); + + q->Node.ptr.tp = NULL; + } + } + + return OK; +} + +/* + * ͼλ + * + * L + * + *ע + * ォ"( )"ΪΪյ״̬ + */ +void PrintGraph(GList L) { + Print(L, Head); + printf("\n"); +} + +/* + * ͼλڲʵ֣markͼλǡ + */ +static void Print(GList L, Mark mark) { + // LΪ + if(L == NULL) { + if(mark == Head) { + printf("( "); + } + + printf(")"); + + // LΪʱ + } else { + // ԭӽ㣬ԭ + if(L->tag == Atom) { + printf("%c", L->Node.atom); + + // ӱ㣬ҪԱͷβֱ + } else { + if(mark == Head) { + printf("("); + } else { + printf(","); + } + + Print(L->Node.ptr.hp, Head); + Print(L->Node.ptr.tp, Tail); + } + } +} + +/* + * 㷨5.8 + * + * ǿմstrָ֣hsubΪһ','֮ǰӴstrΪһ','֮Ӵ + * + *ע + * 1.ַstrȷ޿հ׷ţstrѾȥš + * 2.ɺstrҲᷢ仯 + */ +static void sever(SString hstr, SString str) { + int i, k, n; + SString ch; + + n = StrLength(str); + + i = 0; // ַʱα + k = 0; // δ + + do { + ++i; + + // ȡstrһַ + SubString(ch, str, i, 1); + + if(ch[1] == '(') { + ++k; + } + + if(ch[1] == ')') { + --k; + } + } while(i < n && (ch[1] != ',' || k != 0)); + + // ڶ + if(i < n) { + SubString(hstr, str, 1, i - 1); + SubString(str, str, i + 1, n - i); + + // ֻһ + } else { + StrCopy(hstr, str); + ClearString(str); + } +} diff --git a/Dev-C++/ExerciseBook/05.35-05.36/GList.h b/Dev-C++/ExerciseBook/05.35-05.36/GList.h new file mode 100644 index 0000000..c9837e7 --- /dev/null +++ b/Dev-C++/ExerciseBook/05.35-05.36/GList.h @@ -0,0 +1,82 @@ +/*============================ + * ͷβ洢ʾ + =============================*/ + +#ifndef GLIST_H +#define GLIST_H + +#include +#include // ṩ mallocreallocfreeexit ԭ +#include "Status.h" //**01 **// +#include "SString.h" //**04 **// + +/* ԭԪ */ +typedef char AtomType; + +/* + * + * + * Atom-0ԭӽ + * List-1 + */ +typedef enum { Atom, List } ElemTag; + +/* ͷβ洢ʾͶ */ +typedef struct GLNode { + ElemTag tag; // ǣԭӽͱ + + // ԭӽͱϲ + union { + AtomType atom; // atomԭӽֵAtomTypeû + struct { + struct GLNode* hp; // ָͷ + struct GLNode* tp; // ָβ + } ptr; // ָ + } Node; +} GLNode; + +/* */ +typedef GLNode* GList; + +/* + * ͼλ + * + * HeadָԱͷ + * TailָԱβ + */ +typedef enum { Head, Tail } Mark; + + +/* + * 㷨5.7 + * + * + * + * ַSL + */ +Status CreateGList(GList* L, SString S); + +/* + * ͼλ + * + * L + */ +void PrintGraph(GList L); + +/* + * ͼλڲʵ֣markͼλǡ + */ +static void Print(GList L, Mark mark); + +/* + * 㷨5.8 + * + * ǿմstrָ֣hsubΪһ','֮ǰӴstrΪһ','֮Ӵ + * + *ע + * 1.ַstrȷ޿հ׷ţstrѾȥš + * 2.ɺstrҲᷢ仯 + */ +static void sever(SString hstr, SString str); + +#endif diff --git a/Dev-C++/ExerciseBook/05.35-05.36/SString.cpp b/Dev-C++/ExerciseBook/05.35-05.36/SString.cpp new file mode 100644 index 0000000..b8bb831 --- /dev/null +++ b/Dev-C++/ExerciseBook/05.35-05.36/SString.cpp @@ -0,0 +1,195 @@ +/*============================= + * Ķ˳洢ʾ˳򴮣 + * + * 㷨: 4.14.24.34.5 + ==============================*/ + +#include "SString.h" //**04 **// + +/* + * ʼ + * + * һֵΪcharsĴT + * + *ע + * òСӼ + */ +Status StrAssign(SString T, const char* chars) { + int i, len; + + len = (int) strlen(chars); + + // chars + if(len > MAXSTRLEN) { + return ERROR; + } + + T[0] = len; + for(i = 1; i <= len; i++) { + T[i] = chars[i - 1]; + } + + return OK; +} + +/* + * + * + * Sա + */ +Status ClearString(SString S) { + // ֻҪΪ0Ϳ + S[0] = 0; + return OK; +} + +/* + * п + * + * жϴSǷЧݡ + * + * ֵ + * TRUE : SΪ + * FALSE: SΪ + */ +Status StrEmpty(SString S) { + return S[0] == 0 ? TRUE : FALSE; +} + +/* + * + * + * شSԪصĸ + * + *ע + * òСӼ + */ +int StrLength(SString S) { + return S[0]; +} + +/* + * 㷨4.3 + * + * Ӵ + * + * SubS[pos, pos+len-1] + * ֵָʾǷȡɹ + * + *ע + * òСӼ + */ +Status SubString(SString Sub, SString S, int pos, int len) { + int i; + + if(pos < 1 || pos > S[0] || len < 0 || pos + len - 1 > S[0]) { + return ERROR; + } + + // Ԫ + for(i = 1; i <= len; i++) { + Sub[i] = S[pos + i - 1]; + } + + // ȷ³ + Sub[0] = len; + + return OK; +} + +/* + * ɾ + * + * ɾS[pos, pos+len-1] + */ +Status StrDelete(SString S, int pos, int len) { + int i; + + if(pos < 1 || pos + len - 1 > S[0] || len < 0) { + return ERROR; + } + + // ɾijΪ0ǰ + if(len == 0) { + return OK; + } + + // ѺԪŲǰ棬ǵɾԪ + for(i = pos + len; i <= S[0]; i++) { + S[i - len] = S[i]; + } + + // ȼ + S[0] -= len; + + return OK; +} + +/* + * Ƚ + * + * ȽϴSʹTرȽϽ + * + *ע + * òСӼ + */ +int StrCompare(SString S, SString T) { + int i = 1; + + while(i <= S[0] && i <= T[0]) { + // ַͬʱȽС + if(S[i] != T[i]) { + return S[i] - T[i]; + } + + i++; + } + + return S[0] - T[0]; +} + +/* + * + * + * SƵT + */ +Status StrCopy(SString T, SString S) { + int i; + + // ͬϢһ + for(i = 0; i <= S[0]; i++) { + T[i] = S[i]; + } + + return OK; +} + +/* + * ַSеIJɴӡַո + * + *ע + * úڱġ + */ +Status ClearBlank(SString S) { + int i, j; + + // ǿմ + if(S[0] == 0) { + return ERROR; + } + + for(i = 1, j = 0; i <= S[0]; i++) { + // հףԹ + if(!isprint(S[i])) { + continue; + } + + j++; + + S[j] = S[i]; + } + + S[0] = j; + + return OK; +} diff --git a/Dev-C++/ExerciseBook/05.35-05.36/SString.h b/Dev-C++/ExerciseBook/05.35-05.36/SString.h new file mode 100644 index 0000000..3635a16 --- /dev/null +++ b/Dev-C++/ExerciseBook/05.35-05.36/SString.h @@ -0,0 +1,117 @@ +/*============================= + * Ķ˳洢ʾ˳򴮣 + * + * 㷨: 4.14.24.34.5 + ==============================*/ + +#ifndef SSTRING_H +#define SSTRING_H + +#include +#include // ṩ strlen ԭ +#include // ṩ isprint ԭ +#include "Status.h" //**01 **// + +/* 궨 */ +#define MAXSTRLEN 255 // ˳򴮵󴮳 + +/* + * ˳洢Ͷ + * + * עЧԪشSString1ŵԪʼ洢 + * SString0ŵԪ洢䳤 + */ +typedef unsigned char SString[MAXSTRLEN + 1]; // 0ŵԪŴij + + +/* + * ʾ + * + * ѭ̲ĵдϰߣposָʾַλ()1ʼ + */ + + +/* + * ʼ + * + * һֵΪcharsĴT + * + *ע + * òСӼ + */ +Status StrAssign(SString T, const char* chars); + +/* + * + * + * Sա + */ +Status ClearString(SString S); + +/* + * п + * + * жϴSǷЧݡ + * + * ֵ + * TRUE : SΪ + * FALSE: SΪ + */ +Status StrEmpty(SString S); + +/* + * + * + * شSԪصĸ + * + *ע + * òСӼ + */ +int StrLength(SString S); + +/* + * 㷨4.3 + * + * Ӵ + * + * SubS[pos, pos+len-1] + * ֵָʾǷȡɹ + * + *ע + * òСӼ + */ +Status SubString(SString Sub, SString S, int pos, int len); + +/* + * ɾ + * + * ɾS[pos, pos+len-1] + */ +Status StrDelete(SString S, int pos, int len); + +/* + * Ƚ + * + * ȽϴSʹTرȽϽ + * + *ע + * òСӼ + */ +int StrCompare(SString S, SString T); + +/* + * + * + * SƵT + */ +Status StrCopy(SString T, SString S); + +/* + * ַSеIJɴӡַո + * + *ע + * úڱġ + */ +Status ClearBlank(SString S); + +#endif diff --git a/Dev-C++/ExerciseBook/05.37.1/05.37.1.cpp b/Dev-C++/ExerciseBook/05.37.1/05.37.1.cpp new file mode 100644 index 0000000..11b37d6 --- /dev/null +++ b/Dev-C++/ExerciseBook/05.37.1/05.37.1.cpp @@ -0,0 +1,63 @@ +#include +#include "SString.h" //**04 **// +#include "GList-HT.h" //**05 ͹**// + +/* + * ɾֵΪxԭͷβ洢ʾ + */ +void Algo_5_37_1(GList* L, AtomType x); + + +int main(int argc, char* argv[]) { + GList L; + char* s = "((b),(e),(a,(b,c,d)),(b,((b),b)),x,b,(y))"; + SString S; + + printf(" L ...\n"); + StrAssign(S, s); + CreateGList(&L, S); + printf("L = "); + PrintGraph(L); + + printf("ɾ L еԪ 'b' ...\n"); + Algo_5_37_1(&L, 'b'); + printf("L = "); + PrintGraph(L); + + return 0; +} + + +/* + * ɾֵΪxԭͷβ洢ʾ + */ +void Algo_5_37_1(GList* L, AtomType x) { + GList h, p; + + if(L == NULL || *L == NULL || (*L)->tag == Atom) { + return; + } + + h = (*L)->Node.ptr.hp; + + if(h != NULL) { + if(h->tag == List) { + Algo_5_37_1(&((*L)->Node.ptr.hp), x); + Algo_5_37_1(&((*L)->Node.ptr.tp), x); + } else { + if(h->Node.atom == x) { + p = *L; + *L = (*L)->Node.ptr.tp; + p->Node.ptr.tp = NULL; + DestroyGList(&p); + Algo_5_37_1(L, x); + } else { + Algo_5_37_1(&((*L)->Node.ptr.tp), x); + } + } + } else { + if((*L)->Node.ptr.tp != NULL) { + Algo_5_37_1(&((*L)->Node.ptr.tp), x); + } + } +} diff --git a/Dev-C++/ExerciseBook/05.37.1/05.37.1.dev b/Dev-C++/ExerciseBook/05.37.1/05.37.1.dev new file mode 100644 index 0000000..d2794e4 --- /dev/null +++ b/Dev-C++/ExerciseBook/05.37.1/05.37.1.dev @@ -0,0 +1,102 @@ +[Project] +FileName=05.37.1.dev +Name=05.37.1 +Type=1 +Ver=2 +ObjFiles= +Includes= +Libs= +PrivateResource= +ResourceIncludes= +MakeIncludes= +Compiler= +CppCompiler= +Linker= +IsCpp=0 +Icon= +ExeOutput= +ObjectOutput= +LogOutput= +LogOutputEnabled=0 +OverrideOutput=0 +OverrideOutputName= +HostApplication= +UseCustomMakefile=0 +CustomMakefile= +CommandLine= +Folders= +IncludeVersionInfo=0 +SupportXPThemes=0 +CompilerSet=1 +CompilerSettings=0000000000000000001000000 +UnitCount=5 + +[VersionInfo] +Major=1 +Minor=0 +Release=0 +Build=0 +LanguageID=1033 +CharsetID=1252 +CompanyName= +FileVersion= +FileDescription=Developed using the Dev-C++ IDE +InternalName= +LegalCopyright= +LegalTrademarks= +OriginalFilename= +ProductName= +ProductVersion= +AutoIncBuildNr=0 +SyncProduct=1 + +[Unit4] +FileName=SString.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit2] +FileName=GList-HT.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit1] +FileName=05.37.1.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit3] +FileName=GList-HT.h +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit5] +FileName=SString.h +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + diff --git a/Dev-C++/ExerciseBook/05.37.1/GList-HT.cpp b/Dev-C++/ExerciseBook/05.37.1/GList-HT.cpp new file mode 100644 index 0000000..bad30df --- /dev/null +++ b/Dev-C++/ExerciseBook/05.37.1/GList-HT.cpp @@ -0,0 +1,418 @@ +/*============================ + * ͷβ洢ʾ + * + * 㷨: 5.55.65.75.8 + =============================*/ + +#include "GList-HT.h" //**05 ͹**// + +/* + * ʼ + * + * ʼյĹΪ0Ϊ1 + * + *ע + * Ҫÿһȥſ + */ +Status InitGList(GList* L) { + if(L == NULL) { + return ERROR; + } + + *L = NULL; + + return OK; +} + +/* + * 㷨5.7 + * + * + * + * ַSL + */ +Status CreateGList(GList* L, SString S) { + SString emp; // չַ + SString hsub, sub; + GList p, q; + + if(L == NULL) { + return ERROR; + } + + // ַSеĿհףɴӡַո + ClearBlank(S); + + if(StrEmpty(S)) { + return ERROR; + } + + StrAssign(emp, "()"); + + /* + * 봮Ϊ()ҪյĹ + * + *ע + * ̲Ĵġ + * StrCompareķֵָʾַĴСָʾַǷȡ + * S()ȣֵӦ0 + */ + if(!StrCompare(S, emp)) { + *L = NULL; + } else { + *L = (GList) malloc(sizeof(GLNode)); + if(*L == NULL) { + exit(OVERFLOW); + } + + // ԭ + if(StrLength(S) == 1) { + (*L)->tag = Atom; + (*L)->Node.atom = S[1]; + } else { + (*L)->tag = List; + + p = *L; + + // ȥ + SubString(sub, S, 2, StrLength(S) - 2); + + // ظnӱ + do { + // subзͷhsubɺsubҲᷢ仯 + sever(hsub, sub); + + // ݹ鴴 + CreateGList(&(p->Node.ptr.hp), hsub); + + q = p; + + // βΪգҪβ + if(!StrEmpty(sub)) { + p = (GList) malloc(sizeof(GLNode)); + if(p == NULL) { + exit(OVERFLOW); + } + + p->tag = List; + + q->Node.ptr.tp = p; + } + } while(!StrEmpty(sub)); + + q->Node.ptr.tp = NULL; + } + } + + return OK; +} + +/* + * + * + * ͷŹռڴ档 + */ +Status DestroyGList(GList* L) { + GList head, tail; + + if(L == NULL || *L == NULL) { + return ERROR; + } + + // ɾԭӽ + if((*L)->tag == Atom) { + free(*L); + *L = NULL; + + // ɾӱ + } else { + head = (*L)->Node.ptr.hp; + tail = (*L)->Node.ptr.tp; + free(*L); + *L = NULL; + DestroyGList(&head); + DestroyGList(&tail); + } + + return OK; +} + +/* + * 㷨5.6 + * + * + * + * ɹLƵõT + */ +Status CopyGList(GList* T, GList L) { + if(T == NULL) { + return ERROR; + } + + if(L == NULL) { + *T = NULL; + } else { + // ½ + *T = (GList) malloc(sizeof(GLNode)); + if(*T == NULL) { + exit(OVERFLOW); + } + + (*T)->tag = L->tag; + + // Ƶԭ + if(L->tag == Atom) { + (*T)->Node.atom = L->Node.atom; + + // Ʊͷͱβ + } else { + CopyGList(&((*T)->Node.ptr.hp), L->Node.ptr.hp); + CopyGList(&((*T)->Node.ptr.tp), L->Node.ptr.tp); + } + } + + return OK; +} + +/* + * + * + * عijȡ + */ +int GListLength(GList L) { + int count; + + for(count = 0; L != NULL; count++, L = L->Node.ptr.tp) { + } + + return count; +} + +/* + * 㷨5.5 + * + * + * + * ع + */ +int GListDepth(GList L) { + int max, deep; + GList p; + + // ձΪ1 + if(L == NULL) { + return 1; + } + + // ԭΪ0 + if(L->tag == Atom) { + return 0; + } + + // ݹӱ + for(max = 0, p = L; p != NULL; p = p->Node.ptr.tp) { + deep = GListDepth(p->Node.ptr.hp); + if(deep > max) { + max = deep; + } + } + + // ǿձǸԪȼһ + return max + 1; +} + +/* + * п + * + * жϹǷΪա + */ +Status GListEmpty(GList L) { + return L == NULL ? TRUE : FALSE; +} + +/* + * ͷ + */ +GList GetHead(GList L) { + GList p; + + // ձޱͷﲻܷNULLȻֲʧ˻Ƿ˿ձ + if(L == NULL) { + exit(ERROR); + } + + CopyGList(&p, L->Node.ptr.hp); + + return p; +} + +/* + * β + */ +GList GetTail(GList L) { + GList p; + + // ձޱβﲻܷNULLȻֲʧ˻Ƿ˿ձ + if(L == NULL) { + exit(ERROR); + } + + CopyGList(&p, L->Node.ptr.tp); + + return p; +} + +/* + * + * + * ԪeΪLĵһԪء + */ +Status InsertFirst(GList* L, GList e) { + GList g; + + if(L == NULL) { + return ERROR; + } + + g = (GList) malloc(sizeof(GLNode)); + if(g == NULL) { + exit(OVERFLOW); + } + + g->tag = List; + g->Node.ptr.hp = e; + g->Node.ptr.tp = *L; + *L = g; + + return OK; +} + +/* + * ɾ + * + * LĵһԪɾeء + */ +Status DeleteFirst(GList* L, GList* e) { + GList p; + + // ձ޷ɾ + if(L == NULL || *L == NULL) { + return ERROR; + } + + p = *L; + *L = (*L)->Node.ptr.tp; + + CopyGList(e, p->Node.ptr.hp); + + free(p); + + return OK; +} + +/* + * + * + * visitʹL + */ +void Traverse(GList L, void(Visit)(AtomType)) { + + if(L == NULL) { + return; + } + + if(L->tag == Atom) { + Visit(L->Node.atom); + } else { + Traverse(L->Node.ptr.hp, Visit); + Traverse(L->Node.ptr.tp, Visit); + } + +} + +/* + * ͼλ + * + * L + */ +void PrintGraph(GList L) { + Print(L, Head); + printf("\n"); +} + +/* + * ͼλڲʵ֣markͼλǡ + */ +static void Print(GList L, Mark mark) { + // LΪ + if(L == NULL) { + if(mark == Head) { + printf("("); + } + + printf(")"); + + // LΪʱ + } else { + // ԭӽ㣬ԭ + if(L->tag == Atom) { + printf("%c", L->Node.atom); + + // ӱ㣬ҪԱͷβֱ + } else { + if(mark == Head) { + printf("("); + } else { + printf(","); + } + + Print(L->Node.ptr.hp, Head); + Print(L->Node.ptr.tp, Tail); + } + } +} + +/* + * 㷨5.8 + * + * ǿմstrָ֣hsubΪһ','֮ǰӴstrΪһ','֮Ӵ + * + *ע + * 1.ַstrȷ޿հ׷ţstrѾȥš + * 2.ɺstrҲᷢ仯 + */ +static void sever(SString hstr, SString str) { + int i, k, n; + SString ch; + + n = StrLength(str); + + i = 0; // ַʱα + k = 0; // δ + + do { + ++i; + + // ȡstrһַ + SubString(ch, str, i, 1); + + if(ch[1] == '(') { + ++k; + } + + if(ch[1] == ')') { + --k; + } + } while(i < n && (ch[1] != ',' || k != 0)); + + // ڶ + if(i < n) { + SubString(hstr, str, 1, i - 1); + SubString(str, str, i + 1, n - i); + + // ֻһ + } else { + StrCopy(hstr, str); + ClearString(str); + } +} diff --git a/Dev-C++/ExerciseBook/05.37.1/GList-HT.h b/Dev-C++/ExerciseBook/05.37.1/GList-HT.h new file mode 100644 index 0000000..508b96f --- /dev/null +++ b/Dev-C++/ExerciseBook/05.37.1/GList-HT.h @@ -0,0 +1,164 @@ +/*============================ + * ͷβ洢ʾ + * + * 㷨: 5.55.65.75.8 + =============================*/ + +#ifndef GLIST_HT_H +#define GLIST_HT_H + +#include +#include // ṩ mallocreallocfreeexit ԭ +#include "Status.h" //**01 **// +#include "SString.h" //**04 **// + +/* ԭԪ */ +typedef char AtomType; + +/* + * + * + * Atom-0ԭӽ + * List-1 + */ +typedef enum { Atom, List } ElemTag; + +/* ͷβ洢ʾͶ */ +typedef struct GLNode { + ElemTag tag; // ǣԭӽͱ + + // ԭӽͱϲ + union { + AtomType atom; // atomԭӽֵAtomTypeû + struct { + struct GLNode* hp; // ָͷ + struct GLNode* tp; // ָβ + } ptr; // ָ + } Node; +} GLNode; + +/* */ +typedef GLNode* GList; + +/* + * ͼλ + * + * HeadָԱͷ + * TailָԱβ + */ +typedef enum { Head, Tail } Mark; + + +/* + * ʼ + * + * ʼյĹΪ0Ϊ1 + * + *ע + * Ҫÿһȥſ + */ +Status InitGList(GList* L); + +/* + * 㷨5.7 + * + * + * + * ַSL + */ +Status CreateGList(GList* L, SString S); + +/* + * + * + * ͷŹռڴ档 + */ +Status DestroyGList(GList* L); + +/* + * 㷨5.6 + * + * + * + * ɹLƵõT + */ +Status CopyGList(GList* T, GList L); + +/* + * + * + * عijȡ + */ +int GListLength(GList L); + +/* + * 㷨5.5 + * + * + * + * ع + */ +int GListDepth(GList L); + +/* + * п + * + * жϹǷΪա + */ +Status GListEmpty(GList L); + +/* + * ͷ + */ +GList GetHead(GList L); + +/* + * β + */ +GList GetTail(GList L); + +/* + * + * + * ԪeΪLĵһԪء + */ +Status InsertFirst(GList* L, GList e); + +/* + * ɾ + * + * LĵһԪɾeء + */ +Status DeleteFirst(GList* L, GList* e); + +/* + * + * + * visitʹL + */ +void Traverse(GList L, void (Visit)(AtomType)); + +/* + * ͼλ + * + * L + */ +void PrintGraph(GList L); + +/* + * ͼλڲʵ֣markͼλǡ + */ +static void Print(GList L, Mark mark); + +/* + * 㷨5.8 + * + * ǿմstrָ֣hsubΪһ','֮ǰӴstrΪһ','֮Ӵ + * + *ע + * 1.ַstrȷ޿հ׷ţstrѾȥš + * 2.ɺstrҲᷢ仯 + */ +static void sever(SString hstr, SString str); + +#endif diff --git a/Dev-C++/ExerciseBook/05.37.1/SString.cpp b/Dev-C++/ExerciseBook/05.37.1/SString.cpp new file mode 100644 index 0000000..7a96fcf --- /dev/null +++ b/Dev-C++/ExerciseBook/05.37.1/SString.cpp @@ -0,0 +1,195 @@ +/*============================= + * Ķ˳洢ʾ˳򴮣 + * + * 㷨: 4.14.24.34.5 + ==============================*/ + +#include "SString.h" //**04 **// + +/* + * ʼ + * + * һֵΪcharsĴT + * + *ע + * òСӼ + */ +Status StrAssign(SString T, const char* chars) { + int i, len; + + len = (int) strlen(chars); + + // chars + if(len > MAXSTRLEN) { + return ERROR; + } + + T[0] = len; + for(i = 1; i <= len; i++) { + T[i] = chars[i - 1]; + } + + return OK; +} + +/* + * + * + * Sա + */ +Status ClearString(SString S) { + // ֻҪΪ0Ϳ + S[0] = 0; + return OK; +} + +/* + * п + * + * жϴSǷЧݡ + * + * ֵ + * TRUE : SΪ + * FALSE: SΪ + */ +Status StrEmpty(SString S) { + return S[0] == 0 ? TRUE : FALSE; +} + +/* + * + * + * شSԪصĸ + * + *ע + * òСӼ + */ +int StrLength(SString S) { + return S[0]; +} + +/* + * 㷨4.3 + * + * Ӵ + * + * SubS[pos, pos+len-1] + * ֵָʾǷȡɹ + * + *ע + * òСӼ + */ +Status SubString(SString Sub, SString S, int pos, int len) { + int i; + + if(pos < 1 || pos > S[0] || len < 0 || pos + len - 1 > S[0]) { + return ERROR; + } + + // Ԫ + for(i = 1; i <= len; i++) { + Sub[i] = S[pos + i - 1]; + } + + // ȷ³ + Sub[0] = len; + + return OK; +} + +/* + * ɾ + * + * ɾS[pos, pos+len-1] + */ +Status StrDelete(SString S, int pos, int len) { + int i; + + if(pos < 1 || pos + len - 1 > S[0] || len < 0) { + return ERROR; + } + + // ɾijΪ0ǰ + if(len == 0) { + return OK; + } + + // ѺԪŲǰ棬ǵɾԪ + for(i = pos + len; i <= S[0]; i++) { + S[i - len] = S[i]; + } + + // ȼ + S[0] -= len; + + return OK; +} + +/* + * Ƚ + * + * ȽϴSʹTرȽϽ + * + *ע + * òСӼ + */ +int StrCompare(SString S, SString T) { + int i = 1; + + while(i <= S[0] && i <= T[0]) { + // ַͬʱȽС + if(S[i] != T[i]) { + return S[i] - T[i]; + } + + i++; + } + + return S[0] - T[0]; +} + +/* + * + * + * SƵT + */ +Status StrCopy(SString T, SString S) { + int i; + + // ͬϢһ + for(i = 0; i <= S[0]; i++) { + T[i] = S[i]; + } + + return OK; +} + +/* + * ַSеĿհףɴӡַո + * + *ע + * úڱġ + */ +Status ClearBlank(SString S) { + int i, j; + + // ǿմ + if(S[0] == 0) { + return ERROR; + } + + for(i = 1, j = 0; i <= S[0]; i++) { + // հףԹ + if(S[i] == ' ' || !isprint(S[i])) { + continue; + } + + j++; + + S[j] = S[i]; + } + + S[0] = j; + + return OK; +} diff --git a/Dev-C++/ExerciseBook/05.37.1/SString.h b/Dev-C++/ExerciseBook/05.37.1/SString.h new file mode 100644 index 0000000..0632f18 --- /dev/null +++ b/Dev-C++/ExerciseBook/05.37.1/SString.h @@ -0,0 +1,117 @@ +/*============================= + * Ķ˳洢ʾ˳򴮣 + * + * 㷨: 4.14.24.34.5 + ==============================*/ + +#ifndef SSTRING_H +#define SSTRING_H + +#include +#include // ṩ strlen ԭ +#include // ṩ isprint ԭ +#include "Status.h" //**01 **// + +/* 궨 */ +#define MAXSTRLEN 255 // ˳򴮵󴮳 + +/* + * ˳洢Ͷ + * + * עЧԪشSString1ŵԪʼ洢 + * SString0ŵԪ洢䳤 + */ +typedef unsigned char SString[MAXSTRLEN + 1]; // 0ŵԪŴij + + +/* + * ʾ + * + * ѭ̲ĵдϰߣposָʾַλ()1ʼ + */ + + +/* + * ʼ + * + * һֵΪcharsĴT + * + *ע + * òСӼ + */ +Status StrAssign(SString T, const char* chars); + +/* + * + * + * Sա + */ +Status ClearString(SString S); + +/* + * п + * + * жϴSǷЧݡ + * + * ֵ + * TRUE : SΪ + * FALSE: SΪ + */ +Status StrEmpty(SString S); + +/* + * + * + * شSԪصĸ + * + *ע + * òСӼ + */ +int StrLength(SString S); + +/* + * 㷨4.3 + * + * Ӵ + * + * SubS[pos, pos+len-1] + * ֵָʾǷȡɹ + * + *ע + * òСӼ + */ +Status SubString(SString Sub, SString S, int pos, int len); + +/* + * ɾ + * + * ɾS[pos, pos+len-1] + */ +Status StrDelete(SString S, int pos, int len); + +/* + * Ƚ + * + * ȽϴSʹTرȽϽ + * + *ע + * òСӼ + */ +int StrCompare(SString S, SString T); + +/* + * + * + * SƵT + */ +Status StrCopy(SString T, SString S); + +/* + * ַSеĿհףɴӡַո + * + *ע + * úڱġ + */ +Status ClearBlank(SString S); + +#endif diff --git a/Dev-C++/ExerciseBook/05.37.2/05.37.2.cpp b/Dev-C++/ExerciseBook/05.37.2/05.37.2.cpp new file mode 100644 index 0000000..9e5afb1 --- /dev/null +++ b/Dev-C++/ExerciseBook/05.37.2/05.37.2.cpp @@ -0,0 +1,56 @@ +#include +#include // ṩmallocreallocfreeexitԭ +#include "SString.h" //**04 **// +#include "GList-E.h" //**05 ͹**// + +/* + * ɾֵΪxԭչ洢ʾ + */ +void Algo_5_37_2(GList* L, AtomType x); + + +int main(int argc, char* argv[]) { + GList L; + char* s = "((b),(e),(a,(b,c,d)),(b,((b),b)),x,b,(y))"; + SString S; + + printf(" L ...\n"); + StrAssign(S, s); + CreateGList(&L, S); + printf("L = "); + PrintGraph(L); + + printf("ɾ L еԪ 'b' ...\n"); + Algo_5_37_2(&L, 'b'); + printf("L = "); + PrintGraph(L); + + return 0; +} + + +/* + * ɾֵΪxԭչ洢ʾ + */ +void Algo_5_37_2(GList* L, AtomType x) { + GList p; + + if(L == NULL || *L == NULL) { + return; + } + + if((*L)->tag == List) { + Algo_5_37_2(&((*L)->Node.hp), x); + Algo_5_37_2(&((*L)->tp), x); + } else { + if((*L)->Node.atom == x) { + p = *L; + *L = (*L)->tp; + free(p); + + Algo_5_37_2(L, x); + } else { + Algo_5_37_2(&((*L)->tp), x); + } + } +} diff --git a/Dev-C++/ExerciseBook/05.37.2/05.37.2.dev b/Dev-C++/ExerciseBook/05.37.2/05.37.2.dev new file mode 100644 index 0000000..f6537dd --- /dev/null +++ b/Dev-C++/ExerciseBook/05.37.2/05.37.2.dev @@ -0,0 +1,102 @@ +[Project] +FileName=05.37.2.dev +Name=05.37.2 +Type=1 +Ver=2 +ObjFiles= +Includes= +Libs= +PrivateResource= +ResourceIncludes= +MakeIncludes= +Compiler= +CppCompiler= +Linker= +IsCpp=0 +Icon= +ExeOutput= +ObjectOutput= +LogOutput= +LogOutputEnabled=0 +OverrideOutput=0 +OverrideOutputName= +HostApplication= +UseCustomMakefile=0 +CustomMakefile= +CommandLine= +Folders= +IncludeVersionInfo=0 +SupportXPThemes=0 +CompilerSet=1 +CompilerSettings=0000000000000000001000000 +UnitCount=5 + +[VersionInfo] +Major=1 +Minor=0 +Release=0 +Build=0 +LanguageID=1033 +CharsetID=1252 +CompanyName= +FileVersion= +FileDescription=Developed using the Dev-C++ IDE +InternalName= +LegalCopyright= +LegalTrademarks= +OriginalFilename= +ProductName= +ProductVersion= +AutoIncBuildNr=0 +SyncProduct=1 + +[Unit4] +FileName=SString.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit2] +FileName=GList-E.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit1] +FileName=05.37.2.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit3] +FileName=GList-E.h +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit5] +FileName=SString.h +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + diff --git a/Dev-C++/ExerciseBook/05.37.2/GList-E.cpp b/Dev-C++/ExerciseBook/05.37.2/GList-E.cpp new file mode 100644 index 0000000..3fc0ad9 --- /dev/null +++ b/Dev-C++/ExerciseBook/05.37.2/GList-E.cpp @@ -0,0 +1,449 @@ +/*=========================== + * չ洢ʾ + ============================*/ + +#include "GList-E.h" //**05 ͹**// + +/* + * ʼ + * + * ʼյĹΪ0Ϊ1 + * + *ע + * Ҫÿһſ + */ +Status InitGList(GList* L) { + if(L == NULL) { + return ERROR; + } + + *L = (GList) malloc(sizeof(GLNode)); + if(!*L) { + exit(OVERFLOW); + } + + (*L)->tag = List; + (*L)->Node.hp = NULL; + (*L)->tp = NULL; + + return OK; +} + +/* + * + * + * ַSL + */ +Status CreateGList(GList* L, SString S) { + SString emp, hsub, sub, tmp; + + if(L == NULL) { + return ERROR; + } + + // ַSеĿհףɴӡַո + ClearBlank(S); + + if(StrEmpty(S)) { + return ERROR; + } + + // Ϊ˲ƻS + StrCopy(sub, S); + + /* + * ִеʱ + * ٴִеʱѾȥ + */ + sever(hsub, sub); + + *L = (GList) malloc(sizeof(GLNode)); + if(*L == NULL) { + exit(OVERFLOW); + } + + StrAssign(emp, "()"); + + if(!StrCompare(hsub, emp)) { + (*L)->tag = List; + (*L)->Node.hp = NULL; + } else { + if(StrLength(hsub) == 1) { + (*L)->tag = Atom; + (*L)->Node.atom = hsub[1]; + } else { + (*L)->tag = List; + + SubString(tmp, hsub, 2, StrLength(hsub) - 2); + + CreateGList(&((*L)->Node.hp), tmp); + } + } + + // ڶβ˳ݹ + if(StrEmpty(sub)) { + (*L)->tp = NULL; + } else { + // ݹβ + CreateGList(&((*L)->tp), sub); + } + + return OK; +} + +/* + * + * + * ͷŹռڴ档 + */ +Status DestroyGList(GList* L) { + GList head, tail; + + if(L == NULL || *L == NULL) { + return ERROR; + } + + // ӱ + if((*L)->tag == List) { + head = (*L)->Node.hp; // ͷ + tail = (*L)->tp; // β + + free(*L); + *L = NULL; + + // ݹ鴦ͷ + if(head != NULL) { + DestroyGList(&head); + } + + // ݹ鴦β + if(tail != NULL) { + DestroyGList(&tail); + } + + // ԭӽ + } else { + tail = (*L)->tp; // β + + free(*L); + *L = NULL; + + if(tail != NULL) { + DestroyGList(&tail); + } + } + + return OK; +} + +/* + * + * + * ɹLƵõT + */ +Status CopyGList(GList* T, GList L) { + + if(L == NULL) { + return ERROR; + } + + *T = (GList) malloc(sizeof(GLNode)); + if(*T == NULL) { + exit(OVERFLOW); + } + + // ԭ + if(L->tag == Atom) { + (*T)->tag = Atom; + (*T)->Node.atom = L->Node.atom; + + // ӱ + } else { + (*T)->tag = List; + + // Ʊͷ + if(L->Node.hp != NULL) { + CopyGList(&((*T)->Node.hp), L->Node.hp); + } else { + (*T)->Node.hp = NULL; + } + } + + // Ʊβ + if(L->tp != NULL) { + CopyGList(&((*T)->tp), L->tp); + } else { + (*T)->tp = NULL; + } + + return OK; +} + +/* + * + * + * عijȡ + */ +int GListLength(GList L) { + int count = 0; + GList p; + + // + if(L == NULL) { + return -1; + } + + p = L->Node.hp; + + while(p != NULL) { + ++count; + p = p->tp; + } + + return count; +} + +/* + * + * + * ع + */ +int GListDepth(GList L) { + int max, deep; + GList p; + + max = 0; + + // + if(L == NULL) { + return -1; + } + + // ձΪ1 + if(L->tag == List && !L->Node.hp) { + return 1; + } + + // ԭΪ0 + if(L->tag == Atom) { + return 0; + } + + // ݹӱ + for(p = L->Node.hp; p != NULL; p = p->tp) { + // pΪͷָӱ + deep = GListDepth(p); + if(deep > max) { + max = deep; + } + } + + return max + 1; +} + +/* + * п + * + * жϹǷΪա + */ +Status GListEmpty(GList L) { + // + if(L == NULL) { + return ERROR; + } + + if(L->tag == List && L->Node.hp == NULL && L->tp == NULL) { + return TRUE; + } else { + return ERROR; + } +} + +/* + * ͷ + */ +GList GetHead(GList L) { + GList p, q; + + // ڻΪձ޷ȡͷ + if(L == NULL || L->Node.hp == NULL) { + return NULL; + } + + q = L->Node.hp->tp; // ʱLıβϢ + L->Node.hp->tp = NULL; // ȥLıβ + + CopyGList(&p, L->Node.hp); // ƱͷϢαβ + + L->Node.hp->tp = q; // ָLıβϢ + + return p; +} + +/* + * β + */ +GList GetTail(GList L) { + GList p, q; + + // ڻΪձ޷ȡβ + if(L == NULL || L->Node.hp == NULL) { + return NULL; + } + + q = L->Node.hp; // ʱLıͷϢ + L->Node.hp = q->tp; // ժLıͷ + + CopyGList(&p, L); // ƱβϢαͷ + + q->tp = L->Node.hp; // ָLıͷϢ + L->Node.hp = q; + + return p; +} + +/* + * + * + * ԪeΪLĵһԪء + */ +Status InsertFirst(GList* L, GList e) { + + // + if(L == NULL || *L == NULL) { + return ERROR; + } + + if(e == NULL) { + return ERROR; + } + + e->tp = (*L)->Node.hp; + (*L)->Node.hp = e; + + return OK; +} + +/* + * ɾ + * + * LĵһԪɾeء + */ +Status DeleteFirst(GList* L, GList* e) { + GList p; + + // ڻΪձ޷ɾͷ + if(*L == NULL || (*L)->Node.hp == NULL) { + return ERROR; + } + + p = (*L)->Node.hp; + (*L)->Node.hp = p->tp; + p->tp = NULL; + + *e = p; + + return OK; +} + +/* + * + * + * visitʹL + */ +void Traverse(GList L, void(Visit)(AtomType)) { + if(L == NULL) { + return; + } + + if(L->tag == List) { + Traverse(L->Node.hp, Visit); + } else { + Visit(L->Node.atom); + } + + Traverse(L->tp, Visit); +} + +/* + * ͼλ + * + * L + */ +void PrintGraph(GList L) { + Print(L); + printf("\n"); +} + +/* + * ͼλڲʵ֡ + */ +static void Print(GList L) { + if(L == NULL) { + return; + } + + // + if(L->tag == List) { + printf("("); + + if(L->Node.hp) { + Print(L->Node.hp); + } + + if(L->tp) { + printf("),"); + Print(L->tp); + } else { + printf(")"); + } + + // ԭӽ + } else { + printf("%c", L->Node.atom); + if(L->tp) { + printf(","); + Print(L->tp); + } + } +} + +/* + * ǿմstrָ֣hsubΪһ','֮ǰӴstrΪһ','֮Ӵ + * + *ע + * 1.ַstrȷ޿հ׷ţ + * strſȥҲδȥ + * 2.ɺstrҲᷢ仯 + */ +static void sever(SString hstr, SString str) { + int i, k, n; + SString ch; + + n = StrLength(str); + + i = 0; // ַʱα + k = 0; // δ + + do { + ++i; + + // ȡstrһַ + SubString(ch, str, i, 1); + + if(ch[1] == '(') { + ++k; + } + if(ch[1] == ')') { + --k; + } + } while(i < n && (ch[1] != ',' || k != 0)); + + if(i < n) { + SubString(hstr, str, 1, i - 1); + SubString(str, str, i + 1, n - i); + } else { + StrCopy(hstr, str); + ClearString(str); + } +} diff --git a/Dev-C++/ExerciseBook/05.37.2/GList-E.h b/Dev-C++/ExerciseBook/05.37.2/GList-E.h new file mode 100644 index 0000000..fa9af82 --- /dev/null +++ b/Dev-C++/ExerciseBook/05.37.2/GList-E.h @@ -0,0 +1,146 @@ +/*=========================== + * չ洢ʾ + ============================*/ + +#ifndef GLIST_E_H +#define GLIST_E_H + +#include +#include // ṩ mallocreallocfreeexit ԭ +#include "Status.h" //**01 **// +#include "SString.h" //**04 **// + +/* ԭԪ */ +typedef char AtomType; //ԭ + +/* + * + * + * Atom-0ԭӽ + * List-1 + */ +typedef enum { Atom, List } ElemTag; + +/* չ洢ʾͶ */ +typedef struct GLNode { + ElemTag tag; // ǣԭӽͱ + + // ԭӽͱϲ + union + { + AtomType atom; // atomԭӽֵAtomTypeû + struct GLNode* hp; // ָͷ + } Node; + struct GLNode* tp; // ָβ +} GLNode; + +/* */ +typedef GLNode* GList; + + +/* + * ʼ + * + * ʼյĹΪ0Ϊ1 + * + *ע + * Ҫÿһſ + */ +Status InitGList(GList* L); + +/* + * + * + * ַSL + */ +Status CreateGList(GList* L, SString S); + +/* + * + * + * ͷŹռڴ档 + */ +Status DestroyGList(GList* L); + +/* + * + * + * ɹLƵõT + */ +Status CopyGList(GList* T, GList L); + +/* + * + * + * عijȡ + */ +int GListLength(GList L); + +/* + * + * + * ع + */ +int GListDepth(GList L); + +/* + * п + * + * жϹǷΪա + */ +Status GListEmpty(GList L); + +/* + * ͷ + */ +GList GetHead(GList L); + +/* + * β + */ +GList GetTail(GList L); + +/* + * + * + * ԪeΪLĵһԪء + */ +Status InsertFirst(GList* L, GList e); + +/* + * ɾ + * + * LĵһԪɾeء + */ +Status DeleteFirst(GList* L, GList* e); + +/* + * + * + * visitʹL + */ +void Traverse(GList L, void(Visit)(AtomType)); + +/* + * ͼλ + * + * L + */ +void PrintGraph(GList L); + +/* + * ͼλڲʵ֡ + */ +static void Print(GList L); + +/* + * ǿմstrָ֣hsubΪһ','֮ǰӴstrΪһ','֮Ӵ + * + *ע + * 1.ַstrȷ޿հ׷ţ + * strſȥҲδȥ + * 2.ɺstrҲᷢ仯 + */ +static void sever(SString hstr, SString str); + +#endif diff --git a/Dev-C++/ExerciseBook/05.37.2/SString.cpp b/Dev-C++/ExerciseBook/05.37.2/SString.cpp new file mode 100644 index 0000000..7a96fcf --- /dev/null +++ b/Dev-C++/ExerciseBook/05.37.2/SString.cpp @@ -0,0 +1,195 @@ +/*============================= + * Ķ˳洢ʾ˳򴮣 + * + * 㷨: 4.14.24.34.5 + ==============================*/ + +#include "SString.h" //**04 **// + +/* + * ʼ + * + * һֵΪcharsĴT + * + *ע + * òСӼ + */ +Status StrAssign(SString T, const char* chars) { + int i, len; + + len = (int) strlen(chars); + + // chars + if(len > MAXSTRLEN) { + return ERROR; + } + + T[0] = len; + for(i = 1; i <= len; i++) { + T[i] = chars[i - 1]; + } + + return OK; +} + +/* + * + * + * Sա + */ +Status ClearString(SString S) { + // ֻҪΪ0Ϳ + S[0] = 0; + return OK; +} + +/* + * п + * + * жϴSǷЧݡ + * + * ֵ + * TRUE : SΪ + * FALSE: SΪ + */ +Status StrEmpty(SString S) { + return S[0] == 0 ? TRUE : FALSE; +} + +/* + * + * + * شSԪصĸ + * + *ע + * òСӼ + */ +int StrLength(SString S) { + return S[0]; +} + +/* + * 㷨4.3 + * + * Ӵ + * + * SubS[pos, pos+len-1] + * ֵָʾǷȡɹ + * + *ע + * òСӼ + */ +Status SubString(SString Sub, SString S, int pos, int len) { + int i; + + if(pos < 1 || pos > S[0] || len < 0 || pos + len - 1 > S[0]) { + return ERROR; + } + + // Ԫ + for(i = 1; i <= len; i++) { + Sub[i] = S[pos + i - 1]; + } + + // ȷ³ + Sub[0] = len; + + return OK; +} + +/* + * ɾ + * + * ɾS[pos, pos+len-1] + */ +Status StrDelete(SString S, int pos, int len) { + int i; + + if(pos < 1 || pos + len - 1 > S[0] || len < 0) { + return ERROR; + } + + // ɾijΪ0ǰ + if(len == 0) { + return OK; + } + + // ѺԪŲǰ棬ǵɾԪ + for(i = pos + len; i <= S[0]; i++) { + S[i - len] = S[i]; + } + + // ȼ + S[0] -= len; + + return OK; +} + +/* + * Ƚ + * + * ȽϴSʹTرȽϽ + * + *ע + * òСӼ + */ +int StrCompare(SString S, SString T) { + int i = 1; + + while(i <= S[0] && i <= T[0]) { + // ַͬʱȽС + if(S[i] != T[i]) { + return S[i] - T[i]; + } + + i++; + } + + return S[0] - T[0]; +} + +/* + * + * + * SƵT + */ +Status StrCopy(SString T, SString S) { + int i; + + // ͬϢһ + for(i = 0; i <= S[0]; i++) { + T[i] = S[i]; + } + + return OK; +} + +/* + * ַSеĿհףɴӡַո + * + *ע + * úڱġ + */ +Status ClearBlank(SString S) { + int i, j; + + // ǿմ + if(S[0] == 0) { + return ERROR; + } + + for(i = 1, j = 0; i <= S[0]; i++) { + // հףԹ + if(S[i] == ' ' || !isprint(S[i])) { + continue; + } + + j++; + + S[j] = S[i]; + } + + S[0] = j; + + return OK; +} diff --git a/Dev-C++/ExerciseBook/05.37.2/SString.h b/Dev-C++/ExerciseBook/05.37.2/SString.h new file mode 100644 index 0000000..0632f18 --- /dev/null +++ b/Dev-C++/ExerciseBook/05.37.2/SString.h @@ -0,0 +1,117 @@ +/*============================= + * Ķ˳洢ʾ˳򴮣 + * + * 㷨: 4.14.24.34.5 + ==============================*/ + +#ifndef SSTRING_H +#define SSTRING_H + +#include +#include // ṩ strlen ԭ +#include // ṩ isprint ԭ +#include "Status.h" //**01 **// + +/* 궨 */ +#define MAXSTRLEN 255 // ˳򴮵󴮳 + +/* + * ˳洢Ͷ + * + * עЧԪشSString1ŵԪʼ洢 + * SString0ŵԪ洢䳤 + */ +typedef unsigned char SString[MAXSTRLEN + 1]; // 0ŵԪŴij + + +/* + * ʾ + * + * ѭ̲ĵдϰߣposָʾַλ()1ʼ + */ + + +/* + * ʼ + * + * һֵΪcharsĴT + * + *ע + * òСӼ + */ +Status StrAssign(SString T, const char* chars); + +/* + * + * + * Sա + */ +Status ClearString(SString S); + +/* + * п + * + * жϴSǷЧݡ + * + * ֵ + * TRUE : SΪ + * FALSE: SΪ + */ +Status StrEmpty(SString S); + +/* + * + * + * شSԪصĸ + * + *ע + * òСӼ + */ +int StrLength(SString S); + +/* + * 㷨4.3 + * + * Ӵ + * + * SubS[pos, pos+len-1] + * ֵָʾǷȡɹ + * + *ע + * òСӼ + */ +Status SubString(SString Sub, SString S, int pos, int len); + +/* + * ɾ + * + * ɾS[pos, pos+len-1] + */ +Status StrDelete(SString S, int pos, int len); + +/* + * Ƚ + * + * ȽϴSʹTرȽϽ + * + *ע + * òСӼ + */ +int StrCompare(SString S, SString T); + +/* + * + * + * SƵT + */ +Status StrCopy(SString T, SString S); + +/* + * ַSеĿհףɴӡַո + * + *ע + * úڱġ + */ +Status ClearBlank(SString S); + +#endif diff --git a/Dev-C++/ExerciseBook/05.38.1/05.38.1.cpp b/Dev-C++/ExerciseBook/05.38.1/05.38.1.cpp new file mode 100644 index 0000000..c41ea76 --- /dev/null +++ b/Dev-C++/ExerciseBook/05.38.1/05.38.1.cpp @@ -0,0 +1,47 @@ +#include +#include "SString.h" //**04 **// +#include "GList-HT.h" //**05 ͹**// + +/* + * еlԭ(ͷβ洢ʾ) + */ +void Algo_5_38_1(GList L, int d, int l); + + +int main(int argc, char* argv[]) { + GList L; + char* s = "((a),(b),(c,(d,e,f)),(g,((h),i)))"; + SString S; + + printf(" L ...\n"); + StrAssign(S, s); + CreateGList(&L, S); + printf("L = "); + PrintGraph(L); + + printf(" 2 ԭΪ"); + Algo_5_38_1(L, 0, 2); + printf("\n"); + + return 0; +} + + +/* + * еlԭ(ͷβ洢ʾ) + */ +void Algo_5_38_1(GList L, int d, int l) { + int i = d; // dijֵֵΪ0 + + if(L && l >= i) { + if(L->tag == Atom) { + // + if(l == i) { + printf("%c ", L->Node.atom); + } + } else { + Algo_5_38_1(L->Node.ptr.hp, i + 1, l); // ͷָָĻһ + Algo_5_38_1(L->Node.ptr.tp, i, l); + } + } +} diff --git a/Dev-C++/ExerciseBook/05.38.1/05.38.1.dev b/Dev-C++/ExerciseBook/05.38.1/05.38.1.dev new file mode 100644 index 0000000..1fd4a1c --- /dev/null +++ b/Dev-C++/ExerciseBook/05.38.1/05.38.1.dev @@ -0,0 +1,102 @@ +[Project] +FileName=05.38.1.dev +Name=05.38.1 +Type=1 +Ver=2 +ObjFiles= +Includes= +Libs= +PrivateResource= +ResourceIncludes= +MakeIncludes= +Compiler= +CppCompiler= +Linker= +IsCpp=0 +Icon= +ExeOutput= +ObjectOutput= +LogOutput= +LogOutputEnabled=0 +OverrideOutput=0 +OverrideOutputName= +HostApplication= +UseCustomMakefile=0 +CustomMakefile= +CommandLine= +Folders= +IncludeVersionInfo=0 +SupportXPThemes=0 +CompilerSet=1 +CompilerSettings=0000000000000000001000000 +UnitCount=5 + +[VersionInfo] +Major=1 +Minor=0 +Release=0 +Build=0 +LanguageID=1033 +CharsetID=1252 +CompanyName= +FileVersion= +FileDescription=Developed using the Dev-C++ IDE +InternalName= +LegalCopyright= +LegalTrademarks= +OriginalFilename= +ProductName= +ProductVersion= +AutoIncBuildNr=0 +SyncProduct=1 + +[Unit4] +FileName=SString.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit2] +FileName=GList-HT.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit1] +FileName=05.38.1.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit3] +FileName=GList-HT.h +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit5] +FileName=SString.h +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + diff --git a/Dev-C++/ExerciseBook/05.38.1/GList-HT.cpp b/Dev-C++/ExerciseBook/05.38.1/GList-HT.cpp new file mode 100644 index 0000000..bad30df --- /dev/null +++ b/Dev-C++/ExerciseBook/05.38.1/GList-HT.cpp @@ -0,0 +1,418 @@ +/*============================ + * ͷβ洢ʾ + * + * 㷨: 5.55.65.75.8 + =============================*/ + +#include "GList-HT.h" //**05 ͹**// + +/* + * ʼ + * + * ʼյĹΪ0Ϊ1 + * + *ע + * Ҫÿһȥſ + */ +Status InitGList(GList* L) { + if(L == NULL) { + return ERROR; + } + + *L = NULL; + + return OK; +} + +/* + * 㷨5.7 + * + * + * + * ַSL + */ +Status CreateGList(GList* L, SString S) { + SString emp; // չַ + SString hsub, sub; + GList p, q; + + if(L == NULL) { + return ERROR; + } + + // ַSеĿհףɴӡַո + ClearBlank(S); + + if(StrEmpty(S)) { + return ERROR; + } + + StrAssign(emp, "()"); + + /* + * 봮Ϊ()ҪյĹ + * + *ע + * ̲Ĵġ + * StrCompareķֵָʾַĴСָʾַǷȡ + * S()ȣֵӦ0 + */ + if(!StrCompare(S, emp)) { + *L = NULL; + } else { + *L = (GList) malloc(sizeof(GLNode)); + if(*L == NULL) { + exit(OVERFLOW); + } + + // ԭ + if(StrLength(S) == 1) { + (*L)->tag = Atom; + (*L)->Node.atom = S[1]; + } else { + (*L)->tag = List; + + p = *L; + + // ȥ + SubString(sub, S, 2, StrLength(S) - 2); + + // ظnӱ + do { + // subзͷhsubɺsubҲᷢ仯 + sever(hsub, sub); + + // ݹ鴴 + CreateGList(&(p->Node.ptr.hp), hsub); + + q = p; + + // βΪգҪβ + if(!StrEmpty(sub)) { + p = (GList) malloc(sizeof(GLNode)); + if(p == NULL) { + exit(OVERFLOW); + } + + p->tag = List; + + q->Node.ptr.tp = p; + } + } while(!StrEmpty(sub)); + + q->Node.ptr.tp = NULL; + } + } + + return OK; +} + +/* + * + * + * ͷŹռڴ档 + */ +Status DestroyGList(GList* L) { + GList head, tail; + + if(L == NULL || *L == NULL) { + return ERROR; + } + + // ɾԭӽ + if((*L)->tag == Atom) { + free(*L); + *L = NULL; + + // ɾӱ + } else { + head = (*L)->Node.ptr.hp; + tail = (*L)->Node.ptr.tp; + free(*L); + *L = NULL; + DestroyGList(&head); + DestroyGList(&tail); + } + + return OK; +} + +/* + * 㷨5.6 + * + * + * + * ɹLƵõT + */ +Status CopyGList(GList* T, GList L) { + if(T == NULL) { + return ERROR; + } + + if(L == NULL) { + *T = NULL; + } else { + // ½ + *T = (GList) malloc(sizeof(GLNode)); + if(*T == NULL) { + exit(OVERFLOW); + } + + (*T)->tag = L->tag; + + // Ƶԭ + if(L->tag == Atom) { + (*T)->Node.atom = L->Node.atom; + + // Ʊͷͱβ + } else { + CopyGList(&((*T)->Node.ptr.hp), L->Node.ptr.hp); + CopyGList(&((*T)->Node.ptr.tp), L->Node.ptr.tp); + } + } + + return OK; +} + +/* + * + * + * عijȡ + */ +int GListLength(GList L) { + int count; + + for(count = 0; L != NULL; count++, L = L->Node.ptr.tp) { + } + + return count; +} + +/* + * 㷨5.5 + * + * + * + * ع + */ +int GListDepth(GList L) { + int max, deep; + GList p; + + // ձΪ1 + if(L == NULL) { + return 1; + } + + // ԭΪ0 + if(L->tag == Atom) { + return 0; + } + + // ݹӱ + for(max = 0, p = L; p != NULL; p = p->Node.ptr.tp) { + deep = GListDepth(p->Node.ptr.hp); + if(deep > max) { + max = deep; + } + } + + // ǿձǸԪȼһ + return max + 1; +} + +/* + * п + * + * жϹǷΪա + */ +Status GListEmpty(GList L) { + return L == NULL ? TRUE : FALSE; +} + +/* + * ͷ + */ +GList GetHead(GList L) { + GList p; + + // ձޱͷﲻܷNULLȻֲʧ˻Ƿ˿ձ + if(L == NULL) { + exit(ERROR); + } + + CopyGList(&p, L->Node.ptr.hp); + + return p; +} + +/* + * β + */ +GList GetTail(GList L) { + GList p; + + // ձޱβﲻܷNULLȻֲʧ˻Ƿ˿ձ + if(L == NULL) { + exit(ERROR); + } + + CopyGList(&p, L->Node.ptr.tp); + + return p; +} + +/* + * + * + * ԪeΪLĵһԪء + */ +Status InsertFirst(GList* L, GList e) { + GList g; + + if(L == NULL) { + return ERROR; + } + + g = (GList) malloc(sizeof(GLNode)); + if(g == NULL) { + exit(OVERFLOW); + } + + g->tag = List; + g->Node.ptr.hp = e; + g->Node.ptr.tp = *L; + *L = g; + + return OK; +} + +/* + * ɾ + * + * LĵһԪɾeء + */ +Status DeleteFirst(GList* L, GList* e) { + GList p; + + // ձ޷ɾ + if(L == NULL || *L == NULL) { + return ERROR; + } + + p = *L; + *L = (*L)->Node.ptr.tp; + + CopyGList(e, p->Node.ptr.hp); + + free(p); + + return OK; +} + +/* + * + * + * visitʹL + */ +void Traverse(GList L, void(Visit)(AtomType)) { + + if(L == NULL) { + return; + } + + if(L->tag == Atom) { + Visit(L->Node.atom); + } else { + Traverse(L->Node.ptr.hp, Visit); + Traverse(L->Node.ptr.tp, Visit); + } + +} + +/* + * ͼλ + * + * L + */ +void PrintGraph(GList L) { + Print(L, Head); + printf("\n"); +} + +/* + * ͼλڲʵ֣markͼλǡ + */ +static void Print(GList L, Mark mark) { + // LΪ + if(L == NULL) { + if(mark == Head) { + printf("("); + } + + printf(")"); + + // LΪʱ + } else { + // ԭӽ㣬ԭ + if(L->tag == Atom) { + printf("%c", L->Node.atom); + + // ӱ㣬ҪԱͷβֱ + } else { + if(mark == Head) { + printf("("); + } else { + printf(","); + } + + Print(L->Node.ptr.hp, Head); + Print(L->Node.ptr.tp, Tail); + } + } +} + +/* + * 㷨5.8 + * + * ǿմstrָ֣hsubΪһ','֮ǰӴstrΪһ','֮Ӵ + * + *ע + * 1.ַstrȷ޿հ׷ţstrѾȥš + * 2.ɺstrҲᷢ仯 + */ +static void sever(SString hstr, SString str) { + int i, k, n; + SString ch; + + n = StrLength(str); + + i = 0; // ַʱα + k = 0; // δ + + do { + ++i; + + // ȡstrһַ + SubString(ch, str, i, 1); + + if(ch[1] == '(') { + ++k; + } + + if(ch[1] == ')') { + --k; + } + } while(i < n && (ch[1] != ',' || k != 0)); + + // ڶ + if(i < n) { + SubString(hstr, str, 1, i - 1); + SubString(str, str, i + 1, n - i); + + // ֻһ + } else { + StrCopy(hstr, str); + ClearString(str); + } +} diff --git a/Dev-C++/ExerciseBook/05.38.1/GList-HT.h b/Dev-C++/ExerciseBook/05.38.1/GList-HT.h new file mode 100644 index 0000000..508b96f --- /dev/null +++ b/Dev-C++/ExerciseBook/05.38.1/GList-HT.h @@ -0,0 +1,164 @@ +/*============================ + * ͷβ洢ʾ + * + * 㷨: 5.55.65.75.8 + =============================*/ + +#ifndef GLIST_HT_H +#define GLIST_HT_H + +#include +#include // ṩ mallocreallocfreeexit ԭ +#include "Status.h" //**01 **// +#include "SString.h" //**04 **// + +/* ԭԪ */ +typedef char AtomType; + +/* + * + * + * Atom-0ԭӽ + * List-1 + */ +typedef enum { Atom, List } ElemTag; + +/* ͷβ洢ʾͶ */ +typedef struct GLNode { + ElemTag tag; // ǣԭӽͱ + + // ԭӽͱϲ + union { + AtomType atom; // atomԭӽֵAtomTypeû + struct { + struct GLNode* hp; // ָͷ + struct GLNode* tp; // ָβ + } ptr; // ָ + } Node; +} GLNode; + +/* */ +typedef GLNode* GList; + +/* + * ͼλ + * + * HeadָԱͷ + * TailָԱβ + */ +typedef enum { Head, Tail } Mark; + + +/* + * ʼ + * + * ʼյĹΪ0Ϊ1 + * + *ע + * Ҫÿһȥſ + */ +Status InitGList(GList* L); + +/* + * 㷨5.7 + * + * + * + * ַSL + */ +Status CreateGList(GList* L, SString S); + +/* + * + * + * ͷŹռڴ档 + */ +Status DestroyGList(GList* L); + +/* + * 㷨5.6 + * + * + * + * ɹLƵõT + */ +Status CopyGList(GList* T, GList L); + +/* + * + * + * عijȡ + */ +int GListLength(GList L); + +/* + * 㷨5.5 + * + * + * + * ع + */ +int GListDepth(GList L); + +/* + * п + * + * жϹǷΪա + */ +Status GListEmpty(GList L); + +/* + * ͷ + */ +GList GetHead(GList L); + +/* + * β + */ +GList GetTail(GList L); + +/* + * + * + * ԪeΪLĵһԪء + */ +Status InsertFirst(GList* L, GList e); + +/* + * ɾ + * + * LĵһԪɾeء + */ +Status DeleteFirst(GList* L, GList* e); + +/* + * + * + * visitʹL + */ +void Traverse(GList L, void (Visit)(AtomType)); + +/* + * ͼλ + * + * L + */ +void PrintGraph(GList L); + +/* + * ͼλڲʵ֣markͼλǡ + */ +static void Print(GList L, Mark mark); + +/* + * 㷨5.8 + * + * ǿմstrָ֣hsubΪһ','֮ǰӴstrΪһ','֮Ӵ + * + *ע + * 1.ַstrȷ޿հ׷ţstrѾȥš + * 2.ɺstrҲᷢ仯 + */ +static void sever(SString hstr, SString str); + +#endif diff --git a/Dev-C++/ExerciseBook/05.38.1/SString.cpp b/Dev-C++/ExerciseBook/05.38.1/SString.cpp new file mode 100644 index 0000000..7a96fcf --- /dev/null +++ b/Dev-C++/ExerciseBook/05.38.1/SString.cpp @@ -0,0 +1,195 @@ +/*============================= + * Ķ˳洢ʾ˳򴮣 + * + * 㷨: 4.14.24.34.5 + ==============================*/ + +#include "SString.h" //**04 **// + +/* + * ʼ + * + * һֵΪcharsĴT + * + *ע + * òСӼ + */ +Status StrAssign(SString T, const char* chars) { + int i, len; + + len = (int) strlen(chars); + + // chars + if(len > MAXSTRLEN) { + return ERROR; + } + + T[0] = len; + for(i = 1; i <= len; i++) { + T[i] = chars[i - 1]; + } + + return OK; +} + +/* + * + * + * Sա + */ +Status ClearString(SString S) { + // ֻҪΪ0Ϳ + S[0] = 0; + return OK; +} + +/* + * п + * + * жϴSǷЧݡ + * + * ֵ + * TRUE : SΪ + * FALSE: SΪ + */ +Status StrEmpty(SString S) { + return S[0] == 0 ? TRUE : FALSE; +} + +/* + * + * + * شSԪصĸ + * + *ע + * òСӼ + */ +int StrLength(SString S) { + return S[0]; +} + +/* + * 㷨4.3 + * + * Ӵ + * + * SubS[pos, pos+len-1] + * ֵָʾǷȡɹ + * + *ע + * òСӼ + */ +Status SubString(SString Sub, SString S, int pos, int len) { + int i; + + if(pos < 1 || pos > S[0] || len < 0 || pos + len - 1 > S[0]) { + return ERROR; + } + + // Ԫ + for(i = 1; i <= len; i++) { + Sub[i] = S[pos + i - 1]; + } + + // ȷ³ + Sub[0] = len; + + return OK; +} + +/* + * ɾ + * + * ɾS[pos, pos+len-1] + */ +Status StrDelete(SString S, int pos, int len) { + int i; + + if(pos < 1 || pos + len - 1 > S[0] || len < 0) { + return ERROR; + } + + // ɾijΪ0ǰ + if(len == 0) { + return OK; + } + + // ѺԪŲǰ棬ǵɾԪ + for(i = pos + len; i <= S[0]; i++) { + S[i - len] = S[i]; + } + + // ȼ + S[0] -= len; + + return OK; +} + +/* + * Ƚ + * + * ȽϴSʹTرȽϽ + * + *ע + * òСӼ + */ +int StrCompare(SString S, SString T) { + int i = 1; + + while(i <= S[0] && i <= T[0]) { + // ַͬʱȽС + if(S[i] != T[i]) { + return S[i] - T[i]; + } + + i++; + } + + return S[0] - T[0]; +} + +/* + * + * + * SƵT + */ +Status StrCopy(SString T, SString S) { + int i; + + // ͬϢһ + for(i = 0; i <= S[0]; i++) { + T[i] = S[i]; + } + + return OK; +} + +/* + * ַSеĿհףɴӡַո + * + *ע + * úڱġ + */ +Status ClearBlank(SString S) { + int i, j; + + // ǿմ + if(S[0] == 0) { + return ERROR; + } + + for(i = 1, j = 0; i <= S[0]; i++) { + // հףԹ + if(S[i] == ' ' || !isprint(S[i])) { + continue; + } + + j++; + + S[j] = S[i]; + } + + S[0] = j; + + return OK; +} diff --git a/Dev-C++/ExerciseBook/05.38.1/SString.h b/Dev-C++/ExerciseBook/05.38.1/SString.h new file mode 100644 index 0000000..0632f18 --- /dev/null +++ b/Dev-C++/ExerciseBook/05.38.1/SString.h @@ -0,0 +1,117 @@ +/*============================= + * Ķ˳洢ʾ˳򴮣 + * + * 㷨: 4.14.24.34.5 + ==============================*/ + +#ifndef SSTRING_H +#define SSTRING_H + +#include +#include // ṩ strlen ԭ +#include // ṩ isprint ԭ +#include "Status.h" //**01 **// + +/* 궨 */ +#define MAXSTRLEN 255 // ˳򴮵󴮳 + +/* + * ˳洢Ͷ + * + * עЧԪشSString1ŵԪʼ洢 + * SString0ŵԪ洢䳤 + */ +typedef unsigned char SString[MAXSTRLEN + 1]; // 0ŵԪŴij + + +/* + * ʾ + * + * ѭ̲ĵдϰߣposָʾַλ()1ʼ + */ + + +/* + * ʼ + * + * һֵΪcharsĴT + * + *ע + * òСӼ + */ +Status StrAssign(SString T, const char* chars); + +/* + * + * + * Sա + */ +Status ClearString(SString S); + +/* + * п + * + * жϴSǷЧݡ + * + * ֵ + * TRUE : SΪ + * FALSE: SΪ + */ +Status StrEmpty(SString S); + +/* + * + * + * شSԪصĸ + * + *ע + * òСӼ + */ +int StrLength(SString S); + +/* + * 㷨4.3 + * + * Ӵ + * + * SubS[pos, pos+len-1] + * ֵָʾǷȡɹ + * + *ע + * òСӼ + */ +Status SubString(SString Sub, SString S, int pos, int len); + +/* + * ɾ + * + * ɾS[pos, pos+len-1] + */ +Status StrDelete(SString S, int pos, int len); + +/* + * Ƚ + * + * ȽϴSʹTرȽϽ + * + *ע + * òСӼ + */ +int StrCompare(SString S, SString T); + +/* + * + * + * SƵT + */ +Status StrCopy(SString T, SString S); + +/* + * ַSеĿհףɴӡַո + * + *ע + * úڱġ + */ +Status ClearBlank(SString S); + +#endif diff --git a/Dev-C++/ExerciseBook/05.38.2/05.38.2.cpp b/Dev-C++/ExerciseBook/05.38.2/05.38.2.cpp new file mode 100644 index 0000000..ed3096f --- /dev/null +++ b/Dev-C++/ExerciseBook/05.38.2/05.38.2.cpp @@ -0,0 +1,48 @@ +#include +#include "SString.h" //**04 **// +#include "GList-E.h" //**05 ͹**// + +/* + * еlԭ(չ洢ʾ) + */ +void Algo_5_38_2(GList L, int d, int l); + + +int main(int argc, char* argv[]) { + GList L; + char* s = "((a),(b),(c,(d,e,f)),(g,((h),i)))"; + SString S; + + printf(" L ...\n"); + StrAssign(S, s); + CreateGList(&L, S); + printf("L = "); + PrintGraph(L); + + printf(" 2 ԭΪ"); + Algo_5_38_2(L, 0, 2); + printf("\n"); + + return 0; +} + + +/* + * еlԭ(չ洢ʾ) + */ +void Algo_5_38_2(GList L, int d, int l) { + int i = d; // dijֵֵΪ0 + + if(L && l >= i) { + if(L->tag == Atom) { + // + if(l == i) { + printf("%c ", L->Node.atom); + } + } else { + Algo_5_38_2(L->Node.hp, i + 1, l); // ͷָָĻһ + } + + Algo_5_38_2(L->tp, i, l); + } +} diff --git a/Dev-C++/ExerciseBook/05.38.2/05.38.2.dev b/Dev-C++/ExerciseBook/05.38.2/05.38.2.dev new file mode 100644 index 0000000..f454314 --- /dev/null +++ b/Dev-C++/ExerciseBook/05.38.2/05.38.2.dev @@ -0,0 +1,102 @@ +[Project] +FileName=05.38.2.dev +Name=05.38.2 +Type=1 +Ver=2 +ObjFiles= +Includes= +Libs= +PrivateResource= +ResourceIncludes= +MakeIncludes= +Compiler= +CppCompiler= +Linker= +IsCpp=0 +Icon= +ExeOutput= +ObjectOutput= +LogOutput= +LogOutputEnabled=0 +OverrideOutput=0 +OverrideOutputName= +HostApplication= +UseCustomMakefile=0 +CustomMakefile= +CommandLine= +Folders= +IncludeVersionInfo=0 +SupportXPThemes=0 +CompilerSet=1 +CompilerSettings=0000000000000000001000000 +UnitCount=5 + +[VersionInfo] +Major=1 +Minor=0 +Release=0 +Build=0 +LanguageID=1033 +CharsetID=1252 +CompanyName= +FileVersion= +FileDescription=Developed using the Dev-C++ IDE +InternalName= +LegalCopyright= +LegalTrademarks= +OriginalFilename= +ProductName= +ProductVersion= +AutoIncBuildNr=0 +SyncProduct=1 + +[Unit4] +FileName=SString.h +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit1] +FileName=05.38.2.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit5] +FileName=GList-E.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit2] +FileName=GList-E.h +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit3] +FileName=SString.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + diff --git a/Dev-C++/ExerciseBook/05.38.2/GList-E.cpp b/Dev-C++/ExerciseBook/05.38.2/GList-E.cpp new file mode 100644 index 0000000..3fc0ad9 --- /dev/null +++ b/Dev-C++/ExerciseBook/05.38.2/GList-E.cpp @@ -0,0 +1,449 @@ +/*=========================== + * չ洢ʾ + ============================*/ + +#include "GList-E.h" //**05 ͹**// + +/* + * ʼ + * + * ʼյĹΪ0Ϊ1 + * + *ע + * Ҫÿһſ + */ +Status InitGList(GList* L) { + if(L == NULL) { + return ERROR; + } + + *L = (GList) malloc(sizeof(GLNode)); + if(!*L) { + exit(OVERFLOW); + } + + (*L)->tag = List; + (*L)->Node.hp = NULL; + (*L)->tp = NULL; + + return OK; +} + +/* + * + * + * ַSL + */ +Status CreateGList(GList* L, SString S) { + SString emp, hsub, sub, tmp; + + if(L == NULL) { + return ERROR; + } + + // ַSеĿհףɴӡַո + ClearBlank(S); + + if(StrEmpty(S)) { + return ERROR; + } + + // Ϊ˲ƻS + StrCopy(sub, S); + + /* + * ִеʱ + * ٴִеʱѾȥ + */ + sever(hsub, sub); + + *L = (GList) malloc(sizeof(GLNode)); + if(*L == NULL) { + exit(OVERFLOW); + } + + StrAssign(emp, "()"); + + if(!StrCompare(hsub, emp)) { + (*L)->tag = List; + (*L)->Node.hp = NULL; + } else { + if(StrLength(hsub) == 1) { + (*L)->tag = Atom; + (*L)->Node.atom = hsub[1]; + } else { + (*L)->tag = List; + + SubString(tmp, hsub, 2, StrLength(hsub) - 2); + + CreateGList(&((*L)->Node.hp), tmp); + } + } + + // ڶβ˳ݹ + if(StrEmpty(sub)) { + (*L)->tp = NULL; + } else { + // ݹβ + CreateGList(&((*L)->tp), sub); + } + + return OK; +} + +/* + * + * + * ͷŹռڴ档 + */ +Status DestroyGList(GList* L) { + GList head, tail; + + if(L == NULL || *L == NULL) { + return ERROR; + } + + // ӱ + if((*L)->tag == List) { + head = (*L)->Node.hp; // ͷ + tail = (*L)->tp; // β + + free(*L); + *L = NULL; + + // ݹ鴦ͷ + if(head != NULL) { + DestroyGList(&head); + } + + // ݹ鴦β + if(tail != NULL) { + DestroyGList(&tail); + } + + // ԭӽ + } else { + tail = (*L)->tp; // β + + free(*L); + *L = NULL; + + if(tail != NULL) { + DestroyGList(&tail); + } + } + + return OK; +} + +/* + * + * + * ɹLƵõT + */ +Status CopyGList(GList* T, GList L) { + + if(L == NULL) { + return ERROR; + } + + *T = (GList) malloc(sizeof(GLNode)); + if(*T == NULL) { + exit(OVERFLOW); + } + + // ԭ + if(L->tag == Atom) { + (*T)->tag = Atom; + (*T)->Node.atom = L->Node.atom; + + // ӱ + } else { + (*T)->tag = List; + + // Ʊͷ + if(L->Node.hp != NULL) { + CopyGList(&((*T)->Node.hp), L->Node.hp); + } else { + (*T)->Node.hp = NULL; + } + } + + // Ʊβ + if(L->tp != NULL) { + CopyGList(&((*T)->tp), L->tp); + } else { + (*T)->tp = NULL; + } + + return OK; +} + +/* + * + * + * عijȡ + */ +int GListLength(GList L) { + int count = 0; + GList p; + + // + if(L == NULL) { + return -1; + } + + p = L->Node.hp; + + while(p != NULL) { + ++count; + p = p->tp; + } + + return count; +} + +/* + * + * + * ع + */ +int GListDepth(GList L) { + int max, deep; + GList p; + + max = 0; + + // + if(L == NULL) { + return -1; + } + + // ձΪ1 + if(L->tag == List && !L->Node.hp) { + return 1; + } + + // ԭΪ0 + if(L->tag == Atom) { + return 0; + } + + // ݹӱ + for(p = L->Node.hp; p != NULL; p = p->tp) { + // pΪͷָӱ + deep = GListDepth(p); + if(deep > max) { + max = deep; + } + } + + return max + 1; +} + +/* + * п + * + * жϹǷΪա + */ +Status GListEmpty(GList L) { + // + if(L == NULL) { + return ERROR; + } + + if(L->tag == List && L->Node.hp == NULL && L->tp == NULL) { + return TRUE; + } else { + return ERROR; + } +} + +/* + * ͷ + */ +GList GetHead(GList L) { + GList p, q; + + // ڻΪձ޷ȡͷ + if(L == NULL || L->Node.hp == NULL) { + return NULL; + } + + q = L->Node.hp->tp; // ʱLıβϢ + L->Node.hp->tp = NULL; // ȥLıβ + + CopyGList(&p, L->Node.hp); // ƱͷϢαβ + + L->Node.hp->tp = q; // ָLıβϢ + + return p; +} + +/* + * β + */ +GList GetTail(GList L) { + GList p, q; + + // ڻΪձ޷ȡβ + if(L == NULL || L->Node.hp == NULL) { + return NULL; + } + + q = L->Node.hp; // ʱLıͷϢ + L->Node.hp = q->tp; // ժLıͷ + + CopyGList(&p, L); // ƱβϢαͷ + + q->tp = L->Node.hp; // ָLıͷϢ + L->Node.hp = q; + + return p; +} + +/* + * + * + * ԪeΪLĵһԪء + */ +Status InsertFirst(GList* L, GList e) { + + // + if(L == NULL || *L == NULL) { + return ERROR; + } + + if(e == NULL) { + return ERROR; + } + + e->tp = (*L)->Node.hp; + (*L)->Node.hp = e; + + return OK; +} + +/* + * ɾ + * + * LĵһԪɾeء + */ +Status DeleteFirst(GList* L, GList* e) { + GList p; + + // ڻΪձ޷ɾͷ + if(*L == NULL || (*L)->Node.hp == NULL) { + return ERROR; + } + + p = (*L)->Node.hp; + (*L)->Node.hp = p->tp; + p->tp = NULL; + + *e = p; + + return OK; +} + +/* + * + * + * visitʹL + */ +void Traverse(GList L, void(Visit)(AtomType)) { + if(L == NULL) { + return; + } + + if(L->tag == List) { + Traverse(L->Node.hp, Visit); + } else { + Visit(L->Node.atom); + } + + Traverse(L->tp, Visit); +} + +/* + * ͼλ + * + * L + */ +void PrintGraph(GList L) { + Print(L); + printf("\n"); +} + +/* + * ͼλڲʵ֡ + */ +static void Print(GList L) { + if(L == NULL) { + return; + } + + // + if(L->tag == List) { + printf("("); + + if(L->Node.hp) { + Print(L->Node.hp); + } + + if(L->tp) { + printf("),"); + Print(L->tp); + } else { + printf(")"); + } + + // ԭӽ + } else { + printf("%c", L->Node.atom); + if(L->tp) { + printf(","); + Print(L->tp); + } + } +} + +/* + * ǿմstrָ֣hsubΪһ','֮ǰӴstrΪһ','֮Ӵ + * + *ע + * 1.ַstrȷ޿հ׷ţ + * strſȥҲδȥ + * 2.ɺstrҲᷢ仯 + */ +static void sever(SString hstr, SString str) { + int i, k, n; + SString ch; + + n = StrLength(str); + + i = 0; // ַʱα + k = 0; // δ + + do { + ++i; + + // ȡstrһַ + SubString(ch, str, i, 1); + + if(ch[1] == '(') { + ++k; + } + if(ch[1] == ')') { + --k; + } + } while(i < n && (ch[1] != ',' || k != 0)); + + if(i < n) { + SubString(hstr, str, 1, i - 1); + SubString(str, str, i + 1, n - i); + } else { + StrCopy(hstr, str); + ClearString(str); + } +} diff --git a/Dev-C++/ExerciseBook/05.38.2/GList-E.h b/Dev-C++/ExerciseBook/05.38.2/GList-E.h new file mode 100644 index 0000000..fa9af82 --- /dev/null +++ b/Dev-C++/ExerciseBook/05.38.2/GList-E.h @@ -0,0 +1,146 @@ +/*=========================== + * չ洢ʾ + ============================*/ + +#ifndef GLIST_E_H +#define GLIST_E_H + +#include +#include // ṩ mallocreallocfreeexit ԭ +#include "Status.h" //**01 **// +#include "SString.h" //**04 **// + +/* ԭԪ */ +typedef char AtomType; //ԭ + +/* + * + * + * Atom-0ԭӽ + * List-1 + */ +typedef enum { Atom, List } ElemTag; + +/* չ洢ʾͶ */ +typedef struct GLNode { + ElemTag tag; // ǣԭӽͱ + + // ԭӽͱϲ + union + { + AtomType atom; // atomԭӽֵAtomTypeû + struct GLNode* hp; // ָͷ + } Node; + struct GLNode* tp; // ָβ +} GLNode; + +/* */ +typedef GLNode* GList; + + +/* + * ʼ + * + * ʼյĹΪ0Ϊ1 + * + *ע + * Ҫÿһſ + */ +Status InitGList(GList* L); + +/* + * + * + * ַSL + */ +Status CreateGList(GList* L, SString S); + +/* + * + * + * ͷŹռڴ档 + */ +Status DestroyGList(GList* L); + +/* + * + * + * ɹLƵõT + */ +Status CopyGList(GList* T, GList L); + +/* + * + * + * عijȡ + */ +int GListLength(GList L); + +/* + * + * + * ع + */ +int GListDepth(GList L); + +/* + * п + * + * жϹǷΪա + */ +Status GListEmpty(GList L); + +/* + * ͷ + */ +GList GetHead(GList L); + +/* + * β + */ +GList GetTail(GList L); + +/* + * + * + * ԪeΪLĵһԪء + */ +Status InsertFirst(GList* L, GList e); + +/* + * ɾ + * + * LĵһԪɾeء + */ +Status DeleteFirst(GList* L, GList* e); + +/* + * + * + * visitʹL + */ +void Traverse(GList L, void(Visit)(AtomType)); + +/* + * ͼλ + * + * L + */ +void PrintGraph(GList L); + +/* + * ͼλڲʵ֡ + */ +static void Print(GList L); + +/* + * ǿմstrָ֣hsubΪһ','֮ǰӴstrΪһ','֮Ӵ + * + *ע + * 1.ַstrȷ޿հ׷ţ + * strſȥҲδȥ + * 2.ɺstrҲᷢ仯 + */ +static void sever(SString hstr, SString str); + +#endif diff --git a/Dev-C++/ExerciseBook/05.38.2/SString.cpp b/Dev-C++/ExerciseBook/05.38.2/SString.cpp new file mode 100644 index 0000000..7a96fcf --- /dev/null +++ b/Dev-C++/ExerciseBook/05.38.2/SString.cpp @@ -0,0 +1,195 @@ +/*============================= + * Ķ˳洢ʾ˳򴮣 + * + * 㷨: 4.14.24.34.5 + ==============================*/ + +#include "SString.h" //**04 **// + +/* + * ʼ + * + * һֵΪcharsĴT + * + *ע + * òСӼ + */ +Status StrAssign(SString T, const char* chars) { + int i, len; + + len = (int) strlen(chars); + + // chars + if(len > MAXSTRLEN) { + return ERROR; + } + + T[0] = len; + for(i = 1; i <= len; i++) { + T[i] = chars[i - 1]; + } + + return OK; +} + +/* + * + * + * Sա + */ +Status ClearString(SString S) { + // ֻҪΪ0Ϳ + S[0] = 0; + return OK; +} + +/* + * п + * + * жϴSǷЧݡ + * + * ֵ + * TRUE : SΪ + * FALSE: SΪ + */ +Status StrEmpty(SString S) { + return S[0] == 0 ? TRUE : FALSE; +} + +/* + * + * + * شSԪصĸ + * + *ע + * òСӼ + */ +int StrLength(SString S) { + return S[0]; +} + +/* + * 㷨4.3 + * + * Ӵ + * + * SubS[pos, pos+len-1] + * ֵָʾǷȡɹ + * + *ע + * òСӼ + */ +Status SubString(SString Sub, SString S, int pos, int len) { + int i; + + if(pos < 1 || pos > S[0] || len < 0 || pos + len - 1 > S[0]) { + return ERROR; + } + + // Ԫ + for(i = 1; i <= len; i++) { + Sub[i] = S[pos + i - 1]; + } + + // ȷ³ + Sub[0] = len; + + return OK; +} + +/* + * ɾ + * + * ɾS[pos, pos+len-1] + */ +Status StrDelete(SString S, int pos, int len) { + int i; + + if(pos < 1 || pos + len - 1 > S[0] || len < 0) { + return ERROR; + } + + // ɾijΪ0ǰ + if(len == 0) { + return OK; + } + + // ѺԪŲǰ棬ǵɾԪ + for(i = pos + len; i <= S[0]; i++) { + S[i - len] = S[i]; + } + + // ȼ + S[0] -= len; + + return OK; +} + +/* + * Ƚ + * + * ȽϴSʹTرȽϽ + * + *ע + * òСӼ + */ +int StrCompare(SString S, SString T) { + int i = 1; + + while(i <= S[0] && i <= T[0]) { + // ַͬʱȽС + if(S[i] != T[i]) { + return S[i] - T[i]; + } + + i++; + } + + return S[0] - T[0]; +} + +/* + * + * + * SƵT + */ +Status StrCopy(SString T, SString S) { + int i; + + // ͬϢһ + for(i = 0; i <= S[0]; i++) { + T[i] = S[i]; + } + + return OK; +} + +/* + * ַSеĿհףɴӡַո + * + *ע + * úڱġ + */ +Status ClearBlank(SString S) { + int i, j; + + // ǿմ + if(S[0] == 0) { + return ERROR; + } + + for(i = 1, j = 0; i <= S[0]; i++) { + // հףԹ + if(S[i] == ' ' || !isprint(S[i])) { + continue; + } + + j++; + + S[j] = S[i]; + } + + S[0] = j; + + return OK; +} diff --git a/Dev-C++/ExerciseBook/05.38.2/SString.h b/Dev-C++/ExerciseBook/05.38.2/SString.h new file mode 100644 index 0000000..0632f18 --- /dev/null +++ b/Dev-C++/ExerciseBook/05.38.2/SString.h @@ -0,0 +1,117 @@ +/*============================= + * Ķ˳洢ʾ˳򴮣 + * + * 㷨: 4.14.24.34.5 + ==============================*/ + +#ifndef SSTRING_H +#define SSTRING_H + +#include +#include // ṩ strlen ԭ +#include // ṩ isprint ԭ +#include "Status.h" //**01 **// + +/* 궨 */ +#define MAXSTRLEN 255 // ˳򴮵󴮳 + +/* + * ˳洢Ͷ + * + * עЧԪشSString1ŵԪʼ洢 + * SString0ŵԪ洢䳤 + */ +typedef unsigned char SString[MAXSTRLEN + 1]; // 0ŵԪŴij + + +/* + * ʾ + * + * ѭ̲ĵдϰߣposָʾַλ()1ʼ + */ + + +/* + * ʼ + * + * һֵΪcharsĴT + * + *ע + * òСӼ + */ +Status StrAssign(SString T, const char* chars); + +/* + * + * + * Sա + */ +Status ClearString(SString S); + +/* + * п + * + * жϴSǷЧݡ + * + * ֵ + * TRUE : SΪ + * FALSE: SΪ + */ +Status StrEmpty(SString S); + +/* + * + * + * شSԪصĸ + * + *ע + * òСӼ + */ +int StrLength(SString S); + +/* + * 㷨4.3 + * + * Ӵ + * + * SubS[pos, pos+len-1] + * ֵָʾǷȡɹ + * + *ע + * òСӼ + */ +Status SubString(SString Sub, SString S, int pos, int len); + +/* + * ɾ + * + * ɾS[pos, pos+len-1] + */ +Status StrDelete(SString S, int pos, int len); + +/* + * Ƚ + * + * ȽϴSʹTرȽϽ + * + *ע + * òСӼ + */ +int StrCompare(SString S, SString T); + +/* + * + * + * SƵT + */ +Status StrCopy(SString T, SString S); + +/* + * ַSеĿհףɴӡַո + * + *ע + * úڱġ + */ +Status ClearBlank(SString S); + +#endif diff --git a/VisualC++/ExerciseBook/05.17/05.17.c b/VisualC++/ExerciseBook/05.17/05.17.c new file mode 100644 index 0000000..17a0f00 --- /dev/null +++ b/VisualC++/ExerciseBook/05.17/05.17.c @@ -0,0 +1,137 @@ +#include +#include // ṩ systemrandsrand ԭ +#include // ṩ time ԭ +#include "SqList.h" //**02 Ա**// + +// ݹֵ +int Algo_5_17_1(SqList L, int len); + +// ݹСֵ +int Algo_5_17_2(SqList L, int len); + +// ݹ +int Algo_5_17_3(SqList L, int len); + +// ݹ +double Algo_5_17_4(SqList L, int len); + +// ݹƽ +double Algo_5_17_5(SqList L, int len); + + +int main(int argc, char* argv[]) { + SqList L; + int i; + + InitList(&L); + + srand((unsigned) time(NULL)); // ϵͳʱ + + for(i = 1; i <= 10; i++) { + ListInsert(&L, i, rand() % 100); + } + + printf("˳еΪ"); + for(i = 0; i < L.length; i++) { + printf("%d ", L.elem[i]); + } + printf("\n"); + + printf("˳еֵΪ %d \n", Algo_5_17_1(L, L.length)); + printf("˳еСֵΪ %d \n", Algo_5_17_2(L, L.length)); + printf("˳еĺΪ %d \n", Algo_5_17_3(L, L.length)); + printf("˳еĻΪ %.2f \n", Algo_5_17_4(L, L.length)); + printf("˳еƽֵΪ %.2f \n", Algo_5_17_5(L, L.length)); + + return 0; +} + + +// ݹֵ +int Algo_5_17_1(SqList L, int len) { + int value, max; + + // ȡǰλõֵ + GetElem(L, len, &value); + + if(len == 1) { + return value; + } + + // ȡǰеֵ + max = Algo_5_17_1(L, --len); + + return max > value ? max : value; +} + +// ݹСֵ +int Algo_5_17_2(SqList L, int len) { + int value, min; + + // ȡǰλõֵ + GetElem(L, len, &value); + + if(len == 1) { + return value; + } + + // ȡǰеСֵ + min = Algo_5_17_2(L, --len); + + return min < value ? min : value; +} + +// ݹ +int Algo_5_17_3(SqList L, int len) { + int sum; + + // ȡǰλõֵ + GetElem(L, len, &sum); + + if(len == 1) { + return sum; + } + + // ȡǰеĺ + sum += Algo_5_17_3(L, --len); + + return sum; +} + +// ݹ +double Algo_5_17_4(SqList L, int len) { + int value; + double mul; + + // ȡǰλõֵ + GetElem(L, len, &value); + mul = value; + + if(len == 1) { + return mul; + } + + // ȡǰеĻ + mul *= Algo_5_17_4(L, --len); + + return mul; +} + +// ݹƽ +double Algo_5_17_5(SqList L, int len) { + int value; + double avg; + + // ȡǰλõֵ + GetElem(L, len, &value); + avg = value; + + if(len == 1) { + return avg; + } + + // ȡǰеƽ + avg = (Algo_5_17_5(L, len - 1) * (len - 1) + value) / len; + + return avg; +} diff --git a/VisualC++/ExerciseBook/05.17/05.17.vcxproj b/VisualC++/ExerciseBook/05.17/05.17.vcxproj new file mode 100644 index 0000000..8d651e8 --- /dev/null +++ b/VisualC++/ExerciseBook/05.17/05.17.vcxproj @@ -0,0 +1,76 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {AD70051F-9782-4A15-A23D-76E1E8A6CC68} + My0517 + + + + Application + true + MultiByte + + + Application + false + true + MultiByte + + + + + + + + + + + + + $(SolutionDir)\..\Status;$(IncludePath) + + + + Level3 + Disabled + + + true + $(SolutionDir)\..\Status\Status.lib;%(AdditionalDependencies) + Console + + + + + Level3 + MaxSpeed + true + true + + + true + true + true + + + + + + + + + + + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/05.17/05.17.vcxproj.filters b/VisualC++/ExerciseBook/05.17/05.17.vcxproj.filters new file mode 100644 index 0000000..9228834 --- /dev/null +++ b/VisualC++/ExerciseBook/05.17/05.17.vcxproj.filters @@ -0,0 +1,30 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + 源文件 + + + 源文件 + + + + + 头文件 + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/05.17/05.17.vcxproj.user b/VisualC++/ExerciseBook/05.17/05.17.vcxproj.user new file mode 100644 index 0000000..ace9a86 --- /dev/null +++ b/VisualC++/ExerciseBook/05.17/05.17.vcxproj.user @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/05.17/SqList.c b/VisualC++/ExerciseBook/05.17/SqList.c new file mode 100644 index 0000000..f797103 --- /dev/null +++ b/VisualC++/ExerciseBook/05.17/SqList.c @@ -0,0 +1,337 @@ +/*============================= + * Ա˳洢ṹ˳ + * + * 㷨: 2.32.42.52.6 + =============================*/ + +#include "SqList.h" + +/* + * 㷨2.3 + * + * ʼ + * + * ʼɹ򷵻OK򷵻ERROR + */ +Status InitList(SqList* L) { + // ָڴ棬ʧܣ򷵻NULL + (*L).elem = (ElemType*) malloc(LIST_INIT_SIZE * sizeof(ElemType)); + if((*L).elem == NULL) { + // 洢ڴʧ + exit(OVERFLOW); + } + + (*L).length = 0; // ʼ˳Ϊ0 + (*L).listsize = LIST_INIT_SIZE; // ˳ʼڴ + + return OK; // ʼɹ +} + +/* + * (ṹ) + * + * ͷ˳ռڴ档 + */ +Status DestroyList(SqList* L) { + // ȷ˳ṹ + if(L == NULL || (*L).elem == NULL) { + return ERROR; + } + + // ͷ˳ڴ + free((*L).elem); + + // ͷڴÿָ + (*L).elem = NULL; + + // ˳ȸ + (*L).length = 0; + (*L).listsize = 0; + + return OK; +} + +/* + * ÿ() + * + * ֻ˳д洢ݣͷ˳ռڴ档 + */ +Status ClearList(SqList* L) { + // ȷ˳ṹ + if(L == NULL || (*L).elem == NULL) { + return ERROR; + } + + (*L).length = 0; + + return OK; +} + +/* + * п + * + * ж˳ǷЧݡ + * + * ֵ + * TRUE : ˳Ϊ + * FALSE: ˳Ϊ + */ +Status ListEmpty(SqList L) { + return L.length == 0 ? TRUE : FALSE; +} + +/* + * + * + * ˳ЧԪص + */ +int ListLength(SqList L) { + return L.length; +} + +/* + * ȡֵ + * + * ȡ˳еiԪأ洢eС + * ҵOK򣬷ERROR + * + *ע + * ̲iĺԪλã1ʼⲻϱͨԼ + * ͨiĺӦָ0ʼ + */ +Status GetElem(SqList L, int i, ElemType* e) { + // ΪiĺλãϷΧǣ[1, length] + if(i < 1 || i > L.length) { + return ERROR; //iֵϷ + } + + *e = L.elem[i - 1]; + + return OK; +} + +/* + * 㷨2.6 + * + * + * + * ˳׸eCompareϵԪλ + * Ԫأ򷵻0 + * + *ע + * ԪeCompareڶβ + */ +int LocateElem(SqList L, ElemType e, Status(Compare)(ElemType, ElemType)) { + int i; + ElemType* p; + + // ȷ˳ṹ + if(L.elem == NULL) { + return ERROR; + } + + /* + * iijֵΪ1Ԫصλ + * + * ʵȻдǽiʼΪ1Ԫص + * ڽ̲ǰλģдλ + */ + i = 1; + + // pijֵΪ1ԪصĴ洢λ + p = L.elem; + + // ˳ + while(i <= L.length && !Compare(*p++, e)) { + ++i; + } + + if(i <= L.length) { + return i; + } else { + return 0; + } +} + +/* + * ǰ + * + * ȡԪcur_eǰ + * ڣ洢pre_eУOK + * ڣ򷵻ERROR + */ +Status PriorElem(SqList L, ElemType cur_e, ElemType* pre_e) { + int i; + + // ȷ˳ṹڣٰԪ + if(L.elem == NULL || L.length < 2) { + return ERROR; + } + + // iʼΪ1Ԫصġ + i = 0; + + // ӵ1Ԫؿʼcur_eλ + while(i < L.length && L.elem[i] != cur_e) { + ++i; + } + + // cur_e׸Ԫ(ûǰ)ûҵԪcur_eERROR + if(i==0 || i >= L.length) { + return ERROR; + } + + // 洢cur_eǰ + *pre_e = L.elem[i - 1]; + + return OK; +} + +/* + * + * + * ȡԪcur_eḷ́ + * ڣ洢next_eУOK + * ڣ򷵻ERROR + */ +Status NextElem(SqList L, ElemType cur_e, ElemType* next_e) { + int i; + + // ȷ˳ṹڣٰԪ + if(L.elem == NULL || L.length < 2) { + return ERROR; + } + + // iʼΪ1Ԫصġ + i = 0; + + // ӵ1Ԫؿʼcur_eλ + while(i < L.length-1 && L.elem[i] != cur_e) { + ++i; + } + + // cur_e1Ԫ(ûǰ)ûҵԪcur_eERROR + if(i >= L.length-1) { + return ERROR; + } + + // 洢cur_eǰ + *next_e = L.elem[i + 1]; + + return OK; +} + +/* + * 㷨2.4 + * + * + * + * ˳iλϲeɹ򷵻OK򷵻ERROR + * + *ע + * ̲iĺԪλã1ʼ + */ +Status ListInsert(SqList* L, int i, ElemType e) { + ElemType* newbase; + ElemType* p, * q; + + // ȷ˳ṹ + if(L == NULL || (*L).elem == NULL) { + return ERROR; + } + + // iֵԽ + if(i < 1 || i > (*L).length + 1) { + return ERROR; + } + + // 洢ռ¿ռ + if((*L).length >= (*L).listsize) { + // пռ + newbase = (ElemType*) realloc((*L).elem, ((*L).listsize + LISTINCREMENT) * sizeof(ElemType)); + if(newbase == NULL) { + // 洢ڴʧ + exit(OVERFLOW); + } + + // »ַ + (*L).elem = newbase; + // Ĵ洢ռ + (*L).listsize += LISTINCREMENT; + } + + // qΪλ + q = &(*L).elem[i - 1]; + + // 1.Ԫأڳλ + for(p = &(*L).elem[(*L).length - 1]; p >= q; --p) { + *(p + 1) = *p; + } + + // 2.e + *q = e; + + // 3.1 + (*L).length++; + + return OK; +} + +/* + * 㷨2.5 + * + * ɾ + * + * ɾ˳iλϵԪأɾԪش洢eС + * ɾɹ򷵻OK򷵻ERROR + * + *ע + * ̲iĺԪλã1ʼ + */ +Status ListDelete(SqList* L, int i, ElemType* e) { + ElemType* p, * q; + + // ȷ˳ṹ + if(L == NULL || (*L).elem == NULL) { + return ERROR; + } + + // iֵԽ + if(i < 1 || i > (*L).length) { + return ERROR; + } + + // pΪɾԪصλ + p = &(*L).elem[i - 1]; + + // 1.ȡɾԪ + *e = *p; + + // βԪλ + q = (*L).elem + (*L).length - 1; + + // 2.ԪأɾԪصλϻԪؽ + for(++p; p <= q; ++p) { + *(p - 1) = *p; + } + + // 3.1 + (*L).length--; + + return OK; +} + +/* + * + * + * visit˳L + */ +void ListTraverse(SqList L, void(Visit)(ElemType)) { + int i; + + for(i = 0; i < L.length; i++) { + Visit(L.elem[i]); + } + + printf("\n"); +} diff --git a/VisualC++/ExerciseBook/05.17/SqList.h b/VisualC++/ExerciseBook/05.17/SqList.h new file mode 100644 index 0000000..975e5b1 --- /dev/null +++ b/VisualC++/ExerciseBook/05.17/SqList.h @@ -0,0 +1,149 @@ +/*============================= + * Ա˳洢ṹ˳ + * + * 㷨: 2.32.42.52.6 + =============================*/ + +#ifndef SQLIST_H +#define SQLIST_H + +#include +#include // ṩmallocreallocfreeexitԭ +#include "Status.h" //**01 **// + +/* 궨 */ +#define LIST_INIT_SIZE 100 // ˳洢ռijʼ +#define LISTINCREMENT 10 // ˳洢ռķ + +/* ˳ԪͶ */ +typedef int ElemType; + +/* + * ˳ṹ + * + * עelemʹǰҪΪڴ棬Ԫشelem[0]ʼ洢 + */ +typedef struct { + ElemType* elem; // ˳洢ռĻַָ˳ռڴʼλã + int length; // ǰ˳ȣԪأ + int listsize; // ǰĴ洢Դ洢Ԫأ +} SqList; + + +/* + * 㷨2.3 + * + * ʼ + * + * ʼɹ򷵻OK򷵻ERROR + */ +Status InitList(SqList* L); + +/* + * (ṹ) + * + * ͷ˳ռڴ档 + */ +Status DestroyList(SqList* L); + +/* + * ÿ() + * + * ֻ˳д洢ݣͷ˳ռڴ档 + */ +Status ClearList(SqList* L); + +/* + * п + * + * ж˳ǷЧݡ + * + * ֵ + * TRUE : ˳Ϊ + * FALSE: ˳Ϊ + */ +Status ListEmpty(SqList L); + +/* + * + * + * ˳ЧԪص + */ +int ListLength(SqList L); + +/* + * ȡֵ + * + * ȡ˳еiԪأ洢eС + * ҵOK򣬷ERROR + * + *ע + * ̲iĺԪλã1ʼⲻϱͨԼ + * ͨiĺӦָ0ʼ + */ +Status GetElem(SqList L, int i, ElemType* e); + +/* + * 㷨2.6 + * + * + * + * ˳׸eCompareϵԪλ + * Ԫأ򷵻0 + * + *ע + * ԪeCompareڶβ + */ +int LocateElem(SqList L, ElemType e, Status(Compare)(ElemType, ElemType)); + +/* + * ǰ + * + * ȡԪcur_eǰ + * ڣ洢pre_eУOK + * ڣ򷵻ERROR + */ +Status PriorElem(SqList L, ElemType cur_e, ElemType* pre_e); + +/* + * + * + * ȡԪcur_eḷ́ + * ڣ洢next_eУOK + * ڣ򷵻ERROR + */ +Status NextElem(SqList L, ElemType cur_e, ElemType* next_e); + +/* + * 㷨2.4 + * + * + * + * ˳iλϲeɹ򷵻OK򷵻ERROR + * + *ע + * ̲iĺԪλã1ʼ + */ +Status ListInsert(SqList* L, int i, ElemType e); + +/* + * 㷨2.5 + * + * ɾ + * + * ɾ˳iλϵԪأɾԪش洢eС + * ɾɹ򷵻OK򷵻ERROR + * + *ע + * ̲iĺԪλã1ʼ + */ +Status ListDelete(SqList* L, int i, ElemType* e); + +/* + * + * + * visit˳L + */ +void ListTraverse(SqList L, void (Visit)(ElemType)); + +#endif diff --git a/VisualC++/ExerciseBook/05.18/05.18.c b/VisualC++/ExerciseBook/05.18/05.18.c new file mode 100644 index 0000000..2633309 --- /dev/null +++ b/VisualC++/ExerciseBook/05.18/05.18.c @@ -0,0 +1,91 @@ +#include +#include // ṩ systemrandsrand ԭ +#include // ṩ time ԭ +#include "Status.h" //**01 **// +#include "Array.h" //**05 ͹**// + +/* + * AеԪѭkλ + */ +Status Algo_5_18(Array A, int k); + +// [begin, end]ΧڵԪ +static Status Reversal_5_18(Array A, int begin, int end); + + +int main(int argc, char* argv[]) { + Array A; + ElemType e; + int i; + int k = 7; // λ + + // ʼΪ10һά + InitArray(&A, 1, 10); + + srand((unsigned) time(NULL)); // ϵͳʱ + + for(i = 0; i < Length(A); i++) { + e = rand() % 100; + Assign(&A, e, i); + } + + printf("AԪΪ\n"); + for(i = 0; i < Length(A); i++) { + Value(A, &e, i); + printf("%2d ", e); + } + printf("\n"); + + printf("Aѭ %d λ\n", k); + Algo_5_18(A, k); + for(i = 0; i < Length(A); i++) { + Value(A, &e, i); + printf("%2d ", e); + } + printf("\n"); + + return 0; +} + + +/* + * AеԪѭkλ + */ +Status Algo_5_18(Array A, int k) { + int n, p; + + n = Length(A); + + p = k % n; // ʵҪѭƵλ + if(p <= 0) { + return ERROR; + } + + Reversal_5_18(A, 0, n-1); // [0, n-1]ΧڵԪ + Reversal_5_18(A, 0, p-1); // [0, p-1]ΧڵԪ + Reversal_5_18(A, p, n-1); // [p, n-1]ΧڵԪ + + return OK; +} + +// [begin, end]ΧڵԪ +static Status Reversal_5_18(Array A, int begin, int end) { + int i; + ElemType e1, e2; + + if(begin < 0 || end > Length(A)-1 || begin >= end) { + return ERROR; + } + + // "" + for(i = 0; i < (end - begin + 1) / 2; i++) { + Value(A, &e1, begin + i); // ȡеǰԪ + Value(A, &e2, end - i); // ȡеԪ + + // Ԫɽ + Assign(&A, e2, begin + i); + Assign(&A, e1, end - i); + } + + return OK; +} diff --git a/VisualC++/ExerciseBook/05.18/05.18.vcxproj b/VisualC++/ExerciseBook/05.18/05.18.vcxproj new file mode 100644 index 0000000..a71a968 --- /dev/null +++ b/VisualC++/ExerciseBook/05.18/05.18.vcxproj @@ -0,0 +1,76 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {DEAB729F-1809-4FAC-93DC-9E42774A3BFA} + My0518 + + + + Application + true + MultiByte + + + Application + false + true + MultiByte + + + + + + + + + + + + + $(SolutionDir)\..\Status;$(IncludePath) + + + + Level3 + Disabled + + + true + $(SolutionDir)\..\Status\Status.lib;%(AdditionalDependencies) + Console + + + + + Level3 + MaxSpeed + true + true + + + true + true + true + + + + + + + + + + + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/05.18/05.18.vcxproj.filters b/VisualC++/ExerciseBook/05.18/05.18.vcxproj.filters new file mode 100644 index 0000000..b5ff1e0 --- /dev/null +++ b/VisualC++/ExerciseBook/05.18/05.18.vcxproj.filters @@ -0,0 +1,30 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + 源文件 + + + 源文件 + + + + + 头文件 + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/05.18/05.18.vcxproj.user b/VisualC++/ExerciseBook/05.18/05.18.vcxproj.user new file mode 100644 index 0000000..ace9a86 --- /dev/null +++ b/VisualC++/ExerciseBook/05.18/05.18.vcxproj.user @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/05.18/Array.c b/VisualC++/ExerciseBook/05.18/Array.c new file mode 100644 index 0000000..494d467 --- /dev/null +++ b/VisualC++/ExerciseBook/05.18/Array.c @@ -0,0 +1,195 @@ +/*======== + * ά + =========*/ + +#include "Array.h" //**05 ͹**// + +/* + * ʼ + * + * ʼάΪdim飬ɱָʾάȵĴС + */ +Status InitArray(Array* A, int dim, ...) { + int elemtotal; // ͳԪظ + va_list ap; // apſɱϢָʾάȵĴС + int i; + + if(A == NULL) { + return ERROR; + } + + if(dim < 1 || dim > MAX_ARRAY_DIM) { // ά + return ERROR; + } + + (*A).dim = dim; // ʼά + + // ʼάϢ + (*A).bounds = (int*) malloc(dim * sizeof(int)); + if((*A).bounds == NULL) { + exit(OVERFLOW); + } + + // άȳȺϷboundsAԪelemtotal + elemtotal = 1; + + // ʹapָһɱdim൱ʼʶ + va_start(ap, dim); + + for(i = 0; i < dim; i++) { + // ¼ǰάȵĿ + (*A).bounds[i] = va_arg(ap, int); + if((*A).bounds[i] <= 0) { + return ERROR; + } + + elemtotal *= A->bounds[i]; + } + + // ÿap + va_end(ap); + + // ʼռ䣬ԴԪ + (*A).base = (ElemType*) malloc(elemtotal * sizeof(ElemType)); + if((*A).base == NULL) { + exit(OVERFLOW); + } + + // ʼӳϢ + (*A).constants = (int*) malloc(dim * sizeof(int)); + if((*A).constants == NULL) { + exit(OVERFLOW); + } + + // һάȣÿҪԽһԪ + (*A).constants[dim - 1] = 1; + for(i = dim - 2; i >= 0; i--) { + (*A).constants[i] = (*A).bounds[i + 1] * (*A).constants[i + 1]; + } + + /* + * + * ά[2,3,4]˵boundsֵΪ<2,3,4>constantsֵΪ<12,4,1> + * boundsһάа2Ԫأڶάа3Ԫأάа4Ԫ + * constantsһάÿҪ12ԪأڶάÿҪԽ4ԪأάÿҪԽ1Ԫ + */ + + return OK; +} + +/* + * (ṹ) + * + * ռõĿռ䡣 + */ +Status DestroyArray(Array* A) { + if(A == NULL || (*A).base == NULL || (*A).bounds == NULL || (*A).constants == NULL) { + return ERROR; + } + + free((*A).base); + (*A).base = NULL; + + free((*A).bounds); + (*A).bounds = NULL; + + free((*A).constants); + (*A).constants = NULL; + + (*A).dim = 0; + + return OK; +} + +/* + * ȡֵ + * + * ȡָ±괦ԪֵɱΪdim±ֵָʾȡԪ±ꡣ + */ +Status Value(Array A, ElemType* e, ...) { + va_list ap; + Status result; + int off; + + va_start(ap, e); + + // ԪصĿԪҪԽԪ + result = Locate(A, ap, &off); + + va_end(ap); + + if(result == OVERFLOW) { + return result; + } + + *e = *(A.base + off); + + return OK; +} + +/* + * ֵ + * + * Ϊָ±괦ԪظֵɱΪdim±ֵָʾֵԪ±ꡣ + */ +Status Assign(Array* A, ElemType e, ...) { + va_list ap; + Status result; + int off; + + va_start(ap, e); + + // ԪصĿԪҪԽԪ + result = Locate(*A, ap, &off); + + va_end(ap); + + if(result == OVERFLOW) { + return result; + } + + *(A->base + off) = e; + + return OK; +} + +/* + * apָʾֵAеλã + * ԪصĿԪҪԽԪ + */ +static Status Locate(Array A, va_list ap, int* off) { + int i, ind; + + *off = 0; + + for(i = 0; i < A.dim; i++) { + ind = va_arg(ap, int); + + // ֤±겻Խ + if(ind < 0 || ind >= A.bounds[i]) { + return OVERFLOW; + } + + // ijάȵĵλԪظ*Ҫĵλ + *off += A.constants[i] * ind; + } + + return OK; +} + +/* + * Ԫصĸ + * + *ע + * Ϊĺ + */ +int Length(Array A) { + int i; + int elemtotal = 1; + + for(i = 0; i < A.dim; i++) { + elemtotal *= A.bounds[i]; + } + + return elemtotal; +} diff --git a/VisualC++/ExerciseBook/05.18/Array.h b/VisualC++/ExerciseBook/05.18/Array.h new file mode 100644 index 0000000..bae6fab --- /dev/null +++ b/VisualC++/ExerciseBook/05.18/Array.h @@ -0,0 +1,70 @@ +/*======== + * ά + =========*/ + +#ifndef ARRAY_H +#define ARRAY_H + +#include +#include // ṩmallocreallocfreeexitԭ +#include // ṩva_startva_argva_end +#include "Status.h" //**01 **// + +/* 궨 */ +#define MAX_ARRAY_DIM 8 // άΪ8 + +/* Ԫ */ +typedef int ElemType; + +/* ˳洢ʾ */ +typedef struct { + ElemType* base; // ԪػַԪأ + int dim; // ά + int* bounds; // άַСϢ + int* constants; // ӳַ洢ijάʱÿҪԽԪظ +} Array; + + +/* + * ʼ + * + * ʼάΪdim飬ɱָʾάȵĴС + */ +Status InitArray(Array* A, int dim, ...); + +/* + * (ṹ) + * + * ռõĿռ䡣 + */ +Status DestroyArray(Array* A); + +/* + * ȡֵ + * + * ȡָ±괦ԪֵɱΪdim±ֵָʾȡԪ±ꡣ + */ +Status Value(Array A, ElemType* e, ...); + +/* + * ֵ + * + * Ϊָ±괦ԪظֵɱΪdim±ֵָʾֵԪ±ꡣ + */ +Status Assign(Array* A, ElemType e, ...); + +/* + * apָʾֵAеλã + * ԪصĿԪҪԽԪ + */ +static Status Locate(Array A, va_list ap, int *off); + +/* + * Ԫصĸ + * + *ע + * Ϊĺ + */ +int Length(Array A); + +#endif diff --git a/VisualC++/ExerciseBook/05.19/05.19.c b/VisualC++/ExerciseBook/05.19/05.19.c new file mode 100644 index 0000000..c5f3ccb --- /dev/null +++ b/VisualC++/ExerciseBook/05.19/05.19.c @@ -0,0 +1,114 @@ +#include +#include +#include +#include "Array.h" //**05 ͹**// + +/* Ԫ */ +typedef struct { + int x; + int y; + ElemType value; +} Elem; + +/* + * ѰҶάAе + * + *ע + * ÿÿеԪزΨһ + */ +void Algo_5_19(Array A); + + +int main(int argc, char* argv[]) { + int a[3][4] = { + {10, 16, 13, 14}, + {15, 18, 15, 20}, + { 5, 8, 12, 32} + }; + int i, j; + Array A; + + // ׼ + InitArray(&A, 2, 3, 4); + for(i = 0; i < 3; i++) { + for(j = 0; j < 4; j++) { + Assign(&A, a[i][j], i, j); + } + } + + // Ѱ + Algo_5_19(A); + + return 0; +} + + +/* + * ѰҶάAе + * + *ע + * ÿÿеԪزΨһ + */ +void Algo_5_19(Array A) { + int row, col; // + Elem* Min; // 洢AÿеСֵϢ + ElemType* Max; // 洢Aÿеֵֻ洢ֵ + int total, k; // total¼Minд洢Ԫ + int i, j; + ElemType e; + int count; + int min; + + row = A.bounds[0]; + col = A.bounds[1]; + + Min = (Elem*) malloc(row * col * sizeof(Elem)); + + Max = (ElemType*) malloc(col * sizeof(ElemType)); + // ʼֵ + for(j = 0; j < col; j++) { + Max[j] = INT_MIN; + } + + total = 0; + + for(i = 0; i < row; i++) { + min = INT_MAX; // ǰСֵ + + for(j = 0; j < col; j++) { + // ȡԪA[i][j] + Value(A, &e, i, j); + + // ¼ֵ + if(e > Max[j]) { + Max[j] = e; + } + + // ¼СֵϢ + if(e <= min) { + // ÿηָСģkҪ + if(e < min) { + k = total; // ͳƵǰеСֵԪ + min = e; + } + + Min[k].x = i; + Min[k].y = j; + Min[k].value = e; + + k++; + } + } + + // ۼӱԪ + total += (k - total); + } + + count = 0; + for(k = 0; k < total; k++) { + // ǰСֵеֵ뵱ǰСֵһ£ + if(Max[Min[k].y] == Min[k].value) { + printf(" %2d λ (%2d, %2d) %d\n", ++count, Min[k].x, Min[k].y, Min[k].value); + } + } +} diff --git a/VisualC++/ExerciseBook/05.19/05.19.vcxproj b/VisualC++/ExerciseBook/05.19/05.19.vcxproj new file mode 100644 index 0000000..02c2a58 --- /dev/null +++ b/VisualC++/ExerciseBook/05.19/05.19.vcxproj @@ -0,0 +1,76 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {0E1F3F75-49AB-4167-83E2-C118DB269292} + My0519 + + + + Application + true + MultiByte + + + Application + false + true + MultiByte + + + + + + + + + + + + + $(SolutionDir)\..\Status;$(IncludePath) + + + + Level3 + Disabled + + + true + $(SolutionDir)\..\Status\Status.lib;%(AdditionalDependencies) + Console + + + + + Level3 + MaxSpeed + true + true + + + true + true + true + + + + + + + + + + + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/05.19/05.19.vcxproj.filters b/VisualC++/ExerciseBook/05.19/05.19.vcxproj.filters new file mode 100644 index 0000000..22049ec --- /dev/null +++ b/VisualC++/ExerciseBook/05.19/05.19.vcxproj.filters @@ -0,0 +1,30 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + 源文件 + + + 源文件 + + + + + 头文件 + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/05.19/05.19.vcxproj.user b/VisualC++/ExerciseBook/05.19/05.19.vcxproj.user new file mode 100644 index 0000000..ace9a86 --- /dev/null +++ b/VisualC++/ExerciseBook/05.19/05.19.vcxproj.user @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/05.19/Array.c b/VisualC++/ExerciseBook/05.19/Array.c new file mode 100644 index 0000000..e81eac3 --- /dev/null +++ b/VisualC++/ExerciseBook/05.19/Array.c @@ -0,0 +1,178 @@ +/*======== + * ά + =========*/ + +#include "Array.h" //**05 ͹**// + +/* + * ʼ + * + * ʼάΪdim飬ɱָʾάȵĴС + */ +Status InitArray(Array* A, int dim, ...) { + int elemtotal; // ͳԪظ + va_list ap; // apſɱϢָʾάȵĴС + int i; + + if(A == NULL) { + return ERROR; + } + + if(dim < 1 || dim > MAX_ARRAY_DIM) { // ά + return ERROR; + } + + (*A).dim = dim; // ʼά + + // ʼάϢ + (*A).bounds = (int*) malloc(dim * sizeof(int)); + if((*A).bounds == NULL) { + exit(OVERFLOW); + } + + // άȳȺϷboundsAԪelemtotal + elemtotal = 1; + + // ʹapָһɱdim൱ʼʶ + va_start(ap, dim); + + for(i = 0; i < dim; i++) { + // ¼ǰάȵĿ + (*A).bounds[i] = va_arg(ap, int); + if((*A).bounds[i] <= 0) { + return ERROR; + } + + elemtotal *= A->bounds[i]; + } + + // ÿap + va_end(ap); + + // ʼռ䣬ԴԪ + (*A).base = (ElemType*) malloc(elemtotal * sizeof(ElemType)); + if((*A).base == NULL) { + exit(OVERFLOW); + } + + // ʼӳϢ + (*A).constants = (int*) malloc(dim * sizeof(int)); + if((*A).constants == NULL) { + exit(OVERFLOW); + } + + // һάȣÿҪԽһԪ + (*A).constants[dim - 1] = 1; + for(i = dim - 2; i >= 0; i--) { + (*A).constants[i] = (*A).bounds[i + 1] * (*A).constants[i + 1]; + } + + /* + * + * ά[2,3,4]˵boundsֵΪ<2,3,4>constantsֵΪ<12,4,1> + * boundsһάа2Ԫأڶάа3Ԫأάа4Ԫ + * constantsһάÿҪ12ԪأڶάÿҪԽ4ԪأάÿҪԽ1Ԫ + */ + + return OK; +} + +/* + * (ṹ) + * + * ռõĿռ䡣 + */ +Status DestroyArray(Array* A) { + if(A == NULL || (*A).base == NULL || (*A).bounds == NULL || (*A).constants == NULL) { + return ERROR; + } + + free((*A).base); + (*A).base = NULL; + + free((*A).bounds); + (*A).bounds = NULL; + + free((*A).constants); + (*A).constants = NULL; + + (*A).dim = 0; + + return OK; +} + +/* + * ȡֵ + * + * ȡָ±괦ԪֵɱΪdim±ֵָʾȡԪ±ꡣ + */ +Status Value(Array A, ElemType* e, ...) { + va_list ap; + Status result; + int off; + + va_start(ap, e); + + // ԪصĿԪҪԽԪ + result = Locate(A, ap, &off); + + va_end(ap); + + if(result == OVERFLOW) { + return result; + } + + *e = *(A.base + off); + + return OK; +} + +/* + * ֵ + * + * Ϊָ±괦ԪظֵɱΪdim±ֵָʾֵԪ±ꡣ + */ +Status Assign(Array* A, ElemType e, ...) { + va_list ap; + Status result; + int off; + + va_start(ap, e); + + // ԪصĿԪҪԽԪ + result = Locate(*A, ap, &off); + + va_end(ap); + + if(result == OVERFLOW) { + return result; + } + + *(A->base + off) = e; + + return OK; +} + +/* + * apָʾֵAеλã + * ԪصĿԪҪԽԪ + */ +static Status Locate(Array A, va_list ap, int* off) { + int i, ind; + + *off = 0; + + for(i = 0; i < A.dim; i++) { + ind = va_arg(ap, int); + + // ֤±겻Խ + if(ind < 0 || ind >= A.bounds[i]) { + return OVERFLOW; + } + + // ijάȵĵλԪظ*Ҫĵλ + *off += A.constants[i] * ind; + } + + return OK; +} diff --git a/VisualC++/ExerciseBook/05.19/Array.h b/VisualC++/ExerciseBook/05.19/Array.h new file mode 100644 index 0000000..31dd29f --- /dev/null +++ b/VisualC++/ExerciseBook/05.19/Array.h @@ -0,0 +1,62 @@ +/*======== + * ά + =========*/ + +#ifndef ARRAY_H +#define ARRAY_H + +#include +#include // ṩmallocreallocfreeexitԭ +#include // ṩva_startva_argva_end +#include "Status.h" //**01 **// + +/* 궨 */ +#define MAX_ARRAY_DIM 8 // άΪ8 + +/* Ԫ */ +typedef int ElemType; + +/* ˳洢ʾ */ +typedef struct { + ElemType* base; // ԪػַԪأ + int dim; // ά + int* bounds; // άַСϢ + int* constants; // ӳַ洢ijάʱÿҪԽԪظ +} Array; + + +/* + * ʼ + * + * ʼάΪdim飬ɱָʾάȵĴС + */ +Status InitArray(Array* A, int dim, ...); + +/* + * (ṹ) + * + * ռõĿռ䡣 + */ +Status DestroyArray(Array* A); + +/* + * ȡֵ + * + * ȡָ±괦ԪֵɱΪdim±ֵָʾȡԪ±ꡣ + */ +Status Value(Array A, ElemType* e, ...); + +/* + * ֵ + * + * Ϊָ±괦ԪظֵɱΪdim±ֵָʾֵԪ±ꡣ + */ +Status Assign(Array* A, ElemType e, ...); + +/* + * apָʾֵAеλã + * ԪصĿԪҪԽԪ + */ +static Status Locate(Array A, va_list ap, int *off); + +#endif diff --git a/VisualC++/ExerciseBook/05.20/05.20.c b/VisualC++/ExerciseBook/05.20/05.20.c new file mode 100644 index 0000000..4246091 --- /dev/null +++ b/VisualC++/ExerciseBook/05.20/05.20.c @@ -0,0 +1,112 @@ +#include +#include // ṩ systemrandsrand ԭ +#include // ṩ time ԭ +#include "Array.h" //**05 ͹**// + +// ݶʽϵʽ +void Algo_5_20(Array A); + +// ڲʵ +static void Print(Array A, int dim, int index[]); + + +int main(int argc, char* argv[]) { + Array A; + int i, j, k; + ElemType e = 0; + + // ʼһάΪ<2,3,4>ά + InitArray(&A, 3, 2, 3, 4); + + srand((unsigned) time(NULL)); // ϵͳʱ + + // ׼ + for(i = 0; i < A.bounds[0]; i++) { + for(j = 0; j < A.bounds[1]; j++) { + for(k = 0; k < A.bounds[2]; k++) { + e = rand() % 50 - 25; // + Assign(&A, e, i, j, k); + } + } + } + + // ʽ + Algo_5_20(A); + + return 0; +} + + +// ݶʽϵʽ +void Algo_5_20(Array A) { + int i; + int* index; + + // ڱԪʱ¼ÿԪصֻ¼ǰdim-1ά + index = (int*) malloc((A.dim - 1) * sizeof(int)); + for(i = 0; i < A.dim - 1; i++) { + index[i] = -1; + } + + Print(A, 1, index); + + printf("\n"); +} + +// ڲʵ +static void Print(Array A, int dim, int index[]) { + int i, j; + int start; + ElemType coef; + + if(dim == A.dim) { + start = 0; + + // 㱾αʼԪλ + for(i = 0; i < dim - 1; i++) { + start += index[i] * A.constants[i]; + } + + // һάڵԪ + for(i = 0; i < A.bounds[dim - 1]; i++) { + // ȡϵ + coef = A.base[start + i]; + + // ϵΪ0 + if(coef == 0) { + continue; + } + + if(coef < 0) { + printf(" - "); + } else { + printf(" + "); + } + + // ϵľֵΪ1ʱϵ + if(abs(coef) != 1) { + // ϵţǰѾţһҲŷ + printf("%d", abs(coef)); + } + + /* + * ʽÿһδ֪abc... + * + *ע + * ָλ0ָλ1ΣȻӡ + * ѡ񲻴ӡЩ + */ + for(j = 0; j < dim - 1; j++) { + printf("%c^%d", 'a' + j, index[j]); + } + printf("%c^%d", 'a' + j, i); + } + } else { + for(i = 0; i < A.bounds[dim - 1]; i++) { + // ת + index[dim - 1] = (index[dim - 1] + 1 + A.bounds[dim - 1]) % A.bounds[dim - 1]; + + Print(A, dim + 1, index); + } + } +} diff --git a/VisualC++/ExerciseBook/05.20/05.20.vcxproj b/VisualC++/ExerciseBook/05.20/05.20.vcxproj new file mode 100644 index 0000000..60d7790 --- /dev/null +++ b/VisualC++/ExerciseBook/05.20/05.20.vcxproj @@ -0,0 +1,76 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {685BE3FF-10F8-417E-9601-7CDE7AEFAC0B} + My0520 + + + + Application + true + MultiByte + + + Application + false + true + MultiByte + + + + + + + + + + + + + $(SolutionDir)\..\Status;$(IncludePath) + + + + Level3 + Disabled + + + true + $(SolutionDir)\..\Status\Status.lib;%(AdditionalDependencies) + Console + + + + + Level3 + MaxSpeed + true + true + + + true + true + true + + + + + + + + + + + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/05.20/05.20.vcxproj.filters b/VisualC++/ExerciseBook/05.20/05.20.vcxproj.filters new file mode 100644 index 0000000..547966c --- /dev/null +++ b/VisualC++/ExerciseBook/05.20/05.20.vcxproj.filters @@ -0,0 +1,30 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + 头文件 + + + + + 源文件 + + + 源文件 + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/05.20/05.20.vcxproj.user b/VisualC++/ExerciseBook/05.20/05.20.vcxproj.user new file mode 100644 index 0000000..ace9a86 --- /dev/null +++ b/VisualC++/ExerciseBook/05.20/05.20.vcxproj.user @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/05.20/Array.c b/VisualC++/ExerciseBook/05.20/Array.c new file mode 100644 index 0000000..e81eac3 --- /dev/null +++ b/VisualC++/ExerciseBook/05.20/Array.c @@ -0,0 +1,178 @@ +/*======== + * ά + =========*/ + +#include "Array.h" //**05 ͹**// + +/* + * ʼ + * + * ʼάΪdim飬ɱָʾάȵĴС + */ +Status InitArray(Array* A, int dim, ...) { + int elemtotal; // ͳԪظ + va_list ap; // apſɱϢָʾάȵĴС + int i; + + if(A == NULL) { + return ERROR; + } + + if(dim < 1 || dim > MAX_ARRAY_DIM) { // ά + return ERROR; + } + + (*A).dim = dim; // ʼά + + // ʼάϢ + (*A).bounds = (int*) malloc(dim * sizeof(int)); + if((*A).bounds == NULL) { + exit(OVERFLOW); + } + + // άȳȺϷboundsAԪelemtotal + elemtotal = 1; + + // ʹapָһɱdim൱ʼʶ + va_start(ap, dim); + + for(i = 0; i < dim; i++) { + // ¼ǰάȵĿ + (*A).bounds[i] = va_arg(ap, int); + if((*A).bounds[i] <= 0) { + return ERROR; + } + + elemtotal *= A->bounds[i]; + } + + // ÿap + va_end(ap); + + // ʼռ䣬ԴԪ + (*A).base = (ElemType*) malloc(elemtotal * sizeof(ElemType)); + if((*A).base == NULL) { + exit(OVERFLOW); + } + + // ʼӳϢ + (*A).constants = (int*) malloc(dim * sizeof(int)); + if((*A).constants == NULL) { + exit(OVERFLOW); + } + + // һάȣÿҪԽһԪ + (*A).constants[dim - 1] = 1; + for(i = dim - 2; i >= 0; i--) { + (*A).constants[i] = (*A).bounds[i + 1] * (*A).constants[i + 1]; + } + + /* + * + * ά[2,3,4]˵boundsֵΪ<2,3,4>constantsֵΪ<12,4,1> + * boundsһάа2Ԫأڶάа3Ԫأάа4Ԫ + * constantsһάÿҪ12ԪأڶάÿҪԽ4ԪأάÿҪԽ1Ԫ + */ + + return OK; +} + +/* + * (ṹ) + * + * ռõĿռ䡣 + */ +Status DestroyArray(Array* A) { + if(A == NULL || (*A).base == NULL || (*A).bounds == NULL || (*A).constants == NULL) { + return ERROR; + } + + free((*A).base); + (*A).base = NULL; + + free((*A).bounds); + (*A).bounds = NULL; + + free((*A).constants); + (*A).constants = NULL; + + (*A).dim = 0; + + return OK; +} + +/* + * ȡֵ + * + * ȡָ±괦ԪֵɱΪdim±ֵָʾȡԪ±ꡣ + */ +Status Value(Array A, ElemType* e, ...) { + va_list ap; + Status result; + int off; + + va_start(ap, e); + + // ԪصĿԪҪԽԪ + result = Locate(A, ap, &off); + + va_end(ap); + + if(result == OVERFLOW) { + return result; + } + + *e = *(A.base + off); + + return OK; +} + +/* + * ֵ + * + * Ϊָ±괦ԪظֵɱΪdim±ֵָʾֵԪ±ꡣ + */ +Status Assign(Array* A, ElemType e, ...) { + va_list ap; + Status result; + int off; + + va_start(ap, e); + + // ԪصĿԪҪԽԪ + result = Locate(*A, ap, &off); + + va_end(ap); + + if(result == OVERFLOW) { + return result; + } + + *(A->base + off) = e; + + return OK; +} + +/* + * apָʾֵAеλã + * ԪصĿԪҪԽԪ + */ +static Status Locate(Array A, va_list ap, int* off) { + int i, ind; + + *off = 0; + + for(i = 0; i < A.dim; i++) { + ind = va_arg(ap, int); + + // ֤±겻Խ + if(ind < 0 || ind >= A.bounds[i]) { + return OVERFLOW; + } + + // ijάȵĵλԪظ*Ҫĵλ + *off += A.constants[i] * ind; + } + + return OK; +} diff --git a/VisualC++/ExerciseBook/05.20/Array.h b/VisualC++/ExerciseBook/05.20/Array.h new file mode 100644 index 0000000..31dd29f --- /dev/null +++ b/VisualC++/ExerciseBook/05.20/Array.h @@ -0,0 +1,62 @@ +/*======== + * ά + =========*/ + +#ifndef ARRAY_H +#define ARRAY_H + +#include +#include // ṩmallocreallocfreeexitԭ +#include // ṩva_startva_argva_end +#include "Status.h" //**01 **// + +/* 궨 */ +#define MAX_ARRAY_DIM 8 // άΪ8 + +/* Ԫ */ +typedef int ElemType; + +/* ˳洢ʾ */ +typedef struct { + ElemType* base; // ԪػַԪأ + int dim; // ά + int* bounds; // άַСϢ + int* constants; // ӳַ洢ijάʱÿҪԽԪظ +} Array; + + +/* + * ʼ + * + * ʼάΪdim飬ɱָʾάȵĴС + */ +Status InitArray(Array* A, int dim, ...); + +/* + * (ṹ) + * + * ռõĿռ䡣 + */ +Status DestroyArray(Array* A); + +/* + * ȡֵ + * + * ȡָ±괦ԪֵɱΪdim±ֵָʾȡԪ±ꡣ + */ +Status Value(Array A, ElemType* e, ...); + +/* + * ֵ + * + * Ϊָ±괦ԪظֵɱΪdim±ֵָʾֵԪ±ꡣ + */ +Status Assign(Array* A, ElemType e, ...); + +/* + * apָʾֵAеλã + * ԪصĿԪҪԽԪ + */ +static Status Locate(Array A, va_list ap, int *off); + +#endif diff --git a/VisualC++/ExerciseBook/05.21/05.21.c b/VisualC++/ExerciseBook/05.21/05.21.c new file mode 100644 index 0000000..c6f0b54 --- /dev/null +++ b/VisualC++/ExerciseBook/05.21/05.21.c @@ -0,0 +1,43 @@ +#include +#include "Status.h" //**01 **// +#include "TSMatrix.h" //**05 ͹**// + +/* + * ϡӷAddSMatrix + * + *ע + * úTSMatrixļж + */ +Status Algo_5_21(TSMatrix A, TSMatrix B, TSMatrix* C); + + +int main(int argc, char* argv[]) { + TSMatrix A, B, C; + + printf(" ϡ AB ...\n"); + CreateSMatrix(&A, "TestData_A.txt"); + CreateSMatrix(&B, "TestData_B.txt"); + printf(" A = \n"); + PrintSMatrix(A); + printf(" B = \n"); + PrintSMatrix(B); + + // + Algo_5_21(A, B, &C); + + printf(" C = A + B = \n"); + PrintSMatrix(C); + + return 0; +} + + +/* + * ϡӷAddSMatrix + * + *ע + * úTSMatrixļж + */ +Status Algo_5_21(TSMatrix A, TSMatrix B, TSMatrix* C) { + return AddSMatrix(A, B, C); +} diff --git a/VisualC++/ExerciseBook/05.21/05.21.vcxproj b/VisualC++/ExerciseBook/05.21/05.21.vcxproj new file mode 100644 index 0000000..53c36c0 --- /dev/null +++ b/VisualC++/ExerciseBook/05.21/05.21.vcxproj @@ -0,0 +1,80 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {2E30EE16-A652-4316-8FBC-6245559F35E3} + My0521 + + + + Application + true + MultiByte + + + Application + false + true + MultiByte + + + + + + + + + + + + + $(SolutionDir)\..\Status;$(IncludePath) + + + + Level3 + Disabled + + + true + $(SolutionDir)\..\Status\Status.lib;%(AdditionalDependencies) + Console + + + + + Level3 + MaxSpeed + true + true + + + true + true + true + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/05.21/05.21.vcxproj.filters b/VisualC++/ExerciseBook/05.21/05.21.vcxproj.filters new file mode 100644 index 0000000..149a548 --- /dev/null +++ b/VisualC++/ExerciseBook/05.21/05.21.vcxproj.filters @@ -0,0 +1,38 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + 源文件 + + + 源文件 + + + + + 头文件 + + + + + 资源文件 + + + 资源文件 + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/05.21/05.21.vcxproj.user b/VisualC++/ExerciseBook/05.21/05.21.vcxproj.user new file mode 100644 index 0000000..ace9a86 --- /dev/null +++ b/VisualC++/ExerciseBook/05.21/05.21.vcxproj.user @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/05.21/TSMatrix.c b/VisualC++/ExerciseBook/05.21/TSMatrix.c new file mode 100644 index 0000000..05eeaad --- /dev/null +++ b/VisualC++/ExerciseBook/05.21/TSMatrix.c @@ -0,0 +1,433 @@ +/*======================= + * Ԫ˳ϡ + * + * 㷨: 5.15.2 + ========================*/ + +#include "TSMatrix.h" //**05 ͹**// + +/* + * ϡM + * + * + *ע + * + * ̲Ĭϴӿ̨ȡݡ + * Ϊ˷ԣÿжֶݣ + * ѡԤļpathжȡݡ + * + * Ҫӿ̨ȡݣpathΪNULLΪմ + * ҪļжȡݣҪpathдļϢ + */ +Status CreateSMatrix(TSMatrix* M, char* path) { + int k; + FILE* fp; + int readFromConsole; // Ƿӿ̨ȡ + + // ûļ·Ϣӿ̨ȡ + readFromConsole = path == NULL || strcmp(path, "") == 0; + + // ûļ·Ϣӿ̨ȡ + if(readFromConsole) { + printf(""); + scanf("%d", &((*M).mu)); + printf(""); + scanf("%d", &((*M).nu)); + printf("Ԫظ"); + scanf("%d", &((*M).tu)); + printf("%dԪϢ\n", (*M).tu); + for(k = 1; k <= (*M).tu; k++) { + printf("%2d飺", k); + scanf("%d%d%d", &((*M).data[k].i), &((*M).data[k].j), &((*M).data[k].e)); + } + } else { + fp = fopen(path, "r"); + + ReadData(fp, "%d%d%d", &((*M).mu), &((*M).nu), &((*M).tu)); + + for(k = 1; k <= (*M).tu; k++) { + ReadData(fp, "%d%d%d", &((*M).data[k].i), &((*M).data[k].j), &((*M).data[k].e)); + } + + fclose(fp); + } + + return OK; +} + +/* + * ϡ + * + *ע + * Ԫ˳Ľṹ޷١ + */ +Status DestroySMatrix(TSMatrix* M) { + if(M == NULL) { + return ERROR; + } + + (*M).mu = 0; + (*M).nu = 0; + (*M).tu = 0; + + return OK; +} + +/* + * + * + * һ¾Tþ˴ӾMаݡ + */ +Status CopySMatrix(TSMatrix M, TSMatrix* T) { + (*T) = M; // ṹֱ֮ӸƣʹڲҲ + + return OK; +} + +/* + * ӷ + * + * Q = M + N + */ +Status AddSMatrix(TSMatrix M, TSMatrix N, TSMatrix* Q) { + int m, n, k; + + if(M.mu != N.mu || M.nu != N.nu) { + printf("\n"); + return ERROR; + } + + // ʼQ + (*Q).mu = M.mu; + (*Q).nu = M.nu; + (*Q).tu = 0; + + m = n = k = 1; + + // αMNԪ + while(m <= M.tu && n <= N.tu) { + // MеԪ±С + if(M.data[m].i < N.data[n].i) { + (*Q).data[k] = M.data[m]; + m++; + + // NеԪ±С + } else if(M.data[m].i > N.data[n].i) { + (*Q).data[k] = N.data[n]; + n++; + + // MNеԪ±һ£ҪһȽ + } else { + // MеԪ±С + if(M.data[m].j < N.data[n].j) { + (*Q).data[k] = M.data[m]; + m++; + + // NеԪ±С + } else if(M.data[m].j > N.data[n].j) { + (*Q).data[k] = N.data[n]; + n++; + + // MNеԪ±һ£Ҫмӷ + } else { + // ֵѾΪ0ĻҪ洢Ԫ + if((M.data[m].e + N.data[n].e) == 0) { + m++; + n++; + continue; + } else { + (*Q).data[k].i = M.data[m].i; + (*Q).data[k].j = M.data[m].j; + (*Q).data[k].e = M.data[m].e + N.data[n].e; + m++; + n++; + } + } + } + + k++; + (*Q).tu++; + } + + // MʣԪ + while(m <= M.tu) { + (*Q).data[k] = M.data[m]; + m++; + k++; + (*Q).tu++; + } + + // NʣԪ + while(n <= N.tu) { + (*Q).data[k] = N.data[n]; + n++; + k++; + (*Q).tu++; + } + + return OK; +} + +/* + * + * + * Q = M - N + */ +Status SubSMatrix(TSMatrix M, TSMatrix N, TSMatrix* Q) { + int m, n, k; + + if(M.mu != N.mu || M.nu != N.nu) { + printf("\n"); + return ERROR; + } + + // ʼQ + (*Q).mu = M.mu; + (*Q).nu = M.nu; + (*Q).tu = 0; + + m = n = k = 1; + + // αMNԪ + while(m <= M.tu && n <= N.tu) { + // MеԪ±С + if(M.data[m].i < N.data[n].i) { + (*Q).data[k] = M.data[m]; + m++; + + // NеԪ±С + } else if(M.data[m].i > N.data[n].i) { + (*Q).data[k].i = N.data[n].i; + (*Q).data[k].j = N.data[n].j; + (*Q).data[k].e = -N.data[n].e; // ҪԪֵȡ෴ + n++; + + // MNеԪ±һ£ҪһȽ + } else { + // MеԪ±С + if(M.data[m].j < N.data[n].j) { + (*Q).data[k] = M.data[m]; + m++; + + // NеԪ±С + } else if(M.data[m].j > N.data[n].j) { + (*Q).data[k].i = N.data[n].i; + (*Q).data[k].j = N.data[n].j; + (*Q).data[k].e = -N.data[n].e; // ҪԪֵȡ෴ + n++; + + // MNеԪ±һ£Ҫм + } else { + // ֵѾΪ0ĻҪ洢Ԫ + if((M.data[m].e - N.data[n].e) == 0) { + m++; + n++; + continue; + } else { + (*Q).data[k].i = M.data[m].i; + (*Q).data[k].j = M.data[m].j; + (*Q).data[k].e = M.data[m].e - N.data[n].e; + m++; + n++; + } + } + } + + k++; + (*Q).tu++; + } + + // MʣԪ + while(m <= M.tu) { + (*Q).data[k] = M.data[m]; + m++; + k++; + (*Q).tu++; + } + + // NʣԪ + while(n <= N.tu) { + (*Q).data[k].i = N.data[n].i; + (*Q).data[k].j = N.data[n].j; + (*Q).data[k].e = -N.data[n].e; + n++; + k++; + (*Q).tu++; + } + + return OK; +} + +/* + * ˷ + * + * Q = M * NʵֵǴͳ˷ + */ +Status MultSMatrix(TSMatrix M, TSMatrix N, TSMatrix* Q) { + int m, n, i, j, k; + ElemType c, c1, c2; + + // MҪN + if(M.nu != N.mu) { + printf("\n"); + return ERROR; + } + + // ʼQ + (*Q).mu = M.mu; + (*Q).nu = N.nu; + (*Q).tu = 0; + + // + if(M.tu * N.tu == 0) { + return OK; + } + + // M + for(i = 1; i <= M.mu; i++) { + // N + for(j = 1; j <= N.nu; j++) { + c = 0; + for(k = 1; k <= M.nu; k++) { + // ¼M[i][k]ֵ + c1 = 0; + // ѰλָλõMԪ + for(m = 1; m <= M.tu; m++) { + if(M.data[m].i == i && M.data[m].j == k) { + c1 = M.data[m].e; + break; + } + } + + // ¼N[k][j]ֵ + c2 = 0; + //ѰλָλõNԪ + for(n = 1; n <= N.tu; n++) { + if(N.data[n].i == k && N.data[n].j == j) { + c2 = N.data[n].e; + break; + } + } + + // Q[i][j]ֵ + if(c1 && c2) { + c += c1 * c2; + } + } + + // Ϊ0д洢 + if(c != 0) { + (*Q).tu++; + (*Q).data[(*Q).tu].i = i; + (*Q).data[(*Q).tu].j = j; + (*Q).data[(*Q).tu].e = c; + } + } + } + + return OK; +} + +/* + * 㷨5.1 + * + * ת + */ +Status TransposeSMatrix(TSMatrix M, TSMatrix* T) { + int p, q, col; + + (*T).mu = M.nu; + (*T).nu = M.mu; + (*T).tu = M.tu; + + if((*T).tu != 0) { + q = 1; // qTзԪļ + + // colMУT + for(col = 1; col <= M.nu; ++col) { + // MвҵjеԪأνתõT + for(p = 1; p <= M.tu; ++p) { + if(M.data[p].j == col) { + (*T).data[q].i = M.data[p].j; // MбΪT + (*T).data[q].j = M.data[p].i; // MбΪT + (*T).data[q].e = M.data[p].e; // ÿԪֵ + ++q; + } + } + } + } + + return OK; +} + +/* + * 㷨5.2 + * + * ת + */ +Status FastTransposeSMatrix(TSMatrix M, TSMatrix* T) { + int col, t, p, q; + int* num; // num[col] ʾMcolзԪĸ + int* copt; // copt[col]ʾMcolеһԪתúеλ + + (*T).mu = M.nu; + (*T).nu = M.mu; + (*T).tu = M.tu; + + // ǰ + if((*T).tu == 0) { + return ERROR; + } + + num = (int*) malloc(M.nu * sizeof(int)); + copt = (int*) malloc(M.nu * sizeof(int)); + + // ʼnum + for(col = 1; col <= M.nu; ++col) { + num[col] = 0; + } + + // ͳMеķԪͳÿзԪĸ + for(t = 1; t <= M.tu; ++t) { + num[M.data[t].j]++; + } + + // 1е1Ԫλתúеλ + copt[1] = 1; + // е1Ԫתþеλ + for(col = 2; col <= M.nu; ++col) { + copt[col] = copt[col - 1] + num[col - 1]; + } + + // ɨMеԪ + for(p = 1; p <= M.tu; ++p) { + col = M.data[p].j; // 㵱ǰԪ + q = copt[col]; // 㵱ǰԪתþеλ + (*T).data[q].i = M.data[p].j; + (*T).data[q].j = M.data[p].i; + (*T).data[q].e = M.data[p].e; + ++copt[col]; // ԪʱתþеλӦһòҪ + } + + return OK; +} + +/* + * + */ +void PrintSMatrix(TSMatrix M) { + int r, c; + int k = 1; + + for(r = 1; r <= M.mu; r++) { + for(c = 1; c <= M.nu; c++) { + if(r == M.data[k].i && c == M.data[k].j) { + printf("%3d ", M.data[k].e); + k++; + } else { + printf("%3d ", 0); + } + } + printf("\n"); + } +} diff --git a/VisualC++/ExerciseBook/05.21/TSMatrix.h b/VisualC++/ExerciseBook/05.21/TSMatrix.h new file mode 100644 index 0000000..52cdeea --- /dev/null +++ b/VisualC++/ExerciseBook/05.21/TSMatrix.h @@ -0,0 +1,107 @@ +/*======================= + * Ԫ˳ϡ + * + * 㷨: 5.15.2 + ========================*/ + +#ifndef TSMATRIX_H +#define TSMATRIX_H + +#include +#include // ṩ malloc ԭ +#include // ṩ strstr ԭ +#include "Status.h" //**01 **// + +/* + * Ԫֵ + * עֵҪIDEջڴ + */ +#define MAXSIZE 100 + +/* ԪϡԪ */ +typedef int ElemType; + +/* ԪͶ壬Ҫ洢Ԫ */ +typedef struct { + int i, j; // ԪԪ±± + ElemType e; +} Triple; + +/* ԪϡͶ */ +typedef struct { + Triple data[MAXSIZE + 1]; // ԪԪdata[0]δ + int mu, nu, tu; // ͷԪ +} TSMatrix; + + +/* + * ϡM + * + * + *ע + * + * ̲Ĭϴӿ̨ȡݡ + * Ϊ˷ԣÿжֶݣ + * ѡԤļpathжȡݡ + * + * Ҫӿ̨ȡݣpathΪNULLΪմ + * ҪļжȡݣҪpathдļϢ + */ +Status CreateSMatrix(TSMatrix* M, char* path); + +/* + * ϡ + * + *ע + * Ԫ˳Ľṹ޷١ + */ +Status DestroySMatrix(TSMatrix* M); + +/* + * + * + * һ¾Tþ˴ӾMаݡ + */ +Status CopySMatrix(TSMatrix M, TSMatrix* T); + +/* + * ӷ + * + * Q = M + N + */ +Status AddSMatrix(TSMatrix M, TSMatrix N, TSMatrix* Q); + +/* + * + * + * Q = M - N + */ +Status SubSMatrix(TSMatrix M, TSMatrix N, TSMatrix* Q); + +/* + * ˷ + * + * Q = M * NʵֵǴͳ˷ + */ +Status MultSMatrix(TSMatrix M, TSMatrix N, TSMatrix* Q); + +/* + * 㷨5.1 + * + * ת + */ +Status TransposeSMatrix(TSMatrix M, TSMatrix* T); + +/* + * 㷨5.2 + * + * ת + */ +Status FastTransposeSMatrix(TSMatrix M, TSMatrix* T); + +/* + * + */ +void PrintSMatrix(TSMatrix M); + +#endif diff --git a/VisualC++/ExerciseBook/05.21/TestData_A.txt b/VisualC++/ExerciseBook/05.21/TestData_A.txt new file mode 100644 index 0000000..be25c94 --- /dev/null +++ b/VisualC++/ExerciseBook/05.21/TestData_A.txt @@ -0,0 +1,4 @@ +5 +5 +Ԫ10 +Ԫ飺(1,2,1),(1,4,5),(2,3,-3),(2,5,2),(3,1,2),(3,2,3),(3,3,4),(4,4,2),(5,1,3),(5,2,-1) \ No newline at end of file diff --git a/VisualC++/ExerciseBook/05.21/TestData_B.txt b/VisualC++/ExerciseBook/05.21/TestData_B.txt new file mode 100644 index 0000000..7c940db --- /dev/null +++ b/VisualC++/ExerciseBook/05.21/TestData_B.txt @@ -0,0 +1,4 @@ +5 +5 +Ԫ8 +Ԫ飺(1,1,-3)(1,3,2)(2,4,-1)(3,2,4)(4,1,6)(4,5,5)(5,1,3)(5,3,2) \ No newline at end of file diff --git a/VisualC++/ExerciseBook/05.22/05.22.c b/VisualC++/ExerciseBook/05.22/05.22.c new file mode 100644 index 0000000..6ee74f7 --- /dev/null +++ b/VisualC++/ExerciseBook/05.22/05.22.c @@ -0,0 +1,106 @@ +#include +#include "Status.h" //**01 **// +#include "TSMatrix.h" //**05 ͹**// + +/* + * ϡӷAddSMatrix + * + *ע + * Ҫ浽ԭA + */ +Status Algo_5_22(TSMatrix* A, TSMatrix B); + + +int main(int argc, char* argv[]) { + TSMatrix A, B; + + printf(" ϡ AB ...\n"); + CreateSMatrix(&A, "TestData_A.txt"); + CreateSMatrix(&B, "TestData_B.txt"); + printf(" A = \n"); + PrintSMatrix(A); + printf(" B = \n"); + PrintSMatrix(B); + + // + Algo_5_22(&A, B); + + printf(" A = A + B = \n"); + PrintSMatrix(A); + + return 0; +} + + +/* + * ϡӷAddSMatrix + * + *ע + * Ҫ浽ԭA + */ +Status Algo_5_22(TSMatrix* A, TSMatrix B) { + int m, n, k; + + if((*A).mu != B.mu || (*A).nu != B.nu) { + printf("\n"); + return ERROR; + } + + // AԪƶƶΪBԪظ + for(k = (*A).tu; k > 0; k--) { + (*A).data[k + B.tu] = (*A).data[k]; + } + + m = B.tu + 1; // A + n = 1; // B + k = 0; // ָα + + // αABԪ + while(m <= (*A).tu + B.tu && n <= B.tu) { + // AеԪ±С + if((*A).data[m].i < B.data[n].i) { + (*A).data[++k] = (*A).data[m++]; + + // BеԪ±С + } else if((*A).data[m].i > B.data[n].i) { + (*A).data[++k] = B.data[n++]; + + // ABеԪ±һ£ҪһȽ + } else { + // AеԪ±С + if((*A).data[m].j < B.data[n].j) { + (*A).data[++k] = (*A).data[m++]; + + // BеԪ±С + } else if((*A).data[m].j > B.data[n].j) { + (*A).data[++k] = B.data[n++]; + + // ABеԪ±һ£Ҫмӷ + } else { + // ֵΪ0ʱҪ洢Ԫ + if(((*A).data[m].e + B.data[n].e) != 0) { + k++; + (*A).data[k].i = (*A).data[m].i; + (*A).data[k].j = (*A).data[m].j; + (*A).data[k].e = (*A).data[m].e + B.data[n].e; + } + m++; + n++; + } + } + } + + // AʣԪ + while(m <= (*A).tu + B.tu) { + (*A).data[++k] = (*A).data[m++]; + } + + // BʣԪ + while(n <= B.tu) { + (*A).data[++k] = B.data[n++]; + } + + (*A).tu = k; + + return OK; +} diff --git a/VisualC++/ExerciseBook/05.22/05.22.vcxproj b/VisualC++/ExerciseBook/05.22/05.22.vcxproj new file mode 100644 index 0000000..ce921a8 --- /dev/null +++ b/VisualC++/ExerciseBook/05.22/05.22.vcxproj @@ -0,0 +1,80 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {AF31443B-830F-4A4C-A72D-40FC9ACE5654} + My0522 + + + + Application + true + MultiByte + + + Application + false + true + MultiByte + + + + + + + + + + + + + $(SolutionDir)\..\Status;$(IncludePath) + + + + Level3 + Disabled + + + true + $(SolutionDir)\..\Status\Status.lib;%(AdditionalDependencies) + Console + + + + + Level3 + MaxSpeed + true + true + + + true + true + true + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/05.22/05.22.vcxproj.filters b/VisualC++/ExerciseBook/05.22/05.22.vcxproj.filters new file mode 100644 index 0000000..4260a59 --- /dev/null +++ b/VisualC++/ExerciseBook/05.22/05.22.vcxproj.filters @@ -0,0 +1,38 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + 源文件 + + + 源文件 + + + + + 资源文件 + + + 资源文件 + + + + + 头文件 + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/05.22/05.22.vcxproj.user b/VisualC++/ExerciseBook/05.22/05.22.vcxproj.user new file mode 100644 index 0000000..ace9a86 --- /dev/null +++ b/VisualC++/ExerciseBook/05.22/05.22.vcxproj.user @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/05.22/TSMatrix.c b/VisualC++/ExerciseBook/05.22/TSMatrix.c new file mode 100644 index 0000000..05eeaad --- /dev/null +++ b/VisualC++/ExerciseBook/05.22/TSMatrix.c @@ -0,0 +1,433 @@ +/*======================= + * Ԫ˳ϡ + * + * 㷨: 5.15.2 + ========================*/ + +#include "TSMatrix.h" //**05 ͹**// + +/* + * ϡM + * + * + *ע + * + * ̲Ĭϴӿ̨ȡݡ + * Ϊ˷ԣÿжֶݣ + * ѡԤļpathжȡݡ + * + * Ҫӿ̨ȡݣpathΪNULLΪմ + * ҪļжȡݣҪpathдļϢ + */ +Status CreateSMatrix(TSMatrix* M, char* path) { + int k; + FILE* fp; + int readFromConsole; // Ƿӿ̨ȡ + + // ûļ·Ϣӿ̨ȡ + readFromConsole = path == NULL || strcmp(path, "") == 0; + + // ûļ·Ϣӿ̨ȡ + if(readFromConsole) { + printf(""); + scanf("%d", &((*M).mu)); + printf(""); + scanf("%d", &((*M).nu)); + printf("Ԫظ"); + scanf("%d", &((*M).tu)); + printf("%dԪϢ\n", (*M).tu); + for(k = 1; k <= (*M).tu; k++) { + printf("%2d飺", k); + scanf("%d%d%d", &((*M).data[k].i), &((*M).data[k].j), &((*M).data[k].e)); + } + } else { + fp = fopen(path, "r"); + + ReadData(fp, "%d%d%d", &((*M).mu), &((*M).nu), &((*M).tu)); + + for(k = 1; k <= (*M).tu; k++) { + ReadData(fp, "%d%d%d", &((*M).data[k].i), &((*M).data[k].j), &((*M).data[k].e)); + } + + fclose(fp); + } + + return OK; +} + +/* + * ϡ + * + *ע + * Ԫ˳Ľṹ޷١ + */ +Status DestroySMatrix(TSMatrix* M) { + if(M == NULL) { + return ERROR; + } + + (*M).mu = 0; + (*M).nu = 0; + (*M).tu = 0; + + return OK; +} + +/* + * + * + * һ¾Tþ˴ӾMаݡ + */ +Status CopySMatrix(TSMatrix M, TSMatrix* T) { + (*T) = M; // ṹֱ֮ӸƣʹڲҲ + + return OK; +} + +/* + * ӷ + * + * Q = M + N + */ +Status AddSMatrix(TSMatrix M, TSMatrix N, TSMatrix* Q) { + int m, n, k; + + if(M.mu != N.mu || M.nu != N.nu) { + printf("\n"); + return ERROR; + } + + // ʼQ + (*Q).mu = M.mu; + (*Q).nu = M.nu; + (*Q).tu = 0; + + m = n = k = 1; + + // αMNԪ + while(m <= M.tu && n <= N.tu) { + // MеԪ±С + if(M.data[m].i < N.data[n].i) { + (*Q).data[k] = M.data[m]; + m++; + + // NеԪ±С + } else if(M.data[m].i > N.data[n].i) { + (*Q).data[k] = N.data[n]; + n++; + + // MNеԪ±һ£ҪһȽ + } else { + // MеԪ±С + if(M.data[m].j < N.data[n].j) { + (*Q).data[k] = M.data[m]; + m++; + + // NеԪ±С + } else if(M.data[m].j > N.data[n].j) { + (*Q).data[k] = N.data[n]; + n++; + + // MNеԪ±һ£Ҫмӷ + } else { + // ֵѾΪ0ĻҪ洢Ԫ + if((M.data[m].e + N.data[n].e) == 0) { + m++; + n++; + continue; + } else { + (*Q).data[k].i = M.data[m].i; + (*Q).data[k].j = M.data[m].j; + (*Q).data[k].e = M.data[m].e + N.data[n].e; + m++; + n++; + } + } + } + + k++; + (*Q).tu++; + } + + // MʣԪ + while(m <= M.tu) { + (*Q).data[k] = M.data[m]; + m++; + k++; + (*Q).tu++; + } + + // NʣԪ + while(n <= N.tu) { + (*Q).data[k] = N.data[n]; + n++; + k++; + (*Q).tu++; + } + + return OK; +} + +/* + * + * + * Q = M - N + */ +Status SubSMatrix(TSMatrix M, TSMatrix N, TSMatrix* Q) { + int m, n, k; + + if(M.mu != N.mu || M.nu != N.nu) { + printf("\n"); + return ERROR; + } + + // ʼQ + (*Q).mu = M.mu; + (*Q).nu = M.nu; + (*Q).tu = 0; + + m = n = k = 1; + + // αMNԪ + while(m <= M.tu && n <= N.tu) { + // MеԪ±С + if(M.data[m].i < N.data[n].i) { + (*Q).data[k] = M.data[m]; + m++; + + // NеԪ±С + } else if(M.data[m].i > N.data[n].i) { + (*Q).data[k].i = N.data[n].i; + (*Q).data[k].j = N.data[n].j; + (*Q).data[k].e = -N.data[n].e; // ҪԪֵȡ෴ + n++; + + // MNеԪ±һ£ҪһȽ + } else { + // MеԪ±С + if(M.data[m].j < N.data[n].j) { + (*Q).data[k] = M.data[m]; + m++; + + // NеԪ±С + } else if(M.data[m].j > N.data[n].j) { + (*Q).data[k].i = N.data[n].i; + (*Q).data[k].j = N.data[n].j; + (*Q).data[k].e = -N.data[n].e; // ҪԪֵȡ෴ + n++; + + // MNеԪ±һ£Ҫм + } else { + // ֵѾΪ0ĻҪ洢Ԫ + if((M.data[m].e - N.data[n].e) == 0) { + m++; + n++; + continue; + } else { + (*Q).data[k].i = M.data[m].i; + (*Q).data[k].j = M.data[m].j; + (*Q).data[k].e = M.data[m].e - N.data[n].e; + m++; + n++; + } + } + } + + k++; + (*Q).tu++; + } + + // MʣԪ + while(m <= M.tu) { + (*Q).data[k] = M.data[m]; + m++; + k++; + (*Q).tu++; + } + + // NʣԪ + while(n <= N.tu) { + (*Q).data[k].i = N.data[n].i; + (*Q).data[k].j = N.data[n].j; + (*Q).data[k].e = -N.data[n].e; + n++; + k++; + (*Q).tu++; + } + + return OK; +} + +/* + * ˷ + * + * Q = M * NʵֵǴͳ˷ + */ +Status MultSMatrix(TSMatrix M, TSMatrix N, TSMatrix* Q) { + int m, n, i, j, k; + ElemType c, c1, c2; + + // MҪN + if(M.nu != N.mu) { + printf("\n"); + return ERROR; + } + + // ʼQ + (*Q).mu = M.mu; + (*Q).nu = N.nu; + (*Q).tu = 0; + + // + if(M.tu * N.tu == 0) { + return OK; + } + + // M + for(i = 1; i <= M.mu; i++) { + // N + for(j = 1; j <= N.nu; j++) { + c = 0; + for(k = 1; k <= M.nu; k++) { + // ¼M[i][k]ֵ + c1 = 0; + // ѰλָλõMԪ + for(m = 1; m <= M.tu; m++) { + if(M.data[m].i == i && M.data[m].j == k) { + c1 = M.data[m].e; + break; + } + } + + // ¼N[k][j]ֵ + c2 = 0; + //ѰλָλõNԪ + for(n = 1; n <= N.tu; n++) { + if(N.data[n].i == k && N.data[n].j == j) { + c2 = N.data[n].e; + break; + } + } + + // Q[i][j]ֵ + if(c1 && c2) { + c += c1 * c2; + } + } + + // Ϊ0д洢 + if(c != 0) { + (*Q).tu++; + (*Q).data[(*Q).tu].i = i; + (*Q).data[(*Q).tu].j = j; + (*Q).data[(*Q).tu].e = c; + } + } + } + + return OK; +} + +/* + * 㷨5.1 + * + * ת + */ +Status TransposeSMatrix(TSMatrix M, TSMatrix* T) { + int p, q, col; + + (*T).mu = M.nu; + (*T).nu = M.mu; + (*T).tu = M.tu; + + if((*T).tu != 0) { + q = 1; // qTзԪļ + + // colMУT + for(col = 1; col <= M.nu; ++col) { + // MвҵjеԪأνתõT + for(p = 1; p <= M.tu; ++p) { + if(M.data[p].j == col) { + (*T).data[q].i = M.data[p].j; // MбΪT + (*T).data[q].j = M.data[p].i; // MбΪT + (*T).data[q].e = M.data[p].e; // ÿԪֵ + ++q; + } + } + } + } + + return OK; +} + +/* + * 㷨5.2 + * + * ת + */ +Status FastTransposeSMatrix(TSMatrix M, TSMatrix* T) { + int col, t, p, q; + int* num; // num[col] ʾMcolзԪĸ + int* copt; // copt[col]ʾMcolеһԪתúеλ + + (*T).mu = M.nu; + (*T).nu = M.mu; + (*T).tu = M.tu; + + // ǰ + if((*T).tu == 0) { + return ERROR; + } + + num = (int*) malloc(M.nu * sizeof(int)); + copt = (int*) malloc(M.nu * sizeof(int)); + + // ʼnum + for(col = 1; col <= M.nu; ++col) { + num[col] = 0; + } + + // ͳMеķԪͳÿзԪĸ + for(t = 1; t <= M.tu; ++t) { + num[M.data[t].j]++; + } + + // 1е1Ԫλתúеλ + copt[1] = 1; + // е1Ԫתþеλ + for(col = 2; col <= M.nu; ++col) { + copt[col] = copt[col - 1] + num[col - 1]; + } + + // ɨMеԪ + for(p = 1; p <= M.tu; ++p) { + col = M.data[p].j; // 㵱ǰԪ + q = copt[col]; // 㵱ǰԪתþеλ + (*T).data[q].i = M.data[p].j; + (*T).data[q].j = M.data[p].i; + (*T).data[q].e = M.data[p].e; + ++copt[col]; // ԪʱתþеλӦһòҪ + } + + return OK; +} + +/* + * + */ +void PrintSMatrix(TSMatrix M) { + int r, c; + int k = 1; + + for(r = 1; r <= M.mu; r++) { + for(c = 1; c <= M.nu; c++) { + if(r == M.data[k].i && c == M.data[k].j) { + printf("%3d ", M.data[k].e); + k++; + } else { + printf("%3d ", 0); + } + } + printf("\n"); + } +} diff --git a/VisualC++/ExerciseBook/05.22/TSMatrix.h b/VisualC++/ExerciseBook/05.22/TSMatrix.h new file mode 100644 index 0000000..52cdeea --- /dev/null +++ b/VisualC++/ExerciseBook/05.22/TSMatrix.h @@ -0,0 +1,107 @@ +/*======================= + * Ԫ˳ϡ + * + * 㷨: 5.15.2 + ========================*/ + +#ifndef TSMATRIX_H +#define TSMATRIX_H + +#include +#include // ṩ malloc ԭ +#include // ṩ strstr ԭ +#include "Status.h" //**01 **// + +/* + * Ԫֵ + * עֵҪIDEջڴ + */ +#define MAXSIZE 100 + +/* ԪϡԪ */ +typedef int ElemType; + +/* ԪͶ壬Ҫ洢Ԫ */ +typedef struct { + int i, j; // ԪԪ±± + ElemType e; +} Triple; + +/* ԪϡͶ */ +typedef struct { + Triple data[MAXSIZE + 1]; // ԪԪdata[0]δ + int mu, nu, tu; // ͷԪ +} TSMatrix; + + +/* + * ϡM + * + * + *ע + * + * ̲Ĭϴӿ̨ȡݡ + * Ϊ˷ԣÿжֶݣ + * ѡԤļpathжȡݡ + * + * Ҫӿ̨ȡݣpathΪNULLΪմ + * ҪļжȡݣҪpathдļϢ + */ +Status CreateSMatrix(TSMatrix* M, char* path); + +/* + * ϡ + * + *ע + * Ԫ˳Ľṹ޷١ + */ +Status DestroySMatrix(TSMatrix* M); + +/* + * + * + * һ¾Tþ˴ӾMаݡ + */ +Status CopySMatrix(TSMatrix M, TSMatrix* T); + +/* + * ӷ + * + * Q = M + N + */ +Status AddSMatrix(TSMatrix M, TSMatrix N, TSMatrix* Q); + +/* + * + * + * Q = M - N + */ +Status SubSMatrix(TSMatrix M, TSMatrix N, TSMatrix* Q); + +/* + * ˷ + * + * Q = M * NʵֵǴͳ˷ + */ +Status MultSMatrix(TSMatrix M, TSMatrix N, TSMatrix* Q); + +/* + * 㷨5.1 + * + * ת + */ +Status TransposeSMatrix(TSMatrix M, TSMatrix* T); + +/* + * 㷨5.2 + * + * ת + */ +Status FastTransposeSMatrix(TSMatrix M, TSMatrix* T); + +/* + * + */ +void PrintSMatrix(TSMatrix M); + +#endif diff --git a/VisualC++/ExerciseBook/05.22/TestData_A.txt b/VisualC++/ExerciseBook/05.22/TestData_A.txt new file mode 100644 index 0000000..be25c94 --- /dev/null +++ b/VisualC++/ExerciseBook/05.22/TestData_A.txt @@ -0,0 +1,4 @@ +5 +5 +Ԫ10 +Ԫ飺(1,2,1),(1,4,5),(2,3,-3),(2,5,2),(3,1,2),(3,2,3),(3,3,4),(4,4,2),(5,1,3),(5,2,-1) \ No newline at end of file diff --git a/VisualC++/ExerciseBook/05.22/TestData_B.txt b/VisualC++/ExerciseBook/05.22/TestData_B.txt new file mode 100644 index 0000000..7c940db --- /dev/null +++ b/VisualC++/ExerciseBook/05.22/TestData_B.txt @@ -0,0 +1,4 @@ +5 +5 +Ԫ8 +Ԫ飺(1,1,-3)(1,3,2)(2,4,-1)(3,2,4)(4,1,6)(4,5,5)(5,1,3)(5,3,2) \ No newline at end of file diff --git a/VisualC++/ExerciseBook/05.23/05.23.c b/VisualC++/ExerciseBook/05.23/05.23.c new file mode 100644 index 0000000..27818c4 --- /dev/null +++ b/VisualC++/ExerciseBook/05.23/05.23.c @@ -0,0 +1,52 @@ +#include +#include "Status.h" //**01 **// +#include "RLSMatrix.h" //**05 ͹**// + +/* + * ȡеiеjеԪأ洢e + */ +Status Algo_5_23(RLSMatrix M, int i, int j, int* e); + + +int main(int argc, char* argv[]) { + RLSMatrix M; + int e; + + printf(" ϡ M ...\n"); + CreateSMatrix(&M, "TestData_M.txt"); + printf("M = \n"); + PrintSMatrix(M); + + Algo_5_23(M, 2, 3, &e); + printf(" %d %d еԪΪ %d\n", 2, 3, e); + + return 0; +} + + +/* + * ȡеiеjеԪأ洢e + */ +Status Algo_5_23(RLSMatrix M, int i, int j, int* e) { + int begin, end, k; + + if(i < 1 || i > M.mu || j < 1 || j > M.nu) { + return ERROR; + } + + // ȡi׸ԪԪеλ + begin = M.rpos[i]; + end = (i == M.mu ? M.tu : M.rpos[i + 1] - 1); + + *e = 0; // ĬΪ0 + + for(k = begin; k <= end; k++) { + // ҵӦ±Ԫ + if(M.data[k].j == j) { + *e = M.data[k].e; + break; + } + } + + return OK; +} diff --git a/VisualC++/ExerciseBook/05.23/05.23.vcxproj b/VisualC++/ExerciseBook/05.23/05.23.vcxproj new file mode 100644 index 0000000..b9cd533 --- /dev/null +++ b/VisualC++/ExerciseBook/05.23/05.23.vcxproj @@ -0,0 +1,79 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {D342BB95-DAA3-4C66-889A-9DC49DA213B0} + My0523 + + + + Application + true + MultiByte + + + Application + false + true + MultiByte + + + + + + + + + + + + + $(SolutionDir)\..\Status;$(IncludePath) + + + + Level3 + Disabled + + + true + $(SolutionDir)\..\Status\Status.lib;%(AdditionalDependencies) + Console + + + + + Level3 + MaxSpeed + true + true + + + true + true + true + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/05.23/05.23.vcxproj.filters b/VisualC++/ExerciseBook/05.23/05.23.vcxproj.filters new file mode 100644 index 0000000..ec899ed --- /dev/null +++ b/VisualC++/ExerciseBook/05.23/05.23.vcxproj.filters @@ -0,0 +1,35 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + 源文件 + + + 源文件 + + + + + 头文件 + + + + + 资源文件 + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/05.23/05.23.vcxproj.user b/VisualC++/ExerciseBook/05.23/05.23.vcxproj.user new file mode 100644 index 0000000..ace9a86 --- /dev/null +++ b/VisualC++/ExerciseBook/05.23/05.23.vcxproj.user @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/05.23/RLSMatrix.c b/VisualC++/ExerciseBook/05.23/RLSMatrix.c new file mode 100644 index 0000000..5d28a0e --- /dev/null +++ b/VisualC++/ExerciseBook/05.23/RLSMatrix.c @@ -0,0 +1,515 @@ +/*============================= + * ߼ӵ˳ϡ + * + * 㷨: 5.3 + ==============================*/ + +#include "RLSMatrix.h" //**05 ͹**// + +/* + * ϡM + * + * + *ע + * + * ̲Ĭϴӿ̨ȡݡ + * Ϊ˷ԣÿжֶݣ + * ѡԤļpathжȡݡ + * + * Ҫӿ̨ȡݣpathΪNULLΪմ + * ҪļжȡݣҪpathдļϢ + */ +Status CreateSMatrix(RLSMatrix* M, char* path) { + int k; + FILE* fp; + int readFromConsole; // Ƿӿ̨ȡ + + // ûļ·Ϣӿ̨ȡ + readFromConsole = path == NULL || strcmp(path, "") == 0; + + // ûļ·Ϣӿ̨ȡ + if(readFromConsole) { + printf(""); + scanf("%d", &((*M).mu)); + printf(""); + scanf("%d", &((*M).nu)); + printf("Ԫظ"); + scanf("%d", &((*M).tu)); + printf("%dԪϢ\n", (*M).tu); + for(k = 1; k <= (*M).tu; k++) { + printf("%2d飺", k); + scanf("%d%d%d", &((*M).data[k].i), &((*M).data[k].j), &((*M).data[k].e)); + } + } else { + fp = fopen(path, "r"); + + ReadData(fp, "%d%d%d", &((*M).mu), &((*M).nu), &((*M).tu)); + + for(k = 1; k <= (*M).tu; k++) { + ReadData(fp, "%d%d%d", &((*M).data[k].i), &((*M).data[k].j), &((*M).data[k].e)); + } + + fclose(fp); + } + + // Ϊrpos鸳ֵ + AssignRpos(M); + + return OK; +} + +/* + * ϡ + * + *ע + * ߼ӵ˳ṹ޷١ + */ +Status DestroySMatrix(RLSMatrix* M) { + int i; + + if(M == NULL) { + return ERROR; + } + + M->mu = 0; + M->nu = 0; + M->tu = 0; + + for(i = 0; i <= MAXRC; ++i) { + M->rpos[i] = 0; + } + + return OK; +} + +/* + * + * + * һ¾Tþ˴ӾMаݡ + */ +Status CopySMatrix(RLSMatrix M, RLSMatrix* T) { + (*T) = M; // ṹֱ֮ӸƣʹڲҲ + + return OK; +} + +/* + * ӷ + * + * Q = M + N + */ +Status AddSMatrix(RLSMatrix M, RLSMatrix N, RLSMatrix* Q) { + int m, n, k; + + if(M.mu != N.mu || M.nu != N.nu) { + printf("\n"); + return ERROR; + } + + // ʼQϢ + (*Q).mu = M.mu; + (*Q).nu = M.nu; + (*Q).tu = 0; + + m = n = k = 1; + + // αMNԪ + while(m <= M.tu && n <= N.tu) { + // MеԪ±С + if(M.data[m].i < N.data[n].i) { + (*Q).data[k] = M.data[m]; + m++; + + // NеԪ±С + } else if(M.data[m].i > N.data[n].i) { + (*Q).data[k] = N.data[n]; + n++; + + // MNеԪ±һ£ҪһȽ + } else { + // MеԪ±С + if(M.data[m].j < N.data[n].j) { + (*Q).data[k] = M.data[m]; + m++; + + // NеԪ±С + } else if(M.data[m].j > N.data[n].j) { + (*Q).data[k] = N.data[n]; + n++; + + // MNеԪ±һ£Ҫмӷ + } else { + // ֵѾΪ0ĻҪ洢Ԫ + if((M.data[m].e + N.data[n].e) == 0) { + m++; + n++; + continue; + } else { + (*Q).data[k].i = M.data[m].i; + (*Q).data[k].j = M.data[m].j; + (*Q).data[k].e = M.data[m].e + N.data[n].e; + m++; + n++; + } + } + } + + k++; + (*Q).tu++; + } + + // MʣԪ + while(m <= M.tu) { + (*Q).data[k] = M.data[m]; + m++; + k++; + (*Q).tu++; + } + + // NʣԪ + while(n <= N.tu) { + (*Q).data[k] = N.data[n]; + n++; + k++; + (*Q).tu++; + } + + // Ϊrpos鸳ֵ + AssignRpos(Q); + + return OK; +} + +/* + * + * + * Q = M - N + */ +Status SubSMatrix(RLSMatrix M, RLSMatrix N, RLSMatrix* Q) { + int m, n, k; + + if(M.mu != N.mu || M.nu != N.nu) { + printf("\n"); + return ERROR; + } + + // ʼQϢ + (*Q).mu = M.mu; + (*Q).nu = M.nu; + (*Q).tu = 0; + + m = n = k = 1; + + // αMNԪ + while(m <= M.tu && n <= N.tu) { + // MеԪ±С + if(M.data[m].i < N.data[n].i) { + (*Q).data[k] = M.data[m]; + m++; + + // NеԪ±С + } else if(M.data[m].i > N.data[n].i) { + (*Q).data[k].i = N.data[n].i; + (*Q).data[k].j = N.data[n].j; + (*Q).data[k].e = -N.data[n].e; // ҪԪֵȡ෴ + n++; + + // MNеԪ±һ£ҪһȽ + } else { + // MеԪ±С + if(M.data[m].j < N.data[n].j) { + (*Q).data[k] = M.data[m]; + m++; + + // NеԪ±С + } else if(M.data[m].j > N.data[n].j) { + (*Q).data[k].i = N.data[n].i; + (*Q).data[k].j = N.data[n].j; + (*Q).data[k].e = -N.data[n].e; // ҪԪֵȡ෴ + n++; + + // MNеԪ±һ£Ҫм + } else { + // ֵѾΪ0ĻҪ洢Ԫ + if((M.data[m].e - N.data[n].e) == 0) { + m++; + n++; + continue; + } else { + (*Q).data[k].i = M.data[m].i; + (*Q).data[k].j = M.data[m].j; + (*Q).data[k].e = M.data[m].e - N.data[n].e; + m++; + n++; + } + } + } + + k++; + (*Q).tu++; + } + + // MʣԪ + while(m <= M.tu) { + (*Q).data[k] = M.data[m]; + m++; + k++; + (*Q).tu++; + } + + // NʣԪ + while(n <= N.tu) { + (*Q).data[k].i = N.data[n].i; + (*Q).data[k].j = N.data[n].j; + (*Q).data[k].e = -N.data[n].e; + n++; + k++; + (*Q).tu++; + } + + // Ϊrpos鸳ֵ + AssignRpos(Q); + + return OK; +} + +/* + * 㷨5.3 + * + * ˷ + * + * Q = M * N + */ +Status MultSMatrix(RLSMatrix M, RLSMatrix N, RLSMatrix* Q) { + int arow, p, tp; + int brow, q, tq; + int ccol; + int* ctemp; // QиԪֵۼctemp[0]Ԫ + int i; + + // MҪN + if(M.nu != N.mu) { + printf("\n"); + return ERROR; + } + + // ʼQϢ + (*Q).mu = M.mu; + (*Q).nu = N.nu; + (*Q).tu = 0; + + // + if(M.tu * N.tu == 0) { + return OK; + } + + ctemp = (int*) malloc((N.nu + 1) * sizeof(int)); + + // Mÿһ + for(arow = 1; arow <= M.mu; ++arow) { + // ʼQԪֵ + for(i = 0; i <= N.nu; ++i) { + ctemp[i] = 0; + } + + // tpָMǰеһеһԪλ + if(arow < M.mu) { + tp = M.rpos[arow + 1]; + } else { + tp = M.tu + 1; + } + + // MarowезԪ + for(p = M.rpos[arow]; p < tp; ++p) { + // ȡ÷ԪNек + brow = M.data[p].j; + + // tqָNǰеһеһԪλ + if(brow < N.mu) { + tq = N.rpos[brow + 1]; + } else { + tq = N.tu + 1; + } + + // NbrowезԪ + for(q = N.rpos[brow]; q < tq; ++q) { + // ˻ԪQек + ccol = N.data[q].j; + + // ۼӳ˻ + ctemp[ccol] += M.data[p].e * N.data[q].e; + } + } + + /* + * ˣQеarowԪ + */ + + // ij˻ѡȡԪQ + for(ccol = 1; ccol <= (*Q).nu; ++ccol) { + // QеarowccolԪزΪ0 + if(ctemp[ccol]) { + ++(*Q).tu; + + // Ԫ + if((*Q).tu > MAXSIZE) { + return ERROR; + } + + (*Q).data[(*Q).tu].i = arow; + (*Q).data[(*Q).tu].j = ccol; + (*Q).data[(*Q).tu].e = ctemp[ccol]; + } + } + } + + // Ϊrpos鸳ֵ + AssignRpos(Q); + + return OK; +} + +/* + * ת + */ +Status TransposeSMatrix(RLSMatrix M, RLSMatrix* T) { + int p, q, col; + + (*T).mu = M.nu; + (*T).nu = M.mu; + (*T).tu = M.tu; + + if((*T).tu) { + q = 1; // qTзԪļ + + // colMУT + for(col = 1; col <= M.nu; ++col) { + // MвҵjеԪأνתõT + for(p = 1; p <= M.tu; ++p) { + if(M.data[p].j == col) { + (*T).data[q].i = M.data[p].j; // MбΪT + (*T).data[q].j = M.data[p].i; // MбΪT + (*T).data[q].e = M.data[p].e; // ÿԪֵ + + ++q; + } + } + } + } + + // Ϊrpos鸳ֵ + AssignRpos(T); + + return OK; +} + +/* + * ת + */ +Status FastTransposeSMatrix(RLSMatrix M, RLSMatrix* T) { + int col, t, p, q; + int* num; // num[col] ʾMcolзԪĸ + int* copt; // copt[col]ʾMcolеһԪתúеλ + + (*T).mu = M.nu; + (*T).nu = M.mu; + (*T).tu = M.tu; + + // ǰ + if((*T).tu == 0) { + return ERROR; + } + + num = (int*) malloc(M.nu * sizeof(int)); + copt = (int*) malloc(M.nu * sizeof(int)); + + // ʼnum + for(col = 1; col <= M.nu; ++col) { + num[col] = 0; + } + + // ͳMеķԪͳÿзԪĸ + for(t = 1; t <= M.tu; ++t) { + num[M.data[t].j]++; + } + + // 1е1Ԫλתúеλ + copt[1] = 1; + // е1Ԫתþеλ + for(col = 2; col <= M.nu; ++col) { + copt[col] = copt[col - 1] + num[col - 1]; + } + + // ɨMеԪ + for(p = 1; p <= M.tu; ++p) { + col = M.data[p].j; // 㵱ǰԪ + q = copt[col]; // 㵱ǰԪתþеλ + (*T).data[q].i = M.data[p].j; + (*T).data[q].j = M.data[p].i; + (*T).data[q].e = M.data[p].e; + ++copt[col]; // ԪʱתþеλӦһòҪ + } + + // Ϊrpos鸳ֵ + AssignRpos(T); + + return OK; +} + +/* + * + */ +void PrintSMatrix(RLSMatrix M) { + int r, c; + int k = 1; + + for(r = 1; r <= M.mu; ++r) { + for(c = 1; c <= M.nu; ++c) { + if(r == M.data[k].i && c == M.data[k].j) { + printf("%3d ", M.data[k].e); + k++; + } else { + printf("%3d ", 0); + } + } + printf("\n"); + } + + printf("rpos = "); + for(k = 1; k <= M.mu; ++k) { + printf("%d ", M.rpos[k]); + } + printf("\n"); +} + +// Ϊrpos鸳ֵ +static void AssignRpos(RLSMatrix* M) { + int k, m; + + // ʼrpos + for(k = 0; k <= MAXRC; ++k) { + (*M).rpos[k] = 0; + } + + for(k = 1; k <= (*M).tu; k++) { + m = (*M).data[k].i; // ǰԪԪھеλ + + // ¼ÿеһԪԪеλ + if((*M).rpos[m] == 0) { + (*M).rpos[m] = k; // ֻڵǰзԪ¼¼ + } + } + + // ЩûзԪ + for(k = (*M).mu; k >= 1; k--) { + // ǰûзԪ˴ֱȡһеIJ + if((*M).rpos[k] == 0) { + // һ޷ԪΪѾһˣ⴦ + if(k == (*M).mu) { + (*M).rpos[k] = (*M).tu + 1; + } else { + (*M).rpos[k] = (*M).rpos[k + 1]; + } + } + } +} diff --git a/VisualC++/ExerciseBook/05.23/RLSMatrix.h b/VisualC++/ExerciseBook/05.23/RLSMatrix.h new file mode 100644 index 0000000..0550c13 --- /dev/null +++ b/VisualC++/ExerciseBook/05.23/RLSMatrix.h @@ -0,0 +1,107 @@ +/*============================= + * ߼ӵ˳ϡ + * + * 㷨: 5.3 + ==============================*/ + +#ifndef RLSMATRIX_H +#define RLSMATRIX_H + +#include +#include // ṩ malloc ԭ +#include // ṩ strstr ԭ +#include "Status.h" //**01 **// + +/* 궨 */ +#define MAXSIZE 12500 // Ԫֵ +#define MAXRC 20 // Ԫظֵ + +/* ߼ӵϡԪ */ +typedef int ElemType; + +/* ԪͶ壬Ҫ洢Ԫ */ +typedef struct { + int i, j; // ÷Ԫ±± + ElemType e; +} Triple; + +/* ߼ӵϡͶ */ +typedef struct { + Triple data[MAXSIZE + 1]; // ԪԪdata[0]δ + int rpos[MAXRC + 1]; // еһԪԪеλñrpos[0]δ + int mu, nu, tu; // ͷԪ +} RLSMatrix; + + +/* + * ϡM + * + * + *ע + * + * ̲Ĭϴӿ̨ȡݡ + * Ϊ˷ԣÿжֶݣ + * ѡԤļpathжȡݡ + * + * Ҫӿ̨ȡݣpathΪNULLΪմ + * ҪļжȡݣҪpathдļϢ + */ +Status CreateSMatrix(RLSMatrix* M, char* path); + +/* + * ϡ + * + *ע + * ߼ӵ˳ṹ޷١ + */ +Status DestroySMatrix(RLSMatrix* M); + +/* + * + * + * һ¾Tþ˴ӾMаݡ + */ +Status CopySMatrix(RLSMatrix M, RLSMatrix* T); + +/* + * ӷ + * + * Q = M + N + */ +Status AddSMatrix(RLSMatrix M, RLSMatrix N, RLSMatrix* Q); + +/* + * + * + * Q = M - N + */ +Status SubSMatrix(RLSMatrix M, RLSMatrix N, RLSMatrix* Q); + +/* + * 㷨5.3 + * + * ˷ + * + * Q = M * N + */ +Status MultSMatrix(RLSMatrix M, RLSMatrix N, RLSMatrix* Q); + +/* + * ת + */ +Status TransposeSMatrix(RLSMatrix M, RLSMatrix* T); + +/* + * ת + */ +Status FastTransposeSMatrix(RLSMatrix M, RLSMatrix* T); + +/* + * + */ +void PrintSMatrix(RLSMatrix M); + +// Ϊrpos鸳ֵ +static void AssignRpos(RLSMatrix* M); + +#endif diff --git a/VisualC++/ExerciseBook/05.23/TestData_M.txt b/VisualC++/ExerciseBook/05.23/TestData_M.txt new file mode 100644 index 0000000..be25c94 --- /dev/null +++ b/VisualC++/ExerciseBook/05.23/TestData_M.txt @@ -0,0 +1,4 @@ +5 +5 +Ԫ10 +Ԫ飺(1,2,1),(1,4,5),(2,3,-3),(2,5,2),(3,1,2),(3,2,3),(3,3,4),(4,4,2),(5,1,3),(5,2,-1) \ No newline at end of file diff --git a/VisualC++/ExerciseBook/05.24/05.24.c b/VisualC++/ExerciseBook/05.24/05.24.c new file mode 100644 index 0000000..1da6f30 --- /dev/null +++ b/VisualC++/ExerciseBook/05.24/05.24.c @@ -0,0 +1,49 @@ +#include +#include "Status.h" //**01 **// +#include "SMatrix.h" //**ϡ**// + +/* + * ȡеiеjеԪأ洢e + */ +Status Algo_5_24(SMatrix M, int i, int j, int* e); + + +int main(int argc, char* argv[]) { + SMatrix M; + int e; + + printf(" ϡ M ...\n"); + CreateSMatrix(&M, "TestData_M.txt"); + printf("M = \n"); + PrintSMatrix(M); + + Algo_5_24(M, 2, 3, &e); + printf(" %d %d еԪΪ %d\n", 2, 3, e); + + return 0; +} + + +/* + * ȡеiеjеԪأ洢e + */ +Status Algo_5_24(SMatrix M, int i, int j, int* e) { + int s, p; + + if(i < 1 || i > M.mu || j < 1 || j > M.nu) { + return ERROR; + } + + for(p = 1, s = (i - 1) * M.nu + j; M.data[p].seq < s; p++) { + // ѰָԪ + } + + *e = 0; // ĬΪ0 + + // ҵӦ±Ԫ + if(M.data[p].seq == s) { + *e = M.data[p].e; + } + + return OK; +} diff --git a/VisualC++/ExerciseBook/05.24/05.24.vcxproj b/VisualC++/ExerciseBook/05.24/05.24.vcxproj new file mode 100644 index 0000000..004337c --- /dev/null +++ b/VisualC++/ExerciseBook/05.24/05.24.vcxproj @@ -0,0 +1,79 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {7B1D365B-1574-45A1-AECD-1E16A521398B} + My0524 + + + + Application + true + MultiByte + + + Application + false + true + MultiByte + + + + + + + + + + + + + $(SolutionDir)\..\Status;$(IncludePath) + + + + Level3 + Disabled + + + true + $(SolutionDir)\..\Status\Status.lib;%(AdditionalDependencies) + Console + + + + + Level3 + MaxSpeed + true + true + + + true + true + true + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/05.24/05.24.vcxproj.filters b/VisualC++/ExerciseBook/05.24/05.24.vcxproj.filters new file mode 100644 index 0000000..b9b145b --- /dev/null +++ b/VisualC++/ExerciseBook/05.24/05.24.vcxproj.filters @@ -0,0 +1,35 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + 源文件 + + + 源文件 + + + + + 头文件 + + + + + 资源文件 + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/05.24/05.24.vcxproj.user b/VisualC++/ExerciseBook/05.24/05.24.vcxproj.user new file mode 100644 index 0000000..ace9a86 --- /dev/null +++ b/VisualC++/ExerciseBook/05.24/05.24.vcxproj.user @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/05.24/SMatrix.c b/VisualC++/ExerciseBook/05.24/SMatrix.c new file mode 100644 index 0000000..729641b --- /dev/null +++ b/VisualC++/ExerciseBook/05.24/SMatrix.c @@ -0,0 +1,44 @@ +/*====================== + * ϡϰ5.24 + =======================*/ + +#include "SMatrix.h" //**ϡ**// + +// ϡM +Status CreateSMatrix(SMatrix* M, char* path) { + FILE* fp; + int k, i, j; + + fp = fopen(path, "r"); + + ReadData(fp, "%d%d%d", &((*M).mu), &((*M).nu), &((*M).tu)); + + // ȡԪ + for(k = 1; k <= (*M).tu; k++) { + ReadData(fp, "%d%d%d", &i, &j, &((*M).data[k].e)); + (*M).data[k].seq = (i - 1) * (*M).nu + j; + } + + fclose(fp); + + return OK; +} + +// ϡM +void PrintSMatrix(SMatrix M) { + int r, c; + int k = 1; + + for(r = 1; r <= M.mu; r++) { + for(c = 1; c <= M.nu; c++) { + if(r == (M.data[k].seq - 1) / M.nu + 1 && c == (M.data[k].seq - 1) % M.nu + 1) { + + printf("%3d ", M.data[k].e); + k++; + } else { + printf(" 0 "); + } + } + printf("\n"); + } +} diff --git a/VisualC++/ExerciseBook/05.24/SMatrix.h b/VisualC++/ExerciseBook/05.24/SMatrix.h new file mode 100644 index 0000000..5df069c --- /dev/null +++ b/VisualC++/ExerciseBook/05.24/SMatrix.h @@ -0,0 +1,32 @@ +/*====================== + * ϡϰ5.24 + =======================*/ + +#ifndef SMATRIX_H +#define SMATRIX_H + +#include +#include "Status.h" //**01 **// + +#define MAXSIZE 100 // ԪֵΪ400 + +/* Ԫ */ +typedef struct { + int seq; // ÷ԪھеţΪ + int e; +} SElem; + +/* ϡ */ +typedef struct { + SElem data[MAXSIZE + 1]; // 洢Ԫأdata[0]δ + int mu, nu, tu; // ͷԪ +} SMatrix; + + +// ϡM +Status CreateSMatrix(SMatrix* M, char* path); + +// ϡM +void PrintSMatrix(SMatrix M); + +#endif diff --git a/VisualC++/ExerciseBook/05.24/TestData_M.txt b/VisualC++/ExerciseBook/05.24/TestData_M.txt new file mode 100644 index 0000000..be25c94 --- /dev/null +++ b/VisualC++/ExerciseBook/05.24/TestData_M.txt @@ -0,0 +1,4 @@ +5 +5 +Ԫ10 +Ԫ飺(1,2,1),(1,4,5),(2,3,-3),(2,5,2),(3,1,2),(3,2,3),(3,3,4),(4,4,2),(5,1,3),(5,2,-1) \ No newline at end of file diff --git a/VisualC++/ExerciseBook/05.25/05.25.c b/VisualC++/ExerciseBook/05.25/05.25.c new file mode 100644 index 0000000..9851d07 --- /dev/null +++ b/VisualC++/ExerciseBook/05.25/05.25.c @@ -0,0 +1,79 @@ +#include +#include "Status.h" //**01 **// +#include "SMatrix.h" //**ϡ**// + +/* + * ϡӷAddSMatrix + */ +Status Algo_5_25(SMatrix P, SMatrix Q, SMatrix* R); + + +int main(int argc, char* argv[]) { + SMatrix M, N, Q; + + printf(" ϡ MN ...\n"); + CreateSMatrix(&M, "TestData_M.txt"); + CreateSMatrix(&N, "TestData_N.txt"); + printf(" M = \n"); + PrintSMatrix(M); + printf(" N = \n"); + PrintSMatrix(N); + + Algo_5_25(M, N, &Q); + printf("Q = M + N = \n"); + PrintSMatrix(Q); + + return 0; +} + + +/* + * ϡӷAddSMatrix + */ +Status Algo_5_25(SMatrix P, SMatrix Q, SMatrix* R) { + int i, j; + int p, q, r; + + if(P.mu != Q.mu || P.nu != Q.nu) { + printf("\n"); + return ERROR; + } + + // ʼRϢ + (*R).mu = P.mu; + (*R).nu = P.nu; + (*R).tu = 0; + memset((*R).V, 0, sizeof((*R).V)); + memset((*R).B, 0, sizeof((*R).B)); + + // ָPQRеV + p = q = r = 0; + + for(i = 0; i < P.mu; ++i) { + for(j = 0; j < P.nu; ++j) { + if(P.B[i][j] == 0 && Q.B[i][j] == 0) { + continue; + } else if(P.B[i][j] == 0 && Q.B[i][j] == 1) { + (*R).V[r++] = Q.V[q++]; + (*R).B[i][j] = 1; + } else if(P.B[i][j] == 1 && Q.B[i][j] == 0) { + (*R).V[r++] = P.V[p++]; + (*R).B[i][j] = 1; + + // PQзԪ + } else { + if((P.V[p] + Q.V[q])!=0) { + (*R).V[r++] = P.V[p] + Q.V[q]; + (*R).B[i][j] = 1; + } + + p++; + q++; + } + } + } + + (*R).tu = r; + + return OK; +} diff --git a/VisualC++/ExerciseBook/05.25/05.25.vcxproj b/VisualC++/ExerciseBook/05.25/05.25.vcxproj new file mode 100644 index 0000000..f842f09 --- /dev/null +++ b/VisualC++/ExerciseBook/05.25/05.25.vcxproj @@ -0,0 +1,80 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {0E85120D-878D-4F74-9D6E-2BC465659A38} + My0525 + + + + Application + true + MultiByte + + + Application + false + true + MultiByte + + + + + + + + + + + + + $(SolutionDir)\..\Status;$(IncludePath) + + + + Level3 + Disabled + + + true + $(SolutionDir)\..\Status\Status.lib;%(AdditionalDependencies) + Console + + + + + Level3 + MaxSpeed + true + true + + + true + true + true + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/05.25/05.25.vcxproj.filters b/VisualC++/ExerciseBook/05.25/05.25.vcxproj.filters new file mode 100644 index 0000000..48837ad --- /dev/null +++ b/VisualC++/ExerciseBook/05.25/05.25.vcxproj.filters @@ -0,0 +1,38 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + 源文件 + + + 源文件 + + + + + 头文件 + + + + + 资源文件 + + + 资源文件 + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/05.25/05.25.vcxproj.user b/VisualC++/ExerciseBook/05.25/05.25.vcxproj.user new file mode 100644 index 0000000..ace9a86 --- /dev/null +++ b/VisualC++/ExerciseBook/05.25/05.25.vcxproj.user @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/05.25/SMatrix.c b/VisualC++/ExerciseBook/05.25/SMatrix.c new file mode 100644 index 0000000..aaef587 --- /dev/null +++ b/VisualC++/ExerciseBook/05.25/SMatrix.c @@ -0,0 +1,48 @@ +/*====================== + * ϡϰ5.25 + =======================*/ + +#include "SMatrix.h" //**ϡ**// + +// ϡM +Status CreateSMatrix(SMatrix* M, char* path) { + FILE* fp; + int v, i, j; + + fp = fopen(path, "r"); + + ReadData(fp, "%d%d%d", &((*M).mu), &((*M).nu), &((*M).tu)); + + memset((*M).V, 0, sizeof((*M).V)); + memset((*M).B, 0, sizeof((*M).B)); + + for(v=0; v < (*M).tu; v++) { + // ȡԪϢԪشV + ReadData(fp, "%d%d%d", &i, &j, &((*M).V[v])); + + (*M).B[i-1][j-1] = 1; + } + + fclose(fp); + + return OK; +} + +// ϡM +void PrintSMatrix(SMatrix M) { + int v, i, j; + + v = 0; // Vα + + for(i = 1; i <= M.mu; i++) { + for(j = 1; j <= M.nu; j++) { + if(M.B[i-1][j-1] == 1) { + printf("%3d ", M.V[v++]); + } else { + printf("%3d ", M.B[i-1][j-1]); + } + } + + printf("\n"); + } +} diff --git a/VisualC++/ExerciseBook/05.25/SMatrix.h b/VisualC++/ExerciseBook/05.25/SMatrix.h new file mode 100644 index 0000000..6ad263d --- /dev/null +++ b/VisualC++/ExerciseBook/05.25/SMatrix.h @@ -0,0 +1,32 @@ +/*====================== + * ϡϰ5.25 + =======================*/ + +#ifndef SMATRIX_H +#define SMATRIX_H + +#include +#include +#include +#include "Status.h" //**01 **// + +/* 궨 */ +#define Mu 20 // ֵΪ20 +#define Nu 20 // ֵΪ20 +#define MAXSIZE 400 // ԪֵΪ400 + +/* ϡͶ */ +typedef struct { + int V[MAXSIZE]; // 洢Ԫ + int B[Mu][Nu]; // ǾиλԪǷΪԪ + int mu, nu, tu; // Ԫ +} SMatrix; + + +// ϡM +Status CreateSMatrix(SMatrix* M, char* path); + +// ϡM +void PrintSMatrix(SMatrix M); + +#endif diff --git a/VisualC++/ExerciseBook/05.25/TestData_M.txt b/VisualC++/ExerciseBook/05.25/TestData_M.txt new file mode 100644 index 0000000..be25c94 --- /dev/null +++ b/VisualC++/ExerciseBook/05.25/TestData_M.txt @@ -0,0 +1,4 @@ +5 +5 +Ԫ10 +Ԫ飺(1,2,1),(1,4,5),(2,3,-3),(2,5,2),(3,1,2),(3,2,3),(3,3,4),(4,4,2),(5,1,3),(5,2,-1) \ No newline at end of file diff --git a/VisualC++/ExerciseBook/05.25/TestData_N.txt b/VisualC++/ExerciseBook/05.25/TestData_N.txt new file mode 100644 index 0000000..7c940db --- /dev/null +++ b/VisualC++/ExerciseBook/05.25/TestData_N.txt @@ -0,0 +1,4 @@ +5 +5 +Ԫ8 +Ԫ飺(1,1,-3)(1,3,2)(2,4,-1)(3,2,4)(4,1,6)(4,5,5)(5,1,3)(5,3,2) \ No newline at end of file diff --git a/VisualC++/ExerciseBook/05.26/05.26.c b/VisualC++/ExerciseBook/05.26/05.26.c new file mode 100644 index 0000000..a2146d0 --- /dev/null +++ b/VisualC++/ExerciseBook/05.26/05.26.c @@ -0,0 +1,49 @@ +#include +#include "Status.h" //**01 **// +#include "CrossList.h" //**05 ͹**// + +/* + * Ԫʽʮ + */ +Status Algo_5_26(CrossList M); + + +int main(int argc, char* argv[]) { + CrossList M; + + printf("ʮ M...\n"); + CreateSMatrix(&M, "TestData_M.txt"); + printf("M = \n"); + PrintSMatrix(M); + + printf("Ԫʽ M...\n"); + printf(" ֵ\n"); + Algo_5_26(M); + + return 0; +} + + +/* + * Ԫʽʮ + */ +Status Algo_5_26(CrossList M) { + int i, j; + OLNode* p; + + if(M.tu==0) { + return ERROR; + } + + for(i = 1; i <= M.mu; ++i) { + p = M.rhead[i]; + for(j = 1; j <= M.nu; ++j) { + if(p && p->j == j) { + printf("(%2d %2d %3d)\n", i, j, p->e); + p = p->right; + } + } + } + + return OK; +} diff --git a/VisualC++/ExerciseBook/05.26/05.26.vcxproj b/VisualC++/ExerciseBook/05.26/05.26.vcxproj new file mode 100644 index 0000000..002358f --- /dev/null +++ b/VisualC++/ExerciseBook/05.26/05.26.vcxproj @@ -0,0 +1,79 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {A124BA87-11B9-4329-8572-F4D3EAE759E8} + My0526 + + + + Application + true + MultiByte + + + Application + false + true + MultiByte + + + + + + + + + + + + + $(SolutionDir)\..\Status;$(IncludePath) + + + + Level3 + Disabled + + + true + $(SolutionDir)\..\Status\Status.lib;%(AdditionalDependencies) + Console + + + + + Level3 + MaxSpeed + true + true + + + true + true + true + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/05.26/05.26.vcxproj.filters b/VisualC++/ExerciseBook/05.26/05.26.vcxproj.filters new file mode 100644 index 0000000..4efbb8c --- /dev/null +++ b/VisualC++/ExerciseBook/05.26/05.26.vcxproj.filters @@ -0,0 +1,35 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + 源文件 + + + 源文件 + + + + + 头文件 + + + + + 资源文件 + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/05.26/05.26.vcxproj.user b/VisualC++/ExerciseBook/05.26/05.26.vcxproj.user new file mode 100644 index 0000000..ace9a86 --- /dev/null +++ b/VisualC++/ExerciseBook/05.26/05.26.vcxproj.user @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/05.26/CrossList.c b/VisualC++/ExerciseBook/05.26/CrossList.c new file mode 100644 index 0000000..07eb63d --- /dev/null +++ b/VisualC++/ExerciseBook/05.26/CrossList.c @@ -0,0 +1,885 @@ +/*=================== + * ʮϡ + * + * 㷨: 5.4 + ====================*/ + +#include "CrossList.h" //**05 ͹**// + +/* + * 㷨5.4 + * + * ϡM + * + * + *ע + * + * ̲Ĭϴӿ̨ȡݡ + * Ϊ˷ԣÿжֶݣ + * ѡԤļpathжȡݡ + * + * Ҫӿ̨ȡݣpathΪNULLΪմ + * ҪļжȡݣҪpathдļϢ + */ +Status CreateSMatrix(CrossList* M, char* path) { + int i, j, k; + OLNode* p, * q; + FILE* fp; + int readFromConsole; // Ƿӿ̨ȡ + + // ûļ·Ϣӿ̨ȡ + readFromConsole = path == NULL || strcmp(path, "") == 0; + + if(readFromConsole) { + printf(""); + scanf("%d", &((*M).mu)); + printf(""); + scanf("%d", &((*M).nu)); + printf("Ԫظ"); + scanf("%d", &((*M).tu)); + printf("%dԪϢ\n", (*M).tu); + } else { + fp = fopen(path, "r"); + ReadData(fp, "%d%d%d", &((*M).mu), &((*M).nu), &((*M).tu)); + } + + // 0ŵԪã + (*M).rhead = (OLink*) malloc(((*M).mu + 1) * sizeof(OLink)); + if((*M).rhead == NULL) { + exit(OVERFLOW); + } + + // 0ŵԪã + (*M).chead = (OLink*) malloc(((*M).nu + 1) * sizeof(OLink)); + if((*M).chead == NULL) { + exit(OVERFLOW); + } + + // ʼΪNULL + for(k = 0; k <= (*M).mu; ++k) { + (*M).rhead[k] = NULL; + } + + // ʼΪNULL + for(k = 0; k <= (*M).nu; ++k) { + (*M).chead[k] = NULL; + } + + // ¼Ԫ + for(k = 1; k <= (*M).tu; ++k) { + // Ԫ + p = (OLNode*) malloc(sizeof(OLNode)); + if(p == NULL) { + exit(OVERFLOW); + } + + if(readFromConsole) { + printf("%2d飺", k); + scanf("%d%d%d", &i, &j, &(p->e)); + } else { + ReadData(fp, "%d%d%d", &i, &j, &(p->e)); + } + + p->i = i; // к + p->j = j; // к + p->right = p->down = NULL; + + /* + * ʼеIJ + */ + + // лûԪأԪؾλڸԪҲֱ࣬Ӳ + if((*M).rhead[i] == NULL || (*M).rhead[i]->j > j) { + // λбеIJλ + p->right = (*M).rhead[i]; + (*M).rhead[i] = p; + } else { + // ѰҲλõǰһλ + for(q = (*M).rhead[i]; (q->right) && (q->right->j < j); q = q->right) { + } + + if(q->j == p->j || ((q->right) && q->right->j == p->j)) { + printf("λѱռã\n"); + exit(ERROR); + } + + p->right = q->right; + q->right = p; + } + + /* + * ʼеIJ + */ + + // лûԪأԪؾλڸԪ²ֱ࣬Ӳ + if((*M).chead[j] == NULL || (*M).chead[j]->i > i) { + // λбеIJλ + p->down = (*M).chead[j]; + (*M).chead[j] = p; + } else { + // ѰҲλõǰһλ + for(q = (*M).chead[j]; (q->down) && (q->down->i < i); q = q->down) { + } + + if(q->i == p->i || ((q->down) && q->down->i == p->i)) { + printf("λѱռã\n"); + exit(ERROR); + } + + p->down = q->down; + q->down = p; + } + } + + if(!readFromConsole) { + fclose(fp); + } + + return OK; +} + +/* + * ϡ + */ +Status DestroySMatrix(CrossList* M) { + int i; + OLNode* p, * q; + + // ۴ӰлǰУֻҪһȥپͿ + for(i = 1; i <= (*M).mu; ++i) { + p = (*M).rhead[i]; + while(p != NULL) { + q = p; + p = p->right; + free(q); + } + } + + free((*M).rhead); + free((*M).chead); + + (*M).rhead = (*M).chead = NULL; + (*M).mu = (*M).nu = (*M).tu = 0; + + return OK; +} + +/* + * + * + * һ¾Tþ˴ӾMаݡ + */ +Status CopySMatrix(CrossList M, CrossList* T) { + int k; + OLNode* p, * q, * r, * l; + + if(T == NULL) { + return ERROR; + } + + // Ϣ + (*T).mu = M.mu; + (*T).nu = M.nu; + (*T).tu = M.tu; + + // 0ŵԪã + (*T).rhead = (OLink*) malloc(((*T).mu + 1) * sizeof(OLink)); + if((*T).rhead == NULL) { + exit(OVERFLOW); + } + + // 0ŵԪã + (*T).chead = (OLink*) malloc(((*T).nu + 1) * sizeof(OLink)); + if((*T).chead == NULL) { + exit(OVERFLOW); + } + + // ʼΪNULL + for(k = 0; k <= (*T).mu; ++k) { //ʼͷָΪ + (*T).rhead[k] = NULL; + } + + // ʼΪNULL + for(k = 0; k <= (*T).nu; ++k) { + (*T).chead[k] = NULL; + } + + // ɨ裬θƷԪ + for(k = 1; k <= M.mu; ++k) { + q = M.rhead[k]; + + // ǰûԪأֱ + if(q == NULL) { + continue; + } + + r = NULL; + + while(q != NULL) { + // Ԫ + p = (OLNode*) malloc(sizeof(OLNode)); + if(p == NULL) { + exit(OVERFLOW); + } + + // Ϊ㸳ֵ + p->i = q->i; + p->j = q->j; + p->e = q->e; + p->right = p->down = NULL; + + /* + * ʼеIJ + */ + + if(r == NULL) { + (*T).rhead[q->i] = p; + } else { + r->right = p; + } + + // rָǰ²Ľ + r = p; + + /* + * ʼеIJ + */ + + // ѰҲλ + if((*T).chead[q->j] == NULL || (*T).chead[q->j]->i > q->i) { + r->down = (*T).chead[q->j]; + (*T).chead[q->j] = r; + } else { + // ѰҲλõǰһλ + for(l = (*T).chead[q->j]; (l->down) && (l->down->i < q->i); l = l->down) { + } + r->down = l->down; + l->down = r; + } + + q = q->right; + } + } + + return OK; +} + +/* + * ӷ + * + * Q = M + N + */ +Status AddSMatrix(CrossList M, CrossList N, CrossList* Q) { + int i; + OLNode* pm, * pn, * p, * r, * l; + + if(M.mu != N.mu || M.nu != N.nu) { + printf("\n"); + return ERROR; + } + + // ʼQϢ + Q->mu = M.mu; + Q->nu = M.nu; + Q->tu = 0; + + // 0ŵԪã + Q->rhead = (OLink*) malloc((Q->mu + 1) * sizeof(OLink)); + if(!Q->rhead) { + exit(OVERFLOW); + } + + // 0ŵԪã + Q->chead = (OLink*) malloc((Q->nu + 1) * sizeof(OLink)); + if(!Q->chead) { + exit(OVERFLOW); + } + + // ʼΪNULL + for(i = 0; i <= Q->mu; ++i) { + Q->rhead[i] = NULL; + } + + // ʼΪNULL + for(i = 0; i <= Q->nu; ++i) { + Q->chead[i] = NULL; + } + + // ӵһ± + for(i = 1; i <= M.mu; ++i) { + pm = M.rhead[i]; + pn = N.rhead[i]; + + // MNĵǰоδķԪ + while(pm != NULL && pn != NULL) { + // + if(pm->j == pn->j && pm->e + pn->e == 0) { + pm = pm->right; + pn = pn->right; + continue; + } + + // + p = (OLNode*) malloc(sizeof(OLNode)); + if(!p) { + exit(OVERFLOW); + } + + // MеԪ±С + if(pm->j < pn->j) { + p->i = pm->i; + p->j = pm->j; + p->e = pm->e; + pm = pm->right; + + // NеԪ±С + } else if(pm->j > pn->j) { + p->i = pn->i; + p->j = pn->j; + p->e = pn->e; + pn = pn->right; + + // MNеԪ±һ£Ҫмӷ + } else { + p->i = pm->i; + p->j = pm->j; + p->e = pm->e + pn->e; + pm = pm->right; + pn = pn->right; + } + + p->right = p->down = NULL; + + Q->tu++; // QзԪһ + + /* + * ʼеIJ + */ + + if(Q->rhead[p->i] == NULL) { + Q->rhead[p->i] = p; + } else { + r->right = p; + } + + // rָǰ²Ľ + r = p; + + /* + * ʼеIJ + */ + + // ѰҲλ + if(Q->chead[p->j] == NULL || Q->chead[p->j]->i > p->i) { + r->down = Q->chead[p->j]; + Q->chead[p->j] = r; + } else { + // ѰҲλõǰһλ + for(l = Q->chead[p->j]; (l->down) && (l->down->i < p->i); l = l->down) { + } + r->down = l->down; + l->down = r; + } + } + + // MĵǰδķԪ + while(pm != NULL) { + p = (OLNode*) malloc(sizeof(OLNode)); + if(p == NULL) { + exit(OVERFLOW); + } + p->i = pm->i; + p->j = pm->j; + p->e = pm->e; + p->right = p->down = NULL; + + Q->tu++; // QзԪһ + + if(Q->rhead[p->i] == NULL) { + Q->rhead[p->i] = p; + } else { + r->right = p; + } + + // rָǰ²Ľ + r = p; + + // ѰҲλ + if(Q->chead[p->j] == NULL || Q->chead[p->j]->i > p->i) { + r->down = Q->chead[p->j]; + Q->chead[p->j] = r; + } else { + // ѰҲλõǰһλ + for(l = Q->chead[p->j]; (l->down) && (l->down->i < p->i); l = l->down) { + } + r->down = l->down; + l->down = r; + } + + pm = pm->right; + } + + // NĵǰδķԪ + while(pn != NULL) { + p = (OLNode*) malloc(sizeof(OLNode)); + if(p == NULL) { + exit(OVERFLOW); + } + p->i = pn->i; + p->j = pn->j; + p->e = pn->e; + p->right = p->down = NULL; + + Q->tu++; // QзԪһ + + if(Q->rhead[p->i] == NULL) { + Q->rhead[p->i] = p; + } else { + r->right = p; + } + + // rָǰ²Ľ + r = p; + + // ѰҲλ + if(Q->chead[p->j] == NULL || Q->chead[p->j]->i > p->i) { + r->down = Q->chead[p->j]; + Q->chead[p->j] = r; + } else { + // ѰҲλõǰһλ + for(l = Q->chead[p->j]; (l->down) && (l->down->i < p->i); l = l->down) { + } + r->down = l->down; + l->down = r; + } + + pn = pn->right; + } + } + + return OK; +} + +/* + * + * + * Q = M - N + */ +Status SubSMatrix(CrossList M, CrossList N, CrossList* Q) { + int i; + OLNode* pm, * pn, * p, * r, * l; + + if(M.mu != N.mu || M.nu != N.nu) { + printf("\n"); + return ERROR; + } + + // ʼQϢ + Q->mu = M.mu; + Q->nu = M.nu; + Q->tu = 0; + + // 0ŵԪã + Q->rhead = (OLink*) malloc((Q->mu + 1) * sizeof(OLink)); + if(!Q->rhead) { + exit(OVERFLOW); + } + + // 0ŵԪã + Q->chead = (OLink*) malloc((Q->nu + 1) * sizeof(OLink)); + if(!Q->chead) { + exit(OVERFLOW); + } + + // ʼΪNULL + for(i = 0; i <= Q->mu; ++i) { + Q->rhead[i] = NULL; + } + + // ʼΪNULL + for(i = 0; i <= Q->nu; ++i) { + Q->chead[i] = NULL; + } + + // ӵһ± + for(i = 1; i <= M.mu; ++i) { + pm = M.rhead[i]; + pn = N.rhead[i]; + + // MNĵǰоδķԪ + while(pm != NULL && pn != NULL) { + // + if(pm->j == pn->j && pm->e - pn->e == 0) { + pm = pm->right; + pn = pn->right; + continue; + } + + // + p = (OLNode*) malloc(sizeof(OLNode)); + if(!p) { + exit(OVERFLOW); + } + + // MеԪ±С + if(pm->j < pn->j) { + p->i = pm->i; + p->j = pm->j; + p->e = pm->e; + pm = pm->right; + + // NеԪ±С + } else if(pm->j > pn->j) { + p->i = pn->i; + p->j = pn->j; + p->e = -pn->e; // Ӹ + pn = pn->right; + + // MNеԪ±һ£Ҫм + } else { + p->i = pm->i; + p->j = pm->j; + p->e = pm->e - pn->e; + pm = pm->right; + pn = pn->right; + } + + p->right = p->down = NULL; + + Q->tu++; // QзԪһ + + /* + * ʼеIJ + */ + + if(Q->rhead[p->i] == NULL) { + Q->rhead[p->i] = p; + } else { + r->right = p; + } + + // rָǰ²Ľ + r = p; + + /* + * ʼеIJ + */ + + // ѰҲλ + if(Q->chead[p->j] == NULL || Q->chead[p->j]->i > p->i) { + r->down = Q->chead[p->j]; + Q->chead[p->j] = r; + } else { + //ѰҲλõǰһλ + for(l = Q->chead[p->j]; (l->down) && (l->down->i < p->i); l = l->down) { + } + r->down = l->down; + l->down = r; + } + } + + // MĵǰδķԪ + while(pm != NULL) { + p = (OLNode*) malloc(sizeof(OLNode)); + if(!p) { + exit(OVERFLOW); + } + p->i = pm->i; + p->j = pm->j; + p->e = pm->e; + p->right = p->down = NULL; + + Q->tu++; // QзԪһ + + if(Q->rhead[p->i] == NULL) { + Q->rhead[p->i] = p; + } else { + r->right = p; + } + + // rָǰ²Ľ + r = p; + + // ѰҲλ + if(Q->chead[p->j] == NULL || Q->chead[p->j]->i > p->i) { + r->down = Q->chead[p->j]; + Q->chead[p->j] = r; + } else { + // ѰҲλõǰһλ + for(l = Q->chead[p->j]; (l->down) && (l->down->i < p->i); l = l->down) { + } + r->down = l->down; + l->down = r; + } + + pm = pm->right; + } + + // NĵǰδķԪ + while(pn != NULL) { + p = (OLNode*) malloc(sizeof(OLNode)); + if(!p) { + exit(OVERFLOW); + } + p->i = pn->i; + p->j = pn->j; + p->e = -pn->e; // Ӹ + p->right = p->down = NULL; + + Q->tu++; // QзԪһ + + if(Q->rhead[p->i] == NULL) { + Q->rhead[p->i] = p; + } else { + r->right = p; + } + + // rָǰ²Ľ + r = p; + + // ѰҲλ + if(Q->chead[p->j] == NULL || Q->chead[p->j]->i > p->i) { + r->down = Q->chead[p->j]; + Q->chead[p->j] = r; + } else { + // ѰҲλõǰһλ + for(l = Q->chead[p->j]; (l->down) && (l->down->i < p->i); l = l->down) { + } + r->down = l->down; + l->down = r; + } + + pn = pn->right; + } + } + + return OK; +} + +/* + * ˷ + * + * Q = M * N + */ +Status MultSMatrix(CrossList M, CrossList N, CrossList* Q) { + int m_row, n_col, i; + ElemType e; + OLNode* pm, * pn, * p, * r, * l; + + // MҪN + if(M.nu != N.mu) { + printf("\n"); + return ERROR; + } + + // ʼQϢ + Q->mu = M.mu; + Q->nu = N.nu; + Q->tu = 0; + + // 0ŵԪã + Q->rhead = (OLink*) malloc((Q->mu + 1) * sizeof(OLink)); + if(!Q->rhead) { + exit(OVERFLOW); + } + + // 0ŵԪã + Q->chead = (OLink*) malloc((Q->nu + 1) * sizeof(OLink)); + if(!Q->chead) { + exit(OVERFLOW); + } + + // ʼΪNULL + for(i = 0; i <= Q->mu; ++i) { + Q->rhead[i] = NULL; + } + + // ʼΪNULL + for(i = 0; i <= Q->nu; ++i) { + Q->chead[i] = NULL; + } + + // QǷ + if(M.tu * N.tu) { + for(m_row = 1; m_row <= M.mu; ++m_row) { + for(n_col = 1; n_col <= N.nu; ++n_col) { + pm = M.rhead[m_row]; + pn = N.chead[n_col]; + + e = 0; + + // MN + while(pm && pn) { + if(pm->j < pn->i) { + pm = pm->right; + } else if(pm->j > pn->i) { + pn = pn->down; + } else { + e += pm->e * pn->e; + pm = pm->right; + pn = pn->down; + } + } + + if(e == 0) { + continue; + } + + p = (OLNode*) malloc(sizeof(OLNode)); + if(!p) { + exit(OVERFLOW); + } + + // Ϊ㸳ֵ + p->i = M.rhead[m_row]->i; + p->j = N.chead[n_col]->j; + p->e = e; + p->right = p->down = NULL; + + Q->tu++; // QзԪһ + + if(Q->rhead[p->i] == NULL) { + Q->rhead[p->i] = p; + } else { + r->right = p; + } + + // rָǰ²Ľ + r = p; + + // ѰҲλ + if(Q->chead[p->j] == NULL || Q->chead[p->j]->i > p->i) { + r->down = Q->chead[p->j]; + Q->chead[p->j] = r; + } else { + // ѰҲλõǰһλ + for(l = Q->chead[p->j]; (l->down) && (l->down->i < p->i); l = l->down) { + } + + r->down = l->down; + l->down = r; + } + } + } + } + + return OK; +} + +/* + * ת + */ +Status TransposeSMatrix(CrossList M, CrossList* T) { + int i; + OLNode* p, * q, * r, * l; + + // ʼQϢ + (*T).mu = M.nu; + (*T).nu = M.mu; + (*T).tu = M.tu; + + // 0ŵԪã + (*T).rhead = (OLink*) malloc(((*T).mu + 1) * sizeof(OLink)); + if(!(*T).rhead) { + exit(OVERFLOW); + } + + // 0ŵԪã + (*T).chead = (OLink*) malloc(((*T).nu + 1) * sizeof(OLink)); + if(!(*T).chead) { + exit(OVERFLOW); + } + + // ʼΪNULL + for(i = 0; i <= (*T).mu; ++i) { + (*T).rhead[i] = NULL; + } + + // ʼΪNULL + for(i = 0; i <= (*T).nu; ++i) { + (*T).chead[i] = NULL; + } + + // + if(!(*T).tu) { + return OK; + } + + // ɨ + for(i = 1; i <= M.nu; ++i) { + q = M.chead[i]; + + // ǰûԪأֱ + if(q == NULL) { + continue; + } + + while(q != NULL) { + // Ԫ + p = (OLNode*) malloc(sizeof(OLNode)); + if(!p) { + exit(OVERFLOW); + } + + // Ϊ㸳ֵбУб + p->i = q->j; + p->j = q->i; + p->e = q->e; + p->right = p->down = NULL; + + /* + * ʼеIJ + */ + + if((*T).rhead[p->i] == NULL) { + (*T).rhead[p->i] = p; + } else { + r->right = p; + } + + // rָǰ²Ľ + r = p; + + /* + * ʼеIJ + */ + + // ѰҲλ + if((*T).chead[p->j] == NULL || (*T).chead[p->j]->i > p->i) { + r->down = (*T).chead[p->j]; + (*T).chead[p->j] = r; + } else { + // ѰҲλõǰһλ + for(l = (*T).chead[p->j]; (l->down) && (l->down->i < p->i); l = l->down) { + } + r->down = l->down; + l->down = r; + } + + q = q->down; + } + } + + return OK; +} + +/* + * + */ +void PrintSMatrix(CrossList M) { + int i, j; + OLNode* p; + + for(i = 1; i <= M.mu; ++i) { + p = M.rhead[i]; + for(j = 1; j <= M.nu; ++j) { + if(p && p->j == j) { + printf("%3d ", p->e); + p = p->right; + } else { + printf("%3d ", 0); + } + } + printf("\n"); + } +} diff --git a/VisualC++/ExerciseBook/05.26/CrossList.h b/VisualC++/ExerciseBook/05.26/CrossList.h new file mode 100644 index 0000000..c774280 --- /dev/null +++ b/VisualC++/ExerciseBook/05.26/CrossList.h @@ -0,0 +1,94 @@ +/*=================== + * ʮϡ + * + * 㷨: 5.4 + ====================*/ + +#ifndef CROSSLIST_H +#define CROSSLIST_H + +#include +#include // ṩmallocreallocfreeexitԭ +#include // ṩ strstr ԭ +#include "Status.h" //**01 **// + +/* ʮԪ */ +typedef int ElemType; + +/* ԪͶ */ +typedef struct OLNode { + int i, j; // ÷Ԫ±± + ElemType e; + struct OLNode* right; // ÷Ԫڵбĺ + struct OLNode* down; // ÷Ԫڵбĺ +} OLNode, * OLink; + +/* ʮͶ */ +typedef struct { + OLink* rhead; // ͷָ + OLink* chead; // ͷָ + int mu, nu, tu; // ͷԪ +} CrossList; + + +/* + * 㷨5.4 + * + * ϡM + * + * + *ע + * + * ̲Ĭϴӿ̨ȡݡ + * Ϊ˷ԣÿжֶݣ + * ѡԤļpathжȡݡ + * + * Ҫӿ̨ȡݣpathΪNULLΪմ + * ҪļжȡݣҪpathдļϢ + */ +Status CreateSMatrix(CrossList* M, char* path); + +/* + * ϡ + */ +Status DestroySMatrix(CrossList* M); + +/* + * + * + * һ¾Tþ˴ӾMаݡ + */ +Status CopySMatrix(CrossList M, CrossList* T); + +/* + * ӷ + * + * Q = M + N + */ +Status AddSMatrix(CrossList M, CrossList N, CrossList* Q); + +/* + * + * + * Q = M - N + */ +Status SubSMatrix(CrossList M, CrossList N, CrossList* Q); + +/* + * ˷ + * + * Q = M * N + */ +Status MultSMatrix(CrossList M, CrossList N, CrossList* Q); + +/* + * ת + */ +Status TransposeSMatrix(CrossList M, CrossList* T); + +/* + * + */ +void PrintSMatrix(CrossList M); + +#endif diff --git a/VisualC++/ExerciseBook/05.26/TestData_M.txt b/VisualC++/ExerciseBook/05.26/TestData_M.txt new file mode 100644 index 0000000..be25c94 --- /dev/null +++ b/VisualC++/ExerciseBook/05.26/TestData_M.txt @@ -0,0 +1,4 @@ +5 +5 +Ԫ10 +Ԫ飺(1,2,1),(1,4,5),(2,3,-3),(2,5,2),(3,1,2),(3,2,3),(3,3,4),(4,4,2),(5,1,3),(5,2,-1) \ No newline at end of file diff --git a/VisualC++/ExerciseBook/05.27/05.27.c b/VisualC++/ExerciseBook/05.27/05.27.c new file mode 100644 index 0000000..c3015d0 --- /dev/null +++ b/VisualC++/ExerciseBook/05.27/05.27.c @@ -0,0 +1,41 @@ +#include +#include "Status.h" //**01 **// +#include "CrossList.h" //**05 ͹**// + +/* + * ϡӷAddSMatrix + * + *ע + * úCrossListļж + */ +Status Algo_5_27(CrossList M, CrossList N, CrossList* Q); + + +int main(int argc, char* argv[]) { + CrossList M, N, Q; + + printf(" ϡ MN ...\n"); + CreateSMatrix(&M, "TestData_M.txt"); + CreateSMatrix(&N, "TestData_N.txt"); + printf(" M = \n"); + PrintSMatrix(M); + printf(" N = \n"); + PrintSMatrix(N); + + Algo_5_27(M, N, &Q); + printf(" Q = M + N = \n"); + PrintSMatrix(Q); + + return 0; +} + + +/* + * ϡӷAddSMatrix + * + *ע + * úCrossListļж + */ +Status Algo_5_27(CrossList M, CrossList N, CrossList* Q) { + return AddSMatrix(M, N, Q); +} diff --git a/VisualC++/ExerciseBook/05.27/05.27.vcxproj b/VisualC++/ExerciseBook/05.27/05.27.vcxproj new file mode 100644 index 0000000..9e5bc4d --- /dev/null +++ b/VisualC++/ExerciseBook/05.27/05.27.vcxproj @@ -0,0 +1,80 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {EF60CDEA-A37D-4A91-ABB9-95D41D970927} + My0527 + + + + Application + true + MultiByte + + + Application + false + true + MultiByte + + + + + + + + + + + + + $(SolutionDir)\..\Status;$(IncludePath) + + + + Level3 + Disabled + + + true + $(SolutionDir)\..\Status\Status.lib;%(AdditionalDependencies) + Console + + + + + Level3 + MaxSpeed + true + true + + + true + true + true + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/05.27/05.27.vcxproj.filters b/VisualC++/ExerciseBook/05.27/05.27.vcxproj.filters new file mode 100644 index 0000000..4cace26 --- /dev/null +++ b/VisualC++/ExerciseBook/05.27/05.27.vcxproj.filters @@ -0,0 +1,38 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + 源文件 + + + 源文件 + + + + + 头文件 + + + + + 资源文件 + + + 资源文件 + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/05.27/05.27.vcxproj.user b/VisualC++/ExerciseBook/05.27/05.27.vcxproj.user new file mode 100644 index 0000000..ace9a86 --- /dev/null +++ b/VisualC++/ExerciseBook/05.27/05.27.vcxproj.user @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/05.27/CrossList.c b/VisualC++/ExerciseBook/05.27/CrossList.c new file mode 100644 index 0000000..07eb63d --- /dev/null +++ b/VisualC++/ExerciseBook/05.27/CrossList.c @@ -0,0 +1,885 @@ +/*=================== + * ʮϡ + * + * 㷨: 5.4 + ====================*/ + +#include "CrossList.h" //**05 ͹**// + +/* + * 㷨5.4 + * + * ϡM + * + * + *ע + * + * ̲Ĭϴӿ̨ȡݡ + * Ϊ˷ԣÿжֶݣ + * ѡԤļpathжȡݡ + * + * Ҫӿ̨ȡݣpathΪNULLΪմ + * ҪļжȡݣҪpathдļϢ + */ +Status CreateSMatrix(CrossList* M, char* path) { + int i, j, k; + OLNode* p, * q; + FILE* fp; + int readFromConsole; // Ƿӿ̨ȡ + + // ûļ·Ϣӿ̨ȡ + readFromConsole = path == NULL || strcmp(path, "") == 0; + + if(readFromConsole) { + printf(""); + scanf("%d", &((*M).mu)); + printf(""); + scanf("%d", &((*M).nu)); + printf("Ԫظ"); + scanf("%d", &((*M).tu)); + printf("%dԪϢ\n", (*M).tu); + } else { + fp = fopen(path, "r"); + ReadData(fp, "%d%d%d", &((*M).mu), &((*M).nu), &((*M).tu)); + } + + // 0ŵԪã + (*M).rhead = (OLink*) malloc(((*M).mu + 1) * sizeof(OLink)); + if((*M).rhead == NULL) { + exit(OVERFLOW); + } + + // 0ŵԪã + (*M).chead = (OLink*) malloc(((*M).nu + 1) * sizeof(OLink)); + if((*M).chead == NULL) { + exit(OVERFLOW); + } + + // ʼΪNULL + for(k = 0; k <= (*M).mu; ++k) { + (*M).rhead[k] = NULL; + } + + // ʼΪNULL + for(k = 0; k <= (*M).nu; ++k) { + (*M).chead[k] = NULL; + } + + // ¼Ԫ + for(k = 1; k <= (*M).tu; ++k) { + // Ԫ + p = (OLNode*) malloc(sizeof(OLNode)); + if(p == NULL) { + exit(OVERFLOW); + } + + if(readFromConsole) { + printf("%2d飺", k); + scanf("%d%d%d", &i, &j, &(p->e)); + } else { + ReadData(fp, "%d%d%d", &i, &j, &(p->e)); + } + + p->i = i; // к + p->j = j; // к + p->right = p->down = NULL; + + /* + * ʼеIJ + */ + + // лûԪأԪؾλڸԪҲֱ࣬Ӳ + if((*M).rhead[i] == NULL || (*M).rhead[i]->j > j) { + // λбеIJλ + p->right = (*M).rhead[i]; + (*M).rhead[i] = p; + } else { + // ѰҲλõǰһλ + for(q = (*M).rhead[i]; (q->right) && (q->right->j < j); q = q->right) { + } + + if(q->j == p->j || ((q->right) && q->right->j == p->j)) { + printf("λѱռã\n"); + exit(ERROR); + } + + p->right = q->right; + q->right = p; + } + + /* + * ʼеIJ + */ + + // лûԪأԪؾλڸԪ²ֱ࣬Ӳ + if((*M).chead[j] == NULL || (*M).chead[j]->i > i) { + // λбеIJλ + p->down = (*M).chead[j]; + (*M).chead[j] = p; + } else { + // ѰҲλõǰһλ + for(q = (*M).chead[j]; (q->down) && (q->down->i < i); q = q->down) { + } + + if(q->i == p->i || ((q->down) && q->down->i == p->i)) { + printf("λѱռã\n"); + exit(ERROR); + } + + p->down = q->down; + q->down = p; + } + } + + if(!readFromConsole) { + fclose(fp); + } + + return OK; +} + +/* + * ϡ + */ +Status DestroySMatrix(CrossList* M) { + int i; + OLNode* p, * q; + + // ۴ӰлǰУֻҪһȥپͿ + for(i = 1; i <= (*M).mu; ++i) { + p = (*M).rhead[i]; + while(p != NULL) { + q = p; + p = p->right; + free(q); + } + } + + free((*M).rhead); + free((*M).chead); + + (*M).rhead = (*M).chead = NULL; + (*M).mu = (*M).nu = (*M).tu = 0; + + return OK; +} + +/* + * + * + * һ¾Tþ˴ӾMаݡ + */ +Status CopySMatrix(CrossList M, CrossList* T) { + int k; + OLNode* p, * q, * r, * l; + + if(T == NULL) { + return ERROR; + } + + // Ϣ + (*T).mu = M.mu; + (*T).nu = M.nu; + (*T).tu = M.tu; + + // 0ŵԪã + (*T).rhead = (OLink*) malloc(((*T).mu + 1) * sizeof(OLink)); + if((*T).rhead == NULL) { + exit(OVERFLOW); + } + + // 0ŵԪã + (*T).chead = (OLink*) malloc(((*T).nu + 1) * sizeof(OLink)); + if((*T).chead == NULL) { + exit(OVERFLOW); + } + + // ʼΪNULL + for(k = 0; k <= (*T).mu; ++k) { //ʼͷָΪ + (*T).rhead[k] = NULL; + } + + // ʼΪNULL + for(k = 0; k <= (*T).nu; ++k) { + (*T).chead[k] = NULL; + } + + // ɨ裬θƷԪ + for(k = 1; k <= M.mu; ++k) { + q = M.rhead[k]; + + // ǰûԪأֱ + if(q == NULL) { + continue; + } + + r = NULL; + + while(q != NULL) { + // Ԫ + p = (OLNode*) malloc(sizeof(OLNode)); + if(p == NULL) { + exit(OVERFLOW); + } + + // Ϊ㸳ֵ + p->i = q->i; + p->j = q->j; + p->e = q->e; + p->right = p->down = NULL; + + /* + * ʼеIJ + */ + + if(r == NULL) { + (*T).rhead[q->i] = p; + } else { + r->right = p; + } + + // rָǰ²Ľ + r = p; + + /* + * ʼеIJ + */ + + // ѰҲλ + if((*T).chead[q->j] == NULL || (*T).chead[q->j]->i > q->i) { + r->down = (*T).chead[q->j]; + (*T).chead[q->j] = r; + } else { + // ѰҲλõǰһλ + for(l = (*T).chead[q->j]; (l->down) && (l->down->i < q->i); l = l->down) { + } + r->down = l->down; + l->down = r; + } + + q = q->right; + } + } + + return OK; +} + +/* + * ӷ + * + * Q = M + N + */ +Status AddSMatrix(CrossList M, CrossList N, CrossList* Q) { + int i; + OLNode* pm, * pn, * p, * r, * l; + + if(M.mu != N.mu || M.nu != N.nu) { + printf("\n"); + return ERROR; + } + + // ʼQϢ + Q->mu = M.mu; + Q->nu = M.nu; + Q->tu = 0; + + // 0ŵԪã + Q->rhead = (OLink*) malloc((Q->mu + 1) * sizeof(OLink)); + if(!Q->rhead) { + exit(OVERFLOW); + } + + // 0ŵԪã + Q->chead = (OLink*) malloc((Q->nu + 1) * sizeof(OLink)); + if(!Q->chead) { + exit(OVERFLOW); + } + + // ʼΪNULL + for(i = 0; i <= Q->mu; ++i) { + Q->rhead[i] = NULL; + } + + // ʼΪNULL + for(i = 0; i <= Q->nu; ++i) { + Q->chead[i] = NULL; + } + + // ӵһ± + for(i = 1; i <= M.mu; ++i) { + pm = M.rhead[i]; + pn = N.rhead[i]; + + // MNĵǰоδķԪ + while(pm != NULL && pn != NULL) { + // + if(pm->j == pn->j && pm->e + pn->e == 0) { + pm = pm->right; + pn = pn->right; + continue; + } + + // + p = (OLNode*) malloc(sizeof(OLNode)); + if(!p) { + exit(OVERFLOW); + } + + // MеԪ±С + if(pm->j < pn->j) { + p->i = pm->i; + p->j = pm->j; + p->e = pm->e; + pm = pm->right; + + // NеԪ±С + } else if(pm->j > pn->j) { + p->i = pn->i; + p->j = pn->j; + p->e = pn->e; + pn = pn->right; + + // MNеԪ±һ£Ҫмӷ + } else { + p->i = pm->i; + p->j = pm->j; + p->e = pm->e + pn->e; + pm = pm->right; + pn = pn->right; + } + + p->right = p->down = NULL; + + Q->tu++; // QзԪһ + + /* + * ʼеIJ + */ + + if(Q->rhead[p->i] == NULL) { + Q->rhead[p->i] = p; + } else { + r->right = p; + } + + // rָǰ²Ľ + r = p; + + /* + * ʼеIJ + */ + + // ѰҲλ + if(Q->chead[p->j] == NULL || Q->chead[p->j]->i > p->i) { + r->down = Q->chead[p->j]; + Q->chead[p->j] = r; + } else { + // ѰҲλõǰһλ + for(l = Q->chead[p->j]; (l->down) && (l->down->i < p->i); l = l->down) { + } + r->down = l->down; + l->down = r; + } + } + + // MĵǰδķԪ + while(pm != NULL) { + p = (OLNode*) malloc(sizeof(OLNode)); + if(p == NULL) { + exit(OVERFLOW); + } + p->i = pm->i; + p->j = pm->j; + p->e = pm->e; + p->right = p->down = NULL; + + Q->tu++; // QзԪһ + + if(Q->rhead[p->i] == NULL) { + Q->rhead[p->i] = p; + } else { + r->right = p; + } + + // rָǰ²Ľ + r = p; + + // ѰҲλ + if(Q->chead[p->j] == NULL || Q->chead[p->j]->i > p->i) { + r->down = Q->chead[p->j]; + Q->chead[p->j] = r; + } else { + // ѰҲλõǰһλ + for(l = Q->chead[p->j]; (l->down) && (l->down->i < p->i); l = l->down) { + } + r->down = l->down; + l->down = r; + } + + pm = pm->right; + } + + // NĵǰδķԪ + while(pn != NULL) { + p = (OLNode*) malloc(sizeof(OLNode)); + if(p == NULL) { + exit(OVERFLOW); + } + p->i = pn->i; + p->j = pn->j; + p->e = pn->e; + p->right = p->down = NULL; + + Q->tu++; // QзԪһ + + if(Q->rhead[p->i] == NULL) { + Q->rhead[p->i] = p; + } else { + r->right = p; + } + + // rָǰ²Ľ + r = p; + + // ѰҲλ + if(Q->chead[p->j] == NULL || Q->chead[p->j]->i > p->i) { + r->down = Q->chead[p->j]; + Q->chead[p->j] = r; + } else { + // ѰҲλõǰһλ + for(l = Q->chead[p->j]; (l->down) && (l->down->i < p->i); l = l->down) { + } + r->down = l->down; + l->down = r; + } + + pn = pn->right; + } + } + + return OK; +} + +/* + * + * + * Q = M - N + */ +Status SubSMatrix(CrossList M, CrossList N, CrossList* Q) { + int i; + OLNode* pm, * pn, * p, * r, * l; + + if(M.mu != N.mu || M.nu != N.nu) { + printf("\n"); + return ERROR; + } + + // ʼQϢ + Q->mu = M.mu; + Q->nu = M.nu; + Q->tu = 0; + + // 0ŵԪã + Q->rhead = (OLink*) malloc((Q->mu + 1) * sizeof(OLink)); + if(!Q->rhead) { + exit(OVERFLOW); + } + + // 0ŵԪã + Q->chead = (OLink*) malloc((Q->nu + 1) * sizeof(OLink)); + if(!Q->chead) { + exit(OVERFLOW); + } + + // ʼΪNULL + for(i = 0; i <= Q->mu; ++i) { + Q->rhead[i] = NULL; + } + + // ʼΪNULL + for(i = 0; i <= Q->nu; ++i) { + Q->chead[i] = NULL; + } + + // ӵһ± + for(i = 1; i <= M.mu; ++i) { + pm = M.rhead[i]; + pn = N.rhead[i]; + + // MNĵǰоδķԪ + while(pm != NULL && pn != NULL) { + // + if(pm->j == pn->j && pm->e - pn->e == 0) { + pm = pm->right; + pn = pn->right; + continue; + } + + // + p = (OLNode*) malloc(sizeof(OLNode)); + if(!p) { + exit(OVERFLOW); + } + + // MеԪ±С + if(pm->j < pn->j) { + p->i = pm->i; + p->j = pm->j; + p->e = pm->e; + pm = pm->right; + + // NеԪ±С + } else if(pm->j > pn->j) { + p->i = pn->i; + p->j = pn->j; + p->e = -pn->e; // Ӹ + pn = pn->right; + + // MNеԪ±һ£Ҫм + } else { + p->i = pm->i; + p->j = pm->j; + p->e = pm->e - pn->e; + pm = pm->right; + pn = pn->right; + } + + p->right = p->down = NULL; + + Q->tu++; // QзԪһ + + /* + * ʼеIJ + */ + + if(Q->rhead[p->i] == NULL) { + Q->rhead[p->i] = p; + } else { + r->right = p; + } + + // rָǰ²Ľ + r = p; + + /* + * ʼеIJ + */ + + // ѰҲλ + if(Q->chead[p->j] == NULL || Q->chead[p->j]->i > p->i) { + r->down = Q->chead[p->j]; + Q->chead[p->j] = r; + } else { + //ѰҲλõǰһλ + for(l = Q->chead[p->j]; (l->down) && (l->down->i < p->i); l = l->down) { + } + r->down = l->down; + l->down = r; + } + } + + // MĵǰδķԪ + while(pm != NULL) { + p = (OLNode*) malloc(sizeof(OLNode)); + if(!p) { + exit(OVERFLOW); + } + p->i = pm->i; + p->j = pm->j; + p->e = pm->e; + p->right = p->down = NULL; + + Q->tu++; // QзԪһ + + if(Q->rhead[p->i] == NULL) { + Q->rhead[p->i] = p; + } else { + r->right = p; + } + + // rָǰ²Ľ + r = p; + + // ѰҲλ + if(Q->chead[p->j] == NULL || Q->chead[p->j]->i > p->i) { + r->down = Q->chead[p->j]; + Q->chead[p->j] = r; + } else { + // ѰҲλõǰһλ + for(l = Q->chead[p->j]; (l->down) && (l->down->i < p->i); l = l->down) { + } + r->down = l->down; + l->down = r; + } + + pm = pm->right; + } + + // NĵǰδķԪ + while(pn != NULL) { + p = (OLNode*) malloc(sizeof(OLNode)); + if(!p) { + exit(OVERFLOW); + } + p->i = pn->i; + p->j = pn->j; + p->e = -pn->e; // Ӹ + p->right = p->down = NULL; + + Q->tu++; // QзԪһ + + if(Q->rhead[p->i] == NULL) { + Q->rhead[p->i] = p; + } else { + r->right = p; + } + + // rָǰ²Ľ + r = p; + + // ѰҲλ + if(Q->chead[p->j] == NULL || Q->chead[p->j]->i > p->i) { + r->down = Q->chead[p->j]; + Q->chead[p->j] = r; + } else { + // ѰҲλõǰһλ + for(l = Q->chead[p->j]; (l->down) && (l->down->i < p->i); l = l->down) { + } + r->down = l->down; + l->down = r; + } + + pn = pn->right; + } + } + + return OK; +} + +/* + * ˷ + * + * Q = M * N + */ +Status MultSMatrix(CrossList M, CrossList N, CrossList* Q) { + int m_row, n_col, i; + ElemType e; + OLNode* pm, * pn, * p, * r, * l; + + // MҪN + if(M.nu != N.mu) { + printf("\n"); + return ERROR; + } + + // ʼQϢ + Q->mu = M.mu; + Q->nu = N.nu; + Q->tu = 0; + + // 0ŵԪã + Q->rhead = (OLink*) malloc((Q->mu + 1) * sizeof(OLink)); + if(!Q->rhead) { + exit(OVERFLOW); + } + + // 0ŵԪã + Q->chead = (OLink*) malloc((Q->nu + 1) * sizeof(OLink)); + if(!Q->chead) { + exit(OVERFLOW); + } + + // ʼΪNULL + for(i = 0; i <= Q->mu; ++i) { + Q->rhead[i] = NULL; + } + + // ʼΪNULL + for(i = 0; i <= Q->nu; ++i) { + Q->chead[i] = NULL; + } + + // QǷ + if(M.tu * N.tu) { + for(m_row = 1; m_row <= M.mu; ++m_row) { + for(n_col = 1; n_col <= N.nu; ++n_col) { + pm = M.rhead[m_row]; + pn = N.chead[n_col]; + + e = 0; + + // MN + while(pm && pn) { + if(pm->j < pn->i) { + pm = pm->right; + } else if(pm->j > pn->i) { + pn = pn->down; + } else { + e += pm->e * pn->e; + pm = pm->right; + pn = pn->down; + } + } + + if(e == 0) { + continue; + } + + p = (OLNode*) malloc(sizeof(OLNode)); + if(!p) { + exit(OVERFLOW); + } + + // Ϊ㸳ֵ + p->i = M.rhead[m_row]->i; + p->j = N.chead[n_col]->j; + p->e = e; + p->right = p->down = NULL; + + Q->tu++; // QзԪһ + + if(Q->rhead[p->i] == NULL) { + Q->rhead[p->i] = p; + } else { + r->right = p; + } + + // rָǰ²Ľ + r = p; + + // ѰҲλ + if(Q->chead[p->j] == NULL || Q->chead[p->j]->i > p->i) { + r->down = Q->chead[p->j]; + Q->chead[p->j] = r; + } else { + // ѰҲλõǰһλ + for(l = Q->chead[p->j]; (l->down) && (l->down->i < p->i); l = l->down) { + } + + r->down = l->down; + l->down = r; + } + } + } + } + + return OK; +} + +/* + * ת + */ +Status TransposeSMatrix(CrossList M, CrossList* T) { + int i; + OLNode* p, * q, * r, * l; + + // ʼQϢ + (*T).mu = M.nu; + (*T).nu = M.mu; + (*T).tu = M.tu; + + // 0ŵԪã + (*T).rhead = (OLink*) malloc(((*T).mu + 1) * sizeof(OLink)); + if(!(*T).rhead) { + exit(OVERFLOW); + } + + // 0ŵԪã + (*T).chead = (OLink*) malloc(((*T).nu + 1) * sizeof(OLink)); + if(!(*T).chead) { + exit(OVERFLOW); + } + + // ʼΪNULL + for(i = 0; i <= (*T).mu; ++i) { + (*T).rhead[i] = NULL; + } + + // ʼΪNULL + for(i = 0; i <= (*T).nu; ++i) { + (*T).chead[i] = NULL; + } + + // + if(!(*T).tu) { + return OK; + } + + // ɨ + for(i = 1; i <= M.nu; ++i) { + q = M.chead[i]; + + // ǰûԪأֱ + if(q == NULL) { + continue; + } + + while(q != NULL) { + // Ԫ + p = (OLNode*) malloc(sizeof(OLNode)); + if(!p) { + exit(OVERFLOW); + } + + // Ϊ㸳ֵбУб + p->i = q->j; + p->j = q->i; + p->e = q->e; + p->right = p->down = NULL; + + /* + * ʼеIJ + */ + + if((*T).rhead[p->i] == NULL) { + (*T).rhead[p->i] = p; + } else { + r->right = p; + } + + // rָǰ²Ľ + r = p; + + /* + * ʼеIJ + */ + + // ѰҲλ + if((*T).chead[p->j] == NULL || (*T).chead[p->j]->i > p->i) { + r->down = (*T).chead[p->j]; + (*T).chead[p->j] = r; + } else { + // ѰҲλõǰһλ + for(l = (*T).chead[p->j]; (l->down) && (l->down->i < p->i); l = l->down) { + } + r->down = l->down; + l->down = r; + } + + q = q->down; + } + } + + return OK; +} + +/* + * + */ +void PrintSMatrix(CrossList M) { + int i, j; + OLNode* p; + + for(i = 1; i <= M.mu; ++i) { + p = M.rhead[i]; + for(j = 1; j <= M.nu; ++j) { + if(p && p->j == j) { + printf("%3d ", p->e); + p = p->right; + } else { + printf("%3d ", 0); + } + } + printf("\n"); + } +} diff --git a/VisualC++/ExerciseBook/05.27/CrossList.h b/VisualC++/ExerciseBook/05.27/CrossList.h new file mode 100644 index 0000000..c774280 --- /dev/null +++ b/VisualC++/ExerciseBook/05.27/CrossList.h @@ -0,0 +1,94 @@ +/*=================== + * ʮϡ + * + * 㷨: 5.4 + ====================*/ + +#ifndef CROSSLIST_H +#define CROSSLIST_H + +#include +#include // ṩmallocreallocfreeexitԭ +#include // ṩ strstr ԭ +#include "Status.h" //**01 **// + +/* ʮԪ */ +typedef int ElemType; + +/* ԪͶ */ +typedef struct OLNode { + int i, j; // ÷Ԫ±± + ElemType e; + struct OLNode* right; // ÷Ԫڵбĺ + struct OLNode* down; // ÷Ԫڵбĺ +} OLNode, * OLink; + +/* ʮͶ */ +typedef struct { + OLink* rhead; // ͷָ + OLink* chead; // ͷָ + int mu, nu, tu; // ͷԪ +} CrossList; + + +/* + * 㷨5.4 + * + * ϡM + * + * + *ע + * + * ̲Ĭϴӿ̨ȡݡ + * Ϊ˷ԣÿжֶݣ + * ѡԤļpathжȡݡ + * + * Ҫӿ̨ȡݣpathΪNULLΪմ + * ҪļжȡݣҪpathдļϢ + */ +Status CreateSMatrix(CrossList* M, char* path); + +/* + * ϡ + */ +Status DestroySMatrix(CrossList* M); + +/* + * + * + * һ¾Tþ˴ӾMаݡ + */ +Status CopySMatrix(CrossList M, CrossList* T); + +/* + * ӷ + * + * Q = M + N + */ +Status AddSMatrix(CrossList M, CrossList N, CrossList* Q); + +/* + * + * + * Q = M - N + */ +Status SubSMatrix(CrossList M, CrossList N, CrossList* Q); + +/* + * ˷ + * + * Q = M * N + */ +Status MultSMatrix(CrossList M, CrossList N, CrossList* Q); + +/* + * ת + */ +Status TransposeSMatrix(CrossList M, CrossList* T); + +/* + * + */ +void PrintSMatrix(CrossList M); + +#endif diff --git a/VisualC++/ExerciseBook/05.27/TestData_M.txt b/VisualC++/ExerciseBook/05.27/TestData_M.txt new file mode 100644 index 0000000..be25c94 --- /dev/null +++ b/VisualC++/ExerciseBook/05.27/TestData_M.txt @@ -0,0 +1,4 @@ +5 +5 +Ԫ10 +Ԫ飺(1,2,1),(1,4,5),(2,3,-3),(2,5,2),(3,1,2),(3,2,3),(3,3,4),(4,4,2),(5,1,3),(5,2,-1) \ No newline at end of file diff --git a/VisualC++/ExerciseBook/05.27/TestData_N.txt b/VisualC++/ExerciseBook/05.27/TestData_N.txt new file mode 100644 index 0000000..7c940db --- /dev/null +++ b/VisualC++/ExerciseBook/05.27/TestData_N.txt @@ -0,0 +1,4 @@ +5 +5 +Ԫ8 +Ԫ飺(1,1,-3)(1,3,2)(2,4,-1)(3,2,4)(4,1,6)(4,5,5)(5,1,3)(5,3,2) \ No newline at end of file diff --git a/VisualC++/ExerciseBook/05.28-05.29/05.28-05.29.c b/VisualC++/ExerciseBook/05.28-05.29/05.28-05.29.c new file mode 100644 index 0000000..eb0a701 --- /dev/null +++ b/VisualC++/ExerciseBook/05.28-05.29/05.28-05.29.c @@ -0,0 +1,336 @@ +#include +#include "MPList.h" //**05 ͹**// + +/* + * mԪʽPеһԪƫPD + * + * ԤһԪΪⲿ + */ +Status Algo_5_28(MPList P, MPList* PD); + +/* + * ָexp˵ʽPԭӽϵ + */ +static void HandleExp(MPList P, int exp); + +/* + * ʽӷR = P + Q + */ +Status Algo_5_29(MPList P, MPList Q, MPList* R); + +/* + * ԷǿյĶԶʽPQӣPQָǸԪбͷ㡣 + */ +static void AddMpList(MPList P, MPList Q, MPList* R); + +/* + * 󴴽һ½㡣 + * tpΪNULLΪԭӽһͷ㣬Ϊӱͷ㡣 + * vΪͷԪ + */ +static MPList VirtualNode(int v, MPList tp, MPList hp); + + +int main(int argc, char* argv[]) { + MPList P, Q; + MPList PD, QD; + MPList R; + char *p = "z((3,y((1,x((3, 1))))),(2,y((2,1))),(0,3))"; + char *q = "z((4,1),(3,y((1,x((3,-1))))),(2,x((1,1))),(0,y((1,1),(0,4))))"; + + printf("Ԫʽ...\n"); + CreateMPList(&P, p, "zyx"); + printf("P = "); + PrintGraph(P); + CreateMPList(&Q, q, "zyx"); + printf("Q = "); + PrintGraph(Q); + + // һԪƫ + printf("P' = "); + Algo_5_28(P, &PD); + PrintGraph(PD); + printf("Q' = "); + Algo_5_28(Q, &QD); + PrintGraph(QD); + + // ʽӷ + printf("R = "); + Algo_5_29(P, Q, &R); + PrintGraph(R); +} + + +/* + * mԪʽPеһԪƫPD + * + * ԤһԪΪⲿ + */ +Status Algo_5_28(MPList P, MPList* PD) { + MPList r, rd, s; + int count; + + if(P == NULL || PD == NULL) { + return ERROR; + } + + // ʽ + *PD = (MPList) malloc(sizeof(MPNode)); + (*PD)->tag = List; + (*PD)->exp = P->exp; + (*PD)->tp = NULL; + + // ͷ + (*PD)->Node.hp = (MPList) malloc(sizeof(MPNode)); + (*PD)->Node.hp->tag = P->Node.hp->tag; + (*PD)->Node.hp->exp = P->Node.hp->exp; + (*PD)->Node.hp->Node.hp = P->Node.hp->Node.hp; + + r = P->Node.hp; // ָPͷ + rd = (*PD)->Node.hp; // ָPDͷ + count = 0; + + // һԪб + while(r->tp != NULL) { + r = r->tp; + + // û""㣬ߣʽPһ"" + if(r->exp!=0 || count==0) { + rd->tp = (MPList) malloc(sizeof(MPNode)); + rd = rd->tp; + } + + /* + * ""㣬󵼺Ϊ0 + * ע""ָΪ0 + */ + if(r->exp == 0) { + // ʽPһ"" + if(count==0) { + rd->tag = Atom; + rd->exp = 0; + rd->Node.coef = 0; + } + + break; + } + + rd->tag = r->tag; + rd->exp = r->exp - 1; + + // ԭӽ㣬ֱӼϵ + if(r->tag==Atom) { + rd->Node.coef = r->Node.coef * r->exp; // ָϵ + + // ӱ㣬Ҫָ˵ʵλ + } else { + Copy(r->Node.hp, &(rd->Node.hp)); + + // ָΪ1ʱûҪ˵ + if(r->exp!=1) { + // ָexp˵ʽPԭӽϵ + HandleExp(rd->Node.hp, r->exp); + } + } + + count++; + } + + rd->tp = NULL; + + return OK; +} + +/* + * ָexp˵ʽPԭӽϵ + */ +static void HandleExp(MPList P, int exp) { + MPList r; + + if(P == NULL) { + return; + } + + for(r = P->tp; r != NULL; r = r->tp) { + if(r->tag == Atom) { + r->Node.coef *= exp; + } else { + HandleExp(r->Node.hp, exp); + } + } +} + +/* + * ʽӷR = P + Q + */ +Status Algo_5_29(MPList P, MPList Q, MPList* R) { + MPList r; + + // ҪʽԪ + if(P == NULL || Q == NULL || R==NULL || P->exp != Q->exp) { + return ERROR; + } + + // ʽ + *R = (MPList) malloc(sizeof(MPNode)); + if(*R == NULL) { + exit(OVERFLOW); + } + (*R)->tag = List; + (*R)->exp = P->exp; // ʽԪ + (*R)->tp = NULL; + + AddMpList(P->Node.hp, Q->Node.hp, &r); + + if(r->tp == NULL) { + r->tp = (MPList) malloc(sizeof(MPNode)); + r->tp->tag = Atom; + r->tp->exp = 0; + r->tp->Node.coef = 0.0f; + r->tp->tp = NULL; + } + + (*R)->Node.hp = r; + + return OK; +} + +/* + * ԷǿյĶԶʽPQӣPQָǸԪбͷ㡣 + */ +static void AddMpList(MPList P, MPList Q, MPList* R) { + MPList p, q, h, r; + MPList t; + MPList tp; + float sum; + int a, b; + int v; + + // ͬһԪ + if(P->exp!=Q->exp) { + + a = (int)(strchr(Var, P->exp)-Var); + b = (int)(strchr(Var, Q->exp)-Var); + + if(aexp, NULL, Q); + v = P->exp; + } + + if(a>b) { + P = VirtualNode(Q->exp, NULL, P); + v = Q->exp; + } + } else { + v = P->exp; + } + + // ͷ + *R = (MPList) malloc(sizeof(MPNode)); + (*R)->tag = List; + (*R)->exp = v; + (*R)->Node.hp =NULL; + + h = *R; + + p = P->tp; + q = Q->tp; + + while(p!=NULL && q!=NULL){ + if(p->exp>q->exp) { + tp = p->tp; + p->tp = NULL; + Copy(p, &(h->tp)); + p->tp = tp; + p = p->tp; + h = h->tp; + } else if(p->expexp) { + tp = q->tp; + q->tp = NULL; + Copy(q, &(h->tp)); + q->tp = tp; + q = q->tp; + h = h->tp; + + // ָͬ + } else { + sum = 0.0f; // ʼϵͣһõ + r = NULL; + + if(p->tag==Atom && q->tag==List) { + t = VirtualNode(q->Node.hp->exp, p, NULL); + tp = p->tp; + p->tp = NULL; + AddMpList(t, q->Node.hp, &r); + p->tp = tp; + } else if(p->tag==List && q->tag==Atom) { + t = VirtualNode(p->Node.hp->exp, q, NULL); + tp = q->tp; + q->tp = NULL; + AddMpList(p->Node.hp, t, &r); + q->tp = tp; + + // ӱ + } else if(p->tag==List && q->tag==List) { + AddMpList(p->Node.hp, q->Node.hp, &r); + + // ԭӵĻֱ + } else if(p->tag==Atom && q->tag==Atom) { + sum = p->Node.coef + q->Node.coef; + } + + if(sum!=0.0f || (r!=NULL && r->tp!=NULL)) { + h->tp = (MPList) malloc(sizeof(MPNode)); + h = h->tp; + h->exp = p->exp; + + if(sum!=0.0f) { + h->tag = Atom; + h->Node.coef = sum; + } else { + h->tag = List; + h->Node.hp = r; + } + } + + p = p->tp; + q = q->tp; + } + } + + h->tp = NULL; + + if(p!=NULL){ + Copy(p, &(h->tp)); + } + + if(q!=NULL){ + Copy(q, &(h->tp)); + } +} + +/* + * 󴴽һ½㡣 + * tpΪNULLΪԭӽһͷ㣬Ϊӱͷ㡣 + * vΪͷԪ + */ +static MPList VirtualNode(int v, MPList tp, MPList hp){ + MPList P; + + P = (MPList) malloc(sizeof(MPNode)); + P->tag = List; + P->exp = v; + P->Node.hp = NULL; + + if(tp!=NULL) { + P->tp = tp; + } else { + P->tp = (MPList) malloc(sizeof(MPNode)); + P->tp->exp = 0; + P->tp->tag = List; + P->tp->Node.hp = hp; + P->tp->tp = NULL; + } + + return P; +} diff --git a/VisualC++/ExerciseBook/05.28-05.29/05.28-05.29.vcxproj b/VisualC++/ExerciseBook/05.28-05.29/05.28-05.29.vcxproj new file mode 100644 index 0000000..e44d727 --- /dev/null +++ b/VisualC++/ExerciseBook/05.28-05.29/05.28-05.29.vcxproj @@ -0,0 +1,78 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {1E4BBDA3-6E21-433D-95B3-CCBB7A450A34} + My05280529 + + + + Application + true + MultiByte + + + Application + false + true + MultiByte + + + + + + + + + + + + + $(SolutionDir)\..\Status;$(IncludePath) + + + + Level3 + Disabled + + + true + $(SolutionDir)\..\Status\Status.lib;%(AdditionalDependencies) + Console + + + + + Level3 + MaxSpeed + true + true + + + true + true + true + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/05.28-05.29/05.28-05.29.vcxproj.filters b/VisualC++/ExerciseBook/05.28-05.29/05.28-05.29.vcxproj.filters new file mode 100644 index 0000000..a479b20 --- /dev/null +++ b/VisualC++/ExerciseBook/05.28-05.29/05.28-05.29.vcxproj.filters @@ -0,0 +1,36 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + 源文件 + + + 源文件 + + + 源文件 + + + + + 头文件 + + + 头文件 + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/05.28-05.29/05.28-05.29.vcxproj.user b/VisualC++/ExerciseBook/05.28-05.29/05.28-05.29.vcxproj.user new file mode 100644 index 0000000..ace9a86 --- /dev/null +++ b/VisualC++/ExerciseBook/05.28-05.29/05.28-05.29.vcxproj.user @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/05.28-05.29/MPList.c b/VisualC++/ExerciseBook/05.28-05.29/MPList.c new file mode 100644 index 0000000..1f08b74 --- /dev/null +++ b/VisualC++/ExerciseBook/05.28-05.29/MPList.c @@ -0,0 +1,233 @@ +/*========== + * mԪʽ + ===========*/ + +#include "MPList.h" + +// μͷļе +char Var[27]; + +/* + * + * + * ַSmԪP + * УSǷдȷ + * + * P : Ķʽ + * S : ʽַ + * vars: бӵһԪʼУxyzԪʽеδ֪ + */ +Status CreateMPList(MPList* P, char* S, char* vars) { + if(P == NULL) { + return ERROR; + } + + // ַSеĿհףɴӡַո + ClearBlank(&S); + + if(strlen(S) == 0) { + *P = NULL; + return ERROR; + } + + // ʼԪϢ + strcpy(Var, vars); + + *P = (MPList) malloc(sizeof(MPNode)); + if(*P == NULL) { + exit(OVERFLOW); + } + + (*P)->tag = List; + (*P)->exp = (int) strlen(vars); + (*P)->tp = NULL; + + Create(&(*P)->Node.hp, S); + + return OK; +} + +/* + * mԪʽ + */ +static Status Create(MPList* P, char* S) { + char* Sc; + char* hhstr, * hstr, * str; + char* sub; + MPList r; + float f; + + // ȡSһ + SubString(&Sc, S, 1, (int) strlen(S)); + + *P = (MPList) malloc(sizeof(MPNode)); + if(*P == NULL) { + exit(OVERFLOW); + } + + (*P)->tag = List; + (*P)->exp = (int) Sc[0]; // δ֪ǣxyz + (*P)->Node.hp = NULL; + (*P)->tp = NULL; + + StrDelete(&Sc, 1, 1); // ɾδ֪ + SubString(&str, Sc, 2, (int) strlen(Sc) - 2); // ȥ + + r = *P; + + while(!StrEmpty(str)) { + // + sever(&hstr, &str); + + SubString(&sub, hstr, 2, (int) strlen(hstr) - 2); // ȥ + sever(&hhstr, &sub); + + // ӽ + r->tp = (MPList) malloc(sizeof(MPNode)); + if(r->tp == NULL) { + exit(OVERFLOW); + } + GetElem(hhstr, 1, &f); + r->tp->exp = (int) f; // ȡָ + r->tp->tp = NULL; + + if(ElemCount(sub) == 1) { + r->tp->tag = Atom; + GetElem(sub, 1, &f); + r->tp->Node.coef = f; + } else { + r->tp->tag = List; + Create(&(r->tp->Node.hp), sub); + } + + r = r->tp; + } + + return OK; +} + +/* + * ͼλ + * + * mԪP + */ +void PrintGraph(MPList P) { + if(P == NULL) { + printf("\n"); + return; + } + Print(P->Node.hp); + printf("\n"); +} + +/* + * ͼλڲʵ + */ +static void Print(MPList head) { + MPList p; + + if(head == NULL) { + return; + } + + printf("%c(", head->exp); + + p = head->tp; + + while(p != NULL) { + printf("(%d,", p->exp); + + if(p->tag == List) { + Print(p->Node.hp); + } else { + printf("%.2f", p->Node.coef); + } + + printf(")"); + + p = p->tp; + + if(p != NULL) { + printf(","); + } + } + + printf(")"); +} + +/* + * ǿմstrָ֣hsubΪһ','֮ǰӴstrΪһ','֮Ӵ + * + *ע + * 1.ַstrȷ޿հ׷ţstrѾȥš + * 2.ɺstrҲᷢ仯 + */ +static void sever(char** hstr, char** str) { + int i, k, n; + + char* head, * tail; + + // strΪʱhstrҲΪ + if(strlen(*str) == 0) { + *hstr = NULL; + return; + } + + n = (int) strlen(*str); + + i = 0; // ַʱα + k = 0; // δ + + do { + if((*str)[i] == '(') { + ++k; + } + + if((*str)[i] == ')') { + --k; + } + + i++; + } while(i < n && ((*str)[i] != ',' || k != 0)); + + if(i < n) { + head = (char*) malloc((i + 1) * sizeof(char)); + tail = (char*) malloc((n - i - 1 + 1) * sizeof(char)); + + strncpy(head, *str, i); + head[i] = '\0'; + + strncpy(tail, (*str + i + 1), n - i - 1); + tail[n - i - 1] = '\0'; + } else { + head = *str; + tail = (char*) malloc(sizeof(char)); + tail[0] = '\0'; + } + + *hstr = head; + *str = tail; +} + + +/* + * ƶʽPƵQ + */ +void Copy(MPList P, MPList* Q) { + if(P == NULL) { + *Q = NULL; + return; + } + + *Q = (MPList) malloc(sizeof(MPNode)); + (*Q)->tag = P->tag; + (*Q)->exp = P->exp; + + if(P->tag == List) { + Copy(P->Node.hp, &((*Q)->Node.hp)); + } else { + (*Q)->Node.coef = P->Node.coef; + } + + Copy(P->tp, &((*Q)->tp)); +} diff --git a/VisualC++/ExerciseBook/05.28-05.29/MPList.h b/VisualC++/ExerciseBook/05.28-05.29/MPList.h new file mode 100644 index 0000000..455e7ea --- /dev/null +++ b/VisualC++/ExerciseBook/05.28-05.29/MPList.h @@ -0,0 +1,97 @@ +/*========== + * mԪʽ + ===========*/ + +#ifndef MPLIST_H +#define MPLIST_H + +#include +#include // ṩ mallocreallocfreeexit ԭ +#include // ṩ strlen ԭ +#include "Status.h" //**01 **// +#include "StringUtil.h" //**ַ**// + +/* + * ʾ + * + * 1.ڶԪԼһԪλ㡣 + * 2.δ֪ĬΪa~zA~Z26ĸ + * 3.ԼʽÿԪָǡݼģ321 + */ + + +/* + * 浱ǰʽıϢxyz + * Լvarеַ˳λԪĴ磺 + * "zyx"ָʾzΪһԪyΪڶԪxΪԪ + */ +extern char Var[27]; + +/* + * mԪʽ + * + * Atom-0ԭӽ + * List-1 + */ +typedef enum { Atom, List } ElemTag; + +/* mԪʽԪؽ */ +typedef struct MPNode { + ElemTag tag; // ԭӽͱ + int exp; // ָ򣬶ͷ㣬洢δ֪ǣxyz + union { + float coef; // ϵ + struct MPNode* hp; // ıͷָ + } Node; + struct MPNode* tp; // ൱nextָһԪؽ +} MPNode; + +/* mԪʽ */ +typedef MPNode* MPList; + + +/* + * + * + * ַSmԪP + * УSǷдȷ + * + * P : Ķʽ + * S : ʽַ + * vars: бӵһԪʼУxyzԪʽеδ֪ + */ +Status CreateMPList(MPList* P, char* S, char* vars); + +/* + * mԪʽ + */ +static Status Create(MPList* P, char* S); + +/* + * ͼλ + * + * mԪP + */ +void PrintGraph(MPList P); + +/* + * ͼλڲʵ + */ +static void Print(MPList P); + +/* + * ǿմstrָ֣hsubΪһ','֮ǰӴstrΪһ','֮Ӵ + * + *ע + * 1.ַstrȷ޿հ׷ţstrѾȥš + * 2.ɺstrҲᷢ仯 + */ +static void sever(char** hstr, char** str); + + +/* + * ƶʽ + */ +void Copy(MPList P, MPList* Q); + +#endif diff --git a/VisualC++/ExerciseBook/05.28-05.29/StringUtil.c b/VisualC++/ExerciseBook/05.28-05.29/StringUtil.c new file mode 100644 index 0000000..b1b0fbf --- /dev/null +++ b/VisualC++/ExerciseBook/05.28-05.29/StringUtil.c @@ -0,0 +1,160 @@ +/*================ + * ַ + =================*/ + +#include "StringUtil.h" + +/* + * ɾ + * + * ɾs[pos, pos+len-1]pos1ʼ + */ +Status StrDelete(char** s, int pos, int n) { + int len; + char* ss; + + len = (int) strlen(*s); + + if(pos < 1 || pos + n - 1 > len || n < 0) { + return ERROR; + } + + // ɾijΪ0ǰ + if(n == 0) { + return ERROR; + } + + ss = (char*) malloc((len - n + 1) * sizeof(char)); + + strncpy(ss, *s, pos - 1); + strncpy(ss, *s + pos + n - 1, len - pos - n + 1); + + ss[len - n] = '\0'; + + *s = ss; + + return OK; +} + +/* + * Ӵ + * + * subs[pos, pos+len-1]pos1ʼ + */ +Status SubString(char** sub, char* s, int pos, int n) { + int len, i; + + len = (int) strlen(s); + + if(pos < 1 || pos > len || n < 0 || pos + n - 1 > len) { + *sub = NULL; + return ERROR; + } + + *sub = (char*) malloc((n + 1) * sizeof(char)); + + for(i = 0; i < n; i++) { + (*sub)[i] = s[pos + i - 1]; + } + + // ȷ³ + (*sub)[n] = '\0'; + + return OK; +} + +/* + * п + * + * жϴsǷЧݡ + */ +Status StrEmpty(char* s) { + return strlen(s) == 0 ? TRUE : FALSE; +} + +/* + * + * + * ַsеĿհףɴӡַո + */ +Status ClearBlank(char** s) { + int len; + int i, j; + char* ss; + + len = (int) strlen(*s); + if(len == 0) { + return ERROR; + } + + ss = (char*) malloc((len + 1) * sizeof(char)); + + for(i = 0, j = 0; i < len; i++) { + // հףԹ + if((*s)[i] == ' ' || !isprint((*s)[i])) { + continue; + } + + ss[j++] = (*s)[i]; + } + + ss[j] = '\0'; + + *s = ss; + + return OK; +} + +/* + * + * + * ͳַsеԪظ + * ֮ڣ֣Ὣ䵱һԪء + */ +int ElemCount(const char* s) { + int count; + float f; + char c; + char* sub; + + if(s==NULL || strlen(s) == 0) { + return 0; + } + + sub = (char*) malloc((strlen(s) + 1) * sizeof(char)); + sub[0] = '\0'; + + // + if(sscanf(s, "%f", &f) == 1) { + sscanf(s, "%f%s", &f, sub); + } else { + sscanf(s, "%c%s", &c, sub); + } + + count = ElemCount(sub); + + return 1 + count; +} + +/* + * ȡֵ + * + * ȡַsеposԪ(pos1ʼ)fա + * ֮ڣ֣Ὣ䵱һԪء + */ +Status GetElem(char* s, int pos, float* f) { + int len; + + len = (int) strlen(s); + + if(pos < 1 || pos > len) { + return ERROR; + } + + // ȳԶ֣ȡʧܵĻٳԶַ + if(sscanf(s + pos - 1, "%f", f) < 1) { + *f = s[pos - 1]; + } + + return OK; +} diff --git a/VisualC++/ExerciseBook/05.28-05.29/StringUtil.h b/VisualC++/ExerciseBook/05.28-05.29/StringUtil.h new file mode 100644 index 0000000..e535a5e --- /dev/null +++ b/VisualC++/ExerciseBook/05.28-05.29/StringUtil.h @@ -0,0 +1,58 @@ +/*================ + * ַ + =================*/ + +#ifndef STRINGUTIL_H +#define STRINGUTIL_H + +#include +#include // ṩ malloc ԭ +#include // ṩ strlenstrncpy ԭ +#include // ṩ isprint ԭ +#include "Status.h" //**01 **// + +/* + * ɾ + * + * ɾs[pos, pos+len-1]pos1ʼ + */ +Status StrDelete(char** S, int pos, int n); + +/* + * Ӵ + * + * subs[pos, pos+len-1]pos1ʼ + */ +Status SubString(char** sub, char* s, int pos, int len); + +/* + * п + * + * жϴsǷЧݡ + */ +Status StrEmpty(char* s); + +/* + * + * + * ַsеĿհףɴӡַո + */ +Status ClearBlank(char** s); + +/* + * + * + * ͳַsеԪظ + * ֮ڣ֣Ὣ䵱һԪء + */ +int ElemCount(const char* s); + +/* + * ȡֵ + * + * ȡַsеposԪ(pos1ʼ)fա + * ֮ڣ֣Ὣ䵱һԪء + */ +Status GetElem(char* s, int pos, float *f); + +#endif diff --git a/VisualC++/ExerciseBook/05.30.1/05.30.1.c b/VisualC++/ExerciseBook/05.30.1/05.30.1.c new file mode 100644 index 0000000..00aefcc --- /dev/null +++ b/VisualC++/ExerciseBook/05.30.1/05.30.1.c @@ -0,0 +1,42 @@ +#include +#include "SString.h" //**04 **// +#include "GList-HT.h" //**05 ͹**// + +// ȣͷβ洢ʾ +int Algo_5_30_1(GList L); + + +int main(int argc, char* argv[]) { + GList L; + char* s = "((),(e),(a,(b,c,d)))"; + SString S; + + printf(" L ...\n"); + StrAssign(S, s); + CreateGList(&L, S); + printf("L = "); + PrintGraph(L); + + printf("Ϊ %d\n", Algo_5_30_1(L)); + + return 0; +} + + +// ȣͷβ洢ʾ +int Algo_5_30_1(GList L) { + int m, n; + + if(L==NULL) { + return 1; // ձΪ1 + } + + if(L->tag == Atom) { + return 0; // ԭΪ0 + } + + m = Algo_5_30_1(L->Node.ptr.hp) + 1; + n = Algo_5_30_1(L->Node.ptr.tp); + + return m > n ? m : n; +} diff --git a/VisualC++/ExerciseBook/05.30.1/05.30.1.vcxproj b/VisualC++/ExerciseBook/05.30.1/05.30.1.vcxproj new file mode 100644 index 0000000..199b6aa --- /dev/null +++ b/VisualC++/ExerciseBook/05.30.1/05.30.1.vcxproj @@ -0,0 +1,78 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {404AA05D-2412-4645-9E2C-280BFC6284FD} + My05301 + + + + Application + true + MultiByte + + + Application + false + true + MultiByte + + + + + + + + + + + + + $(SolutionDir)\..\Status;$(IncludePath) + + + + Level3 + Disabled + + + true + $(SolutionDir)\..\Status\Status.lib;%(AdditionalDependencies) + Console + + + + + Level3 + MaxSpeed + true + true + + + true + true + true + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/05.30.1/05.30.1.vcxproj.filters b/VisualC++/ExerciseBook/05.30.1/05.30.1.vcxproj.filters new file mode 100644 index 0000000..229a44d --- /dev/null +++ b/VisualC++/ExerciseBook/05.30.1/05.30.1.vcxproj.filters @@ -0,0 +1,36 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + 源文件 + + + 源文件 + + + 源文件 + + + + + 头文件 + + + 头文件 + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/05.30.1/05.30.1.vcxproj.user b/VisualC++/ExerciseBook/05.30.1/05.30.1.vcxproj.user new file mode 100644 index 0000000..ace9a86 --- /dev/null +++ b/VisualC++/ExerciseBook/05.30.1/05.30.1.vcxproj.user @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/05.30.1/GList-HT.c b/VisualC++/ExerciseBook/05.30.1/GList-HT.c new file mode 100644 index 0000000..bad30df --- /dev/null +++ b/VisualC++/ExerciseBook/05.30.1/GList-HT.c @@ -0,0 +1,418 @@ +/*============================ + * ͷβ洢ʾ + * + * 㷨: 5.55.65.75.8 + =============================*/ + +#include "GList-HT.h" //**05 ͹**// + +/* + * ʼ + * + * ʼյĹΪ0Ϊ1 + * + *ע + * Ҫÿһȥſ + */ +Status InitGList(GList* L) { + if(L == NULL) { + return ERROR; + } + + *L = NULL; + + return OK; +} + +/* + * 㷨5.7 + * + * + * + * ַSL + */ +Status CreateGList(GList* L, SString S) { + SString emp; // չַ + SString hsub, sub; + GList p, q; + + if(L == NULL) { + return ERROR; + } + + // ַSеĿհףɴӡַո + ClearBlank(S); + + if(StrEmpty(S)) { + return ERROR; + } + + StrAssign(emp, "()"); + + /* + * 봮Ϊ()ҪյĹ + * + *ע + * ̲Ĵġ + * StrCompareķֵָʾַĴСָʾַǷȡ + * S()ȣֵӦ0 + */ + if(!StrCompare(S, emp)) { + *L = NULL; + } else { + *L = (GList) malloc(sizeof(GLNode)); + if(*L == NULL) { + exit(OVERFLOW); + } + + // ԭ + if(StrLength(S) == 1) { + (*L)->tag = Atom; + (*L)->Node.atom = S[1]; + } else { + (*L)->tag = List; + + p = *L; + + // ȥ + SubString(sub, S, 2, StrLength(S) - 2); + + // ظnӱ + do { + // subзͷhsubɺsubҲᷢ仯 + sever(hsub, sub); + + // ݹ鴴 + CreateGList(&(p->Node.ptr.hp), hsub); + + q = p; + + // βΪգҪβ + if(!StrEmpty(sub)) { + p = (GList) malloc(sizeof(GLNode)); + if(p == NULL) { + exit(OVERFLOW); + } + + p->tag = List; + + q->Node.ptr.tp = p; + } + } while(!StrEmpty(sub)); + + q->Node.ptr.tp = NULL; + } + } + + return OK; +} + +/* + * + * + * ͷŹռڴ档 + */ +Status DestroyGList(GList* L) { + GList head, tail; + + if(L == NULL || *L == NULL) { + return ERROR; + } + + // ɾԭӽ + if((*L)->tag == Atom) { + free(*L); + *L = NULL; + + // ɾӱ + } else { + head = (*L)->Node.ptr.hp; + tail = (*L)->Node.ptr.tp; + free(*L); + *L = NULL; + DestroyGList(&head); + DestroyGList(&tail); + } + + return OK; +} + +/* + * 㷨5.6 + * + * + * + * ɹLƵõT + */ +Status CopyGList(GList* T, GList L) { + if(T == NULL) { + return ERROR; + } + + if(L == NULL) { + *T = NULL; + } else { + // ½ + *T = (GList) malloc(sizeof(GLNode)); + if(*T == NULL) { + exit(OVERFLOW); + } + + (*T)->tag = L->tag; + + // Ƶԭ + if(L->tag == Atom) { + (*T)->Node.atom = L->Node.atom; + + // Ʊͷͱβ + } else { + CopyGList(&((*T)->Node.ptr.hp), L->Node.ptr.hp); + CopyGList(&((*T)->Node.ptr.tp), L->Node.ptr.tp); + } + } + + return OK; +} + +/* + * + * + * عijȡ + */ +int GListLength(GList L) { + int count; + + for(count = 0; L != NULL; count++, L = L->Node.ptr.tp) { + } + + return count; +} + +/* + * 㷨5.5 + * + * + * + * ع + */ +int GListDepth(GList L) { + int max, deep; + GList p; + + // ձΪ1 + if(L == NULL) { + return 1; + } + + // ԭΪ0 + if(L->tag == Atom) { + return 0; + } + + // ݹӱ + for(max = 0, p = L; p != NULL; p = p->Node.ptr.tp) { + deep = GListDepth(p->Node.ptr.hp); + if(deep > max) { + max = deep; + } + } + + // ǿձǸԪȼһ + return max + 1; +} + +/* + * п + * + * жϹǷΪա + */ +Status GListEmpty(GList L) { + return L == NULL ? TRUE : FALSE; +} + +/* + * ͷ + */ +GList GetHead(GList L) { + GList p; + + // ձޱͷﲻܷNULLȻֲʧ˻Ƿ˿ձ + if(L == NULL) { + exit(ERROR); + } + + CopyGList(&p, L->Node.ptr.hp); + + return p; +} + +/* + * β + */ +GList GetTail(GList L) { + GList p; + + // ձޱβﲻܷNULLȻֲʧ˻Ƿ˿ձ + if(L == NULL) { + exit(ERROR); + } + + CopyGList(&p, L->Node.ptr.tp); + + return p; +} + +/* + * + * + * ԪeΪLĵһԪء + */ +Status InsertFirst(GList* L, GList e) { + GList g; + + if(L == NULL) { + return ERROR; + } + + g = (GList) malloc(sizeof(GLNode)); + if(g == NULL) { + exit(OVERFLOW); + } + + g->tag = List; + g->Node.ptr.hp = e; + g->Node.ptr.tp = *L; + *L = g; + + return OK; +} + +/* + * ɾ + * + * LĵһԪɾeء + */ +Status DeleteFirst(GList* L, GList* e) { + GList p; + + // ձ޷ɾ + if(L == NULL || *L == NULL) { + return ERROR; + } + + p = *L; + *L = (*L)->Node.ptr.tp; + + CopyGList(e, p->Node.ptr.hp); + + free(p); + + return OK; +} + +/* + * + * + * visitʹL + */ +void Traverse(GList L, void(Visit)(AtomType)) { + + if(L == NULL) { + return; + } + + if(L->tag == Atom) { + Visit(L->Node.atom); + } else { + Traverse(L->Node.ptr.hp, Visit); + Traverse(L->Node.ptr.tp, Visit); + } + +} + +/* + * ͼλ + * + * L + */ +void PrintGraph(GList L) { + Print(L, Head); + printf("\n"); +} + +/* + * ͼλڲʵ֣markͼλǡ + */ +static void Print(GList L, Mark mark) { + // LΪ + if(L == NULL) { + if(mark == Head) { + printf("("); + } + + printf(")"); + + // LΪʱ + } else { + // ԭӽ㣬ԭ + if(L->tag == Atom) { + printf("%c", L->Node.atom); + + // ӱ㣬ҪԱͷβֱ + } else { + if(mark == Head) { + printf("("); + } else { + printf(","); + } + + Print(L->Node.ptr.hp, Head); + Print(L->Node.ptr.tp, Tail); + } + } +} + +/* + * 㷨5.8 + * + * ǿմstrָ֣hsubΪһ','֮ǰӴstrΪһ','֮Ӵ + * + *ע + * 1.ַstrȷ޿հ׷ţstrѾȥš + * 2.ɺstrҲᷢ仯 + */ +static void sever(SString hstr, SString str) { + int i, k, n; + SString ch; + + n = StrLength(str); + + i = 0; // ַʱα + k = 0; // δ + + do { + ++i; + + // ȡstrһַ + SubString(ch, str, i, 1); + + if(ch[1] == '(') { + ++k; + } + + if(ch[1] == ')') { + --k; + } + } while(i < n && (ch[1] != ',' || k != 0)); + + // ڶ + if(i < n) { + SubString(hstr, str, 1, i - 1); + SubString(str, str, i + 1, n - i); + + // ֻһ + } else { + StrCopy(hstr, str); + ClearString(str); + } +} diff --git a/VisualC++/ExerciseBook/05.30.1/GList-HT.h b/VisualC++/ExerciseBook/05.30.1/GList-HT.h new file mode 100644 index 0000000..508b96f --- /dev/null +++ b/VisualC++/ExerciseBook/05.30.1/GList-HT.h @@ -0,0 +1,164 @@ +/*============================ + * ͷβ洢ʾ + * + * 㷨: 5.55.65.75.8 + =============================*/ + +#ifndef GLIST_HT_H +#define GLIST_HT_H + +#include +#include // ṩ mallocreallocfreeexit ԭ +#include "Status.h" //**01 **// +#include "SString.h" //**04 **// + +/* ԭԪ */ +typedef char AtomType; + +/* + * + * + * Atom-0ԭӽ + * List-1 + */ +typedef enum { Atom, List } ElemTag; + +/* ͷβ洢ʾͶ */ +typedef struct GLNode { + ElemTag tag; // ǣԭӽͱ + + // ԭӽͱϲ + union { + AtomType atom; // atomԭӽֵAtomTypeû + struct { + struct GLNode* hp; // ָͷ + struct GLNode* tp; // ָβ + } ptr; // ָ + } Node; +} GLNode; + +/* */ +typedef GLNode* GList; + +/* + * ͼλ + * + * HeadָԱͷ + * TailָԱβ + */ +typedef enum { Head, Tail } Mark; + + +/* + * ʼ + * + * ʼյĹΪ0Ϊ1 + * + *ע + * Ҫÿһȥſ + */ +Status InitGList(GList* L); + +/* + * 㷨5.7 + * + * + * + * ַSL + */ +Status CreateGList(GList* L, SString S); + +/* + * + * + * ͷŹռڴ档 + */ +Status DestroyGList(GList* L); + +/* + * 㷨5.6 + * + * + * + * ɹLƵõT + */ +Status CopyGList(GList* T, GList L); + +/* + * + * + * عijȡ + */ +int GListLength(GList L); + +/* + * 㷨5.5 + * + * + * + * ع + */ +int GListDepth(GList L); + +/* + * п + * + * жϹǷΪա + */ +Status GListEmpty(GList L); + +/* + * ͷ + */ +GList GetHead(GList L); + +/* + * β + */ +GList GetTail(GList L); + +/* + * + * + * ԪeΪLĵһԪء + */ +Status InsertFirst(GList* L, GList e); + +/* + * ɾ + * + * LĵһԪɾeء + */ +Status DeleteFirst(GList* L, GList* e); + +/* + * + * + * visitʹL + */ +void Traverse(GList L, void (Visit)(AtomType)); + +/* + * ͼλ + * + * L + */ +void PrintGraph(GList L); + +/* + * ͼλڲʵ֣markͼλǡ + */ +static void Print(GList L, Mark mark); + +/* + * 㷨5.8 + * + * ǿմstrָ֣hsubΪһ','֮ǰӴstrΪһ','֮Ӵ + * + *ע + * 1.ַstrȷ޿հ׷ţstrѾȥš + * 2.ɺstrҲᷢ仯 + */ +static void sever(SString hstr, SString str); + +#endif diff --git a/VisualC++/ExerciseBook/05.30.1/SString.c b/VisualC++/ExerciseBook/05.30.1/SString.c new file mode 100644 index 0000000..7a96fcf --- /dev/null +++ b/VisualC++/ExerciseBook/05.30.1/SString.c @@ -0,0 +1,195 @@ +/*============================= + * Ķ˳洢ʾ˳򴮣 + * + * 㷨: 4.14.24.34.5 + ==============================*/ + +#include "SString.h" //**04 **// + +/* + * ʼ + * + * һֵΪcharsĴT + * + *ע + * òСӼ + */ +Status StrAssign(SString T, const char* chars) { + int i, len; + + len = (int) strlen(chars); + + // chars + if(len > MAXSTRLEN) { + return ERROR; + } + + T[0] = len; + for(i = 1; i <= len; i++) { + T[i] = chars[i - 1]; + } + + return OK; +} + +/* + * + * + * Sա + */ +Status ClearString(SString S) { + // ֻҪΪ0Ϳ + S[0] = 0; + return OK; +} + +/* + * п + * + * жϴSǷЧݡ + * + * ֵ + * TRUE : SΪ + * FALSE: SΪ + */ +Status StrEmpty(SString S) { + return S[0] == 0 ? TRUE : FALSE; +} + +/* + * + * + * شSԪصĸ + * + *ע + * òСӼ + */ +int StrLength(SString S) { + return S[0]; +} + +/* + * 㷨4.3 + * + * Ӵ + * + * SubS[pos, pos+len-1] + * ֵָʾǷȡɹ + * + *ע + * òСӼ + */ +Status SubString(SString Sub, SString S, int pos, int len) { + int i; + + if(pos < 1 || pos > S[0] || len < 0 || pos + len - 1 > S[0]) { + return ERROR; + } + + // Ԫ + for(i = 1; i <= len; i++) { + Sub[i] = S[pos + i - 1]; + } + + // ȷ³ + Sub[0] = len; + + return OK; +} + +/* + * ɾ + * + * ɾS[pos, pos+len-1] + */ +Status StrDelete(SString S, int pos, int len) { + int i; + + if(pos < 1 || pos + len - 1 > S[0] || len < 0) { + return ERROR; + } + + // ɾijΪ0ǰ + if(len == 0) { + return OK; + } + + // ѺԪŲǰ棬ǵɾԪ + for(i = pos + len; i <= S[0]; i++) { + S[i - len] = S[i]; + } + + // ȼ + S[0] -= len; + + return OK; +} + +/* + * Ƚ + * + * ȽϴSʹTرȽϽ + * + *ע + * òСӼ + */ +int StrCompare(SString S, SString T) { + int i = 1; + + while(i <= S[0] && i <= T[0]) { + // ַͬʱȽС + if(S[i] != T[i]) { + return S[i] - T[i]; + } + + i++; + } + + return S[0] - T[0]; +} + +/* + * + * + * SƵT + */ +Status StrCopy(SString T, SString S) { + int i; + + // ͬϢһ + for(i = 0; i <= S[0]; i++) { + T[i] = S[i]; + } + + return OK; +} + +/* + * ַSеĿհףɴӡַո + * + *ע + * úڱġ + */ +Status ClearBlank(SString S) { + int i, j; + + // ǿմ + if(S[0] == 0) { + return ERROR; + } + + for(i = 1, j = 0; i <= S[0]; i++) { + // հףԹ + if(S[i] == ' ' || !isprint(S[i])) { + continue; + } + + j++; + + S[j] = S[i]; + } + + S[0] = j; + + return OK; +} diff --git a/VisualC++/ExerciseBook/05.30.1/SString.h b/VisualC++/ExerciseBook/05.30.1/SString.h new file mode 100644 index 0000000..0632f18 --- /dev/null +++ b/VisualC++/ExerciseBook/05.30.1/SString.h @@ -0,0 +1,117 @@ +/*============================= + * Ķ˳洢ʾ˳򴮣 + * + * 㷨: 4.14.24.34.5 + ==============================*/ + +#ifndef SSTRING_H +#define SSTRING_H + +#include +#include // ṩ strlen ԭ +#include // ṩ isprint ԭ +#include "Status.h" //**01 **// + +/* 궨 */ +#define MAXSTRLEN 255 // ˳򴮵󴮳 + +/* + * ˳洢Ͷ + * + * עЧԪشSString1ŵԪʼ洢 + * SString0ŵԪ洢䳤 + */ +typedef unsigned char SString[MAXSTRLEN + 1]; // 0ŵԪŴij + + +/* + * ʾ + * + * ѭ̲ĵдϰߣposָʾַλ()1ʼ + */ + + +/* + * ʼ + * + * һֵΪcharsĴT + * + *ע + * òСӼ + */ +Status StrAssign(SString T, const char* chars); + +/* + * + * + * Sա + */ +Status ClearString(SString S); + +/* + * п + * + * жϴSǷЧݡ + * + * ֵ + * TRUE : SΪ + * FALSE: SΪ + */ +Status StrEmpty(SString S); + +/* + * + * + * شSԪصĸ + * + *ע + * òСӼ + */ +int StrLength(SString S); + +/* + * 㷨4.3 + * + * Ӵ + * + * SubS[pos, pos+len-1] + * ֵָʾǷȡɹ + * + *ע + * òСӼ + */ +Status SubString(SString Sub, SString S, int pos, int len); + +/* + * ɾ + * + * ɾS[pos, pos+len-1] + */ +Status StrDelete(SString S, int pos, int len); + +/* + * Ƚ + * + * ȽϴSʹTرȽϽ + * + *ע + * òСӼ + */ +int StrCompare(SString S, SString T); + +/* + * + * + * SƵT + */ +Status StrCopy(SString T, SString S); + +/* + * ַSеĿհףɴӡַո + * + *ע + * úڱġ + */ +Status ClearBlank(SString S); + +#endif diff --git a/VisualC++/ExerciseBook/05.30.2/05.30.2.c b/VisualC++/ExerciseBook/05.30.2/05.30.2.c new file mode 100644 index 0000000..929561f --- /dev/null +++ b/VisualC++/ExerciseBook/05.30.2/05.30.2.c @@ -0,0 +1,42 @@ +#include +#include "SString.h" //**04 **// +#include "GList-E.h" //**05 ͹**// + +// ȣչ洢ʾ +int Algo_5_30_2(GList L); + + +int main(int argc, char* argv[]) { + GList L; + char* s = "((),(e),(a,(b,c,d)))"; + SString S; + + printf(" L ...\n"); + StrAssign(S, s); + CreateGList(&L, S); + printf("L = "); + PrintGraph(L); + + printf("Ϊ %d\n", Algo_5_30_2(L)); + + return 0; +} + + +// ȣչ洢ʾ +int Algo_5_30_2(GList L) { + int m, n; + + if(L==NULL) { + return 1; // ձΪ1 + } + + if(L->tag == Atom) { + return 0; // ԭΪ0 + } + + m = Algo_5_30_2(L->Node.hp) + 1; + n = Algo_5_30_2(L->tp); + + return m > n ? m : n; +} diff --git a/VisualC++/ExerciseBook/05.30.2/05.30.2.vcxproj b/VisualC++/ExerciseBook/05.30.2/05.30.2.vcxproj new file mode 100644 index 0000000..ddf9756 --- /dev/null +++ b/VisualC++/ExerciseBook/05.30.2/05.30.2.vcxproj @@ -0,0 +1,78 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {986E6EF4-6118-4504-9667-3B86BC71D7CC} + My05302 + + + + Application + true + MultiByte + + + Application + false + true + MultiByte + + + + + + + + + + + + + $(SolutionDir)\..\Status;$(IncludePath) + + + + Level3 + Disabled + + + true + $(SolutionDir)\..\Status\Status.lib;%(AdditionalDependencies) + Console + + + + + Level3 + MaxSpeed + true + true + + + true + true + true + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/05.30.2/05.30.2.vcxproj.filters b/VisualC++/ExerciseBook/05.30.2/05.30.2.vcxproj.filters new file mode 100644 index 0000000..494d692 --- /dev/null +++ b/VisualC++/ExerciseBook/05.30.2/05.30.2.vcxproj.filters @@ -0,0 +1,36 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + 源文件 + + + 源文件 + + + 源文件 + + + + + 头文件 + + + 头文件 + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/05.30.2/05.30.2.vcxproj.user b/VisualC++/ExerciseBook/05.30.2/05.30.2.vcxproj.user new file mode 100644 index 0000000..ace9a86 --- /dev/null +++ b/VisualC++/ExerciseBook/05.30.2/05.30.2.vcxproj.user @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/05.30.2/GList-E.c b/VisualC++/ExerciseBook/05.30.2/GList-E.c new file mode 100644 index 0000000..3fc0ad9 --- /dev/null +++ b/VisualC++/ExerciseBook/05.30.2/GList-E.c @@ -0,0 +1,449 @@ +/*=========================== + * չ洢ʾ + ============================*/ + +#include "GList-E.h" //**05 ͹**// + +/* + * ʼ + * + * ʼյĹΪ0Ϊ1 + * + *ע + * Ҫÿһſ + */ +Status InitGList(GList* L) { + if(L == NULL) { + return ERROR; + } + + *L = (GList) malloc(sizeof(GLNode)); + if(!*L) { + exit(OVERFLOW); + } + + (*L)->tag = List; + (*L)->Node.hp = NULL; + (*L)->tp = NULL; + + return OK; +} + +/* + * + * + * ַSL + */ +Status CreateGList(GList* L, SString S) { + SString emp, hsub, sub, tmp; + + if(L == NULL) { + return ERROR; + } + + // ַSеĿհףɴӡַո + ClearBlank(S); + + if(StrEmpty(S)) { + return ERROR; + } + + // Ϊ˲ƻS + StrCopy(sub, S); + + /* + * ִеʱ + * ٴִеʱѾȥ + */ + sever(hsub, sub); + + *L = (GList) malloc(sizeof(GLNode)); + if(*L == NULL) { + exit(OVERFLOW); + } + + StrAssign(emp, "()"); + + if(!StrCompare(hsub, emp)) { + (*L)->tag = List; + (*L)->Node.hp = NULL; + } else { + if(StrLength(hsub) == 1) { + (*L)->tag = Atom; + (*L)->Node.atom = hsub[1]; + } else { + (*L)->tag = List; + + SubString(tmp, hsub, 2, StrLength(hsub) - 2); + + CreateGList(&((*L)->Node.hp), tmp); + } + } + + // ڶβ˳ݹ + if(StrEmpty(sub)) { + (*L)->tp = NULL; + } else { + // ݹβ + CreateGList(&((*L)->tp), sub); + } + + return OK; +} + +/* + * + * + * ͷŹռڴ档 + */ +Status DestroyGList(GList* L) { + GList head, tail; + + if(L == NULL || *L == NULL) { + return ERROR; + } + + // ӱ + if((*L)->tag == List) { + head = (*L)->Node.hp; // ͷ + tail = (*L)->tp; // β + + free(*L); + *L = NULL; + + // ݹ鴦ͷ + if(head != NULL) { + DestroyGList(&head); + } + + // ݹ鴦β + if(tail != NULL) { + DestroyGList(&tail); + } + + // ԭӽ + } else { + tail = (*L)->tp; // β + + free(*L); + *L = NULL; + + if(tail != NULL) { + DestroyGList(&tail); + } + } + + return OK; +} + +/* + * + * + * ɹLƵõT + */ +Status CopyGList(GList* T, GList L) { + + if(L == NULL) { + return ERROR; + } + + *T = (GList) malloc(sizeof(GLNode)); + if(*T == NULL) { + exit(OVERFLOW); + } + + // ԭ + if(L->tag == Atom) { + (*T)->tag = Atom; + (*T)->Node.atom = L->Node.atom; + + // ӱ + } else { + (*T)->tag = List; + + // Ʊͷ + if(L->Node.hp != NULL) { + CopyGList(&((*T)->Node.hp), L->Node.hp); + } else { + (*T)->Node.hp = NULL; + } + } + + // Ʊβ + if(L->tp != NULL) { + CopyGList(&((*T)->tp), L->tp); + } else { + (*T)->tp = NULL; + } + + return OK; +} + +/* + * + * + * عijȡ + */ +int GListLength(GList L) { + int count = 0; + GList p; + + // + if(L == NULL) { + return -1; + } + + p = L->Node.hp; + + while(p != NULL) { + ++count; + p = p->tp; + } + + return count; +} + +/* + * + * + * ع + */ +int GListDepth(GList L) { + int max, deep; + GList p; + + max = 0; + + // + if(L == NULL) { + return -1; + } + + // ձΪ1 + if(L->tag == List && !L->Node.hp) { + return 1; + } + + // ԭΪ0 + if(L->tag == Atom) { + return 0; + } + + // ݹӱ + for(p = L->Node.hp; p != NULL; p = p->tp) { + // pΪͷָӱ + deep = GListDepth(p); + if(deep > max) { + max = deep; + } + } + + return max + 1; +} + +/* + * п + * + * жϹǷΪա + */ +Status GListEmpty(GList L) { + // + if(L == NULL) { + return ERROR; + } + + if(L->tag == List && L->Node.hp == NULL && L->tp == NULL) { + return TRUE; + } else { + return ERROR; + } +} + +/* + * ͷ + */ +GList GetHead(GList L) { + GList p, q; + + // ڻΪձ޷ȡͷ + if(L == NULL || L->Node.hp == NULL) { + return NULL; + } + + q = L->Node.hp->tp; // ʱLıβϢ + L->Node.hp->tp = NULL; // ȥLıβ + + CopyGList(&p, L->Node.hp); // ƱͷϢαβ + + L->Node.hp->tp = q; // ָLıβϢ + + return p; +} + +/* + * β + */ +GList GetTail(GList L) { + GList p, q; + + // ڻΪձ޷ȡβ + if(L == NULL || L->Node.hp == NULL) { + return NULL; + } + + q = L->Node.hp; // ʱLıͷϢ + L->Node.hp = q->tp; // ժLıͷ + + CopyGList(&p, L); // ƱβϢαͷ + + q->tp = L->Node.hp; // ָLıͷϢ + L->Node.hp = q; + + return p; +} + +/* + * + * + * ԪeΪLĵһԪء + */ +Status InsertFirst(GList* L, GList e) { + + // + if(L == NULL || *L == NULL) { + return ERROR; + } + + if(e == NULL) { + return ERROR; + } + + e->tp = (*L)->Node.hp; + (*L)->Node.hp = e; + + return OK; +} + +/* + * ɾ + * + * LĵһԪɾeء + */ +Status DeleteFirst(GList* L, GList* e) { + GList p; + + // ڻΪձ޷ɾͷ + if(*L == NULL || (*L)->Node.hp == NULL) { + return ERROR; + } + + p = (*L)->Node.hp; + (*L)->Node.hp = p->tp; + p->tp = NULL; + + *e = p; + + return OK; +} + +/* + * + * + * visitʹL + */ +void Traverse(GList L, void(Visit)(AtomType)) { + if(L == NULL) { + return; + } + + if(L->tag == List) { + Traverse(L->Node.hp, Visit); + } else { + Visit(L->Node.atom); + } + + Traverse(L->tp, Visit); +} + +/* + * ͼλ + * + * L + */ +void PrintGraph(GList L) { + Print(L); + printf("\n"); +} + +/* + * ͼλڲʵ֡ + */ +static void Print(GList L) { + if(L == NULL) { + return; + } + + // + if(L->tag == List) { + printf("("); + + if(L->Node.hp) { + Print(L->Node.hp); + } + + if(L->tp) { + printf("),"); + Print(L->tp); + } else { + printf(")"); + } + + // ԭӽ + } else { + printf("%c", L->Node.atom); + if(L->tp) { + printf(","); + Print(L->tp); + } + } +} + +/* + * ǿմstrָ֣hsubΪһ','֮ǰӴstrΪһ','֮Ӵ + * + *ע + * 1.ַstrȷ޿հ׷ţ + * strſȥҲδȥ + * 2.ɺstrҲᷢ仯 + */ +static void sever(SString hstr, SString str) { + int i, k, n; + SString ch; + + n = StrLength(str); + + i = 0; // ַʱα + k = 0; // δ + + do { + ++i; + + // ȡstrһַ + SubString(ch, str, i, 1); + + if(ch[1] == '(') { + ++k; + } + if(ch[1] == ')') { + --k; + } + } while(i < n && (ch[1] != ',' || k != 0)); + + if(i < n) { + SubString(hstr, str, 1, i - 1); + SubString(str, str, i + 1, n - i); + } else { + StrCopy(hstr, str); + ClearString(str); + } +} diff --git a/VisualC++/ExerciseBook/05.30.2/GList-E.h b/VisualC++/ExerciseBook/05.30.2/GList-E.h new file mode 100644 index 0000000..fa9af82 --- /dev/null +++ b/VisualC++/ExerciseBook/05.30.2/GList-E.h @@ -0,0 +1,146 @@ +/*=========================== + * չ洢ʾ + ============================*/ + +#ifndef GLIST_E_H +#define GLIST_E_H + +#include +#include // ṩ mallocreallocfreeexit ԭ +#include "Status.h" //**01 **// +#include "SString.h" //**04 **// + +/* ԭԪ */ +typedef char AtomType; //ԭ + +/* + * + * + * Atom-0ԭӽ + * List-1 + */ +typedef enum { Atom, List } ElemTag; + +/* չ洢ʾͶ */ +typedef struct GLNode { + ElemTag tag; // ǣԭӽͱ + + // ԭӽͱϲ + union + { + AtomType atom; // atomԭӽֵAtomTypeû + struct GLNode* hp; // ָͷ + } Node; + struct GLNode* tp; // ָβ +} GLNode; + +/* */ +typedef GLNode* GList; + + +/* + * ʼ + * + * ʼյĹΪ0Ϊ1 + * + *ע + * Ҫÿһſ + */ +Status InitGList(GList* L); + +/* + * + * + * ַSL + */ +Status CreateGList(GList* L, SString S); + +/* + * + * + * ͷŹռڴ档 + */ +Status DestroyGList(GList* L); + +/* + * + * + * ɹLƵõT + */ +Status CopyGList(GList* T, GList L); + +/* + * + * + * عijȡ + */ +int GListLength(GList L); + +/* + * + * + * ع + */ +int GListDepth(GList L); + +/* + * п + * + * жϹǷΪա + */ +Status GListEmpty(GList L); + +/* + * ͷ + */ +GList GetHead(GList L); + +/* + * β + */ +GList GetTail(GList L); + +/* + * + * + * ԪeΪLĵһԪء + */ +Status InsertFirst(GList* L, GList e); + +/* + * ɾ + * + * LĵһԪɾeء + */ +Status DeleteFirst(GList* L, GList* e); + +/* + * + * + * visitʹL + */ +void Traverse(GList L, void(Visit)(AtomType)); + +/* + * ͼλ + * + * L + */ +void PrintGraph(GList L); + +/* + * ͼλڲʵ֡ + */ +static void Print(GList L); + +/* + * ǿմstrָ֣hsubΪһ','֮ǰӴstrΪһ','֮Ӵ + * + *ע + * 1.ַstrȷ޿հ׷ţ + * strſȥҲδȥ + * 2.ɺstrҲᷢ仯 + */ +static void sever(SString hstr, SString str); + +#endif diff --git a/VisualC++/ExerciseBook/05.30.2/SString.c b/VisualC++/ExerciseBook/05.30.2/SString.c new file mode 100644 index 0000000..7a96fcf --- /dev/null +++ b/VisualC++/ExerciseBook/05.30.2/SString.c @@ -0,0 +1,195 @@ +/*============================= + * Ķ˳洢ʾ˳򴮣 + * + * 㷨: 4.14.24.34.5 + ==============================*/ + +#include "SString.h" //**04 **// + +/* + * ʼ + * + * һֵΪcharsĴT + * + *ע + * òСӼ + */ +Status StrAssign(SString T, const char* chars) { + int i, len; + + len = (int) strlen(chars); + + // chars + if(len > MAXSTRLEN) { + return ERROR; + } + + T[0] = len; + for(i = 1; i <= len; i++) { + T[i] = chars[i - 1]; + } + + return OK; +} + +/* + * + * + * Sա + */ +Status ClearString(SString S) { + // ֻҪΪ0Ϳ + S[0] = 0; + return OK; +} + +/* + * п + * + * жϴSǷЧݡ + * + * ֵ + * TRUE : SΪ + * FALSE: SΪ + */ +Status StrEmpty(SString S) { + return S[0] == 0 ? TRUE : FALSE; +} + +/* + * + * + * شSԪصĸ + * + *ע + * òСӼ + */ +int StrLength(SString S) { + return S[0]; +} + +/* + * 㷨4.3 + * + * Ӵ + * + * SubS[pos, pos+len-1] + * ֵָʾǷȡɹ + * + *ע + * òСӼ + */ +Status SubString(SString Sub, SString S, int pos, int len) { + int i; + + if(pos < 1 || pos > S[0] || len < 0 || pos + len - 1 > S[0]) { + return ERROR; + } + + // Ԫ + for(i = 1; i <= len; i++) { + Sub[i] = S[pos + i - 1]; + } + + // ȷ³ + Sub[0] = len; + + return OK; +} + +/* + * ɾ + * + * ɾS[pos, pos+len-1] + */ +Status StrDelete(SString S, int pos, int len) { + int i; + + if(pos < 1 || pos + len - 1 > S[0] || len < 0) { + return ERROR; + } + + // ɾijΪ0ǰ + if(len == 0) { + return OK; + } + + // ѺԪŲǰ棬ǵɾԪ + for(i = pos + len; i <= S[0]; i++) { + S[i - len] = S[i]; + } + + // ȼ + S[0] -= len; + + return OK; +} + +/* + * Ƚ + * + * ȽϴSʹTرȽϽ + * + *ע + * òСӼ + */ +int StrCompare(SString S, SString T) { + int i = 1; + + while(i <= S[0] && i <= T[0]) { + // ַͬʱȽС + if(S[i] != T[i]) { + return S[i] - T[i]; + } + + i++; + } + + return S[0] - T[0]; +} + +/* + * + * + * SƵT + */ +Status StrCopy(SString T, SString S) { + int i; + + // ͬϢһ + for(i = 0; i <= S[0]; i++) { + T[i] = S[i]; + } + + return OK; +} + +/* + * ַSеĿհףɴӡַո + * + *ע + * úڱġ + */ +Status ClearBlank(SString S) { + int i, j; + + // ǿմ + if(S[0] == 0) { + return ERROR; + } + + for(i = 1, j = 0; i <= S[0]; i++) { + // հףԹ + if(S[i] == ' ' || !isprint(S[i])) { + continue; + } + + j++; + + S[j] = S[i]; + } + + S[0] = j; + + return OK; +} diff --git a/VisualC++/ExerciseBook/05.30.2/SString.h b/VisualC++/ExerciseBook/05.30.2/SString.h new file mode 100644 index 0000000..0632f18 --- /dev/null +++ b/VisualC++/ExerciseBook/05.30.2/SString.h @@ -0,0 +1,117 @@ +/*============================= + * Ķ˳洢ʾ˳򴮣 + * + * 㷨: 4.14.24.34.5 + ==============================*/ + +#ifndef SSTRING_H +#define SSTRING_H + +#include +#include // ṩ strlen ԭ +#include // ṩ isprint ԭ +#include "Status.h" //**01 **// + +/* 궨 */ +#define MAXSTRLEN 255 // ˳򴮵󴮳 + +/* + * ˳洢Ͷ + * + * עЧԪشSString1ŵԪʼ洢 + * SString0ŵԪ洢䳤 + */ +typedef unsigned char SString[MAXSTRLEN + 1]; // 0ŵԪŴij + + +/* + * ʾ + * + * ѭ̲ĵдϰߣposָʾַλ()1ʼ + */ + + +/* + * ʼ + * + * һֵΪcharsĴT + * + *ע + * òСӼ + */ +Status StrAssign(SString T, const char* chars); + +/* + * + * + * Sա + */ +Status ClearString(SString S); + +/* + * п + * + * жϴSǷЧݡ + * + * ֵ + * TRUE : SΪ + * FALSE: SΪ + */ +Status StrEmpty(SString S); + +/* + * + * + * شSԪصĸ + * + *ע + * òСӼ + */ +int StrLength(SString S); + +/* + * 㷨4.3 + * + * Ӵ + * + * SubS[pos, pos+len-1] + * ֵָʾǷȡɹ + * + *ע + * òСӼ + */ +Status SubString(SString Sub, SString S, int pos, int len); + +/* + * ɾ + * + * ɾS[pos, pos+len-1] + */ +Status StrDelete(SString S, int pos, int len); + +/* + * Ƚ + * + * ȽϴSʹTرȽϽ + * + *ע + * òСӼ + */ +int StrCompare(SString S, SString T); + +/* + * + * + * SƵT + */ +Status StrCopy(SString T, SString S); + +/* + * ַSеĿհףɴӡַո + * + *ע + * úڱġ + */ +Status ClearBlank(SString S); + +#endif diff --git a/VisualC++/ExerciseBook/05.31/05.31.c b/VisualC++/ExerciseBook/05.31/05.31.c new file mode 100644 index 0000000..da70a36 --- /dev/null +++ b/VisualC++/ExerciseBook/05.31/05.31.c @@ -0,0 +1,43 @@ +#include +#include "Status.h" //**01 **// +#include "SString.h" //**04 **// +#include "GList-E.h" //**05 ͹**// + +/* + * ƣչ洢ʾ + * + *ע + * úGList-Eļж + */ +Status Algo_5_31(GList* T, GList L); + + +int main(int argc, char* argv[]) { + GList L, T; + char* s = "((),(e),(a,(b,c,d)))"; + SString S; + + printf(" L ...\n"); + StrAssign(S, s); + CreateGList(&L, S); + printf("L = "); + PrintGraph(L); + + printf("ƹ L T...\n"); + Algo_5_31(&T, L); + printf("T = "); + PrintGraph(T); + + return 0; +} + + +/* + * ƣչ洢ʾ + * + *ע + * úGList-Eļж + */ +Status Algo_5_31(GList* T, GList L) { + return CopyGList(T, L); +} diff --git a/VisualC++/ExerciseBook/05.31/05.31.vcxproj b/VisualC++/ExerciseBook/05.31/05.31.vcxproj new file mode 100644 index 0000000..47fd141 --- /dev/null +++ b/VisualC++/ExerciseBook/05.31/05.31.vcxproj @@ -0,0 +1,78 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {F63981E9-26D4-4EF9-82F5-1482260619CF} + My0531 + + + + Application + true + MultiByte + + + Application + false + true + MultiByte + + + + + + + + + + + + + $(SolutionDir)\..\Status;$(IncludePath) + + + + Level3 + Disabled + + + true + $(SolutionDir)\..\Status\Status.lib;%(AdditionalDependencies) + Console + + + + + Level3 + MaxSpeed + true + true + + + true + true + true + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/05.31/05.31.vcxproj.filters b/VisualC++/ExerciseBook/05.31/05.31.vcxproj.filters new file mode 100644 index 0000000..3b28619 --- /dev/null +++ b/VisualC++/ExerciseBook/05.31/05.31.vcxproj.filters @@ -0,0 +1,36 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + 源文件 + + + 源文件 + + + 源文件 + + + + + 头文件 + + + 头文件 + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/05.31/05.31.vcxproj.user b/VisualC++/ExerciseBook/05.31/05.31.vcxproj.user new file mode 100644 index 0000000..ace9a86 --- /dev/null +++ b/VisualC++/ExerciseBook/05.31/05.31.vcxproj.user @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/05.31/GList-E.c b/VisualC++/ExerciseBook/05.31/GList-E.c new file mode 100644 index 0000000..3fc0ad9 --- /dev/null +++ b/VisualC++/ExerciseBook/05.31/GList-E.c @@ -0,0 +1,449 @@ +/*=========================== + * չ洢ʾ + ============================*/ + +#include "GList-E.h" //**05 ͹**// + +/* + * ʼ + * + * ʼյĹΪ0Ϊ1 + * + *ע + * Ҫÿһſ + */ +Status InitGList(GList* L) { + if(L == NULL) { + return ERROR; + } + + *L = (GList) malloc(sizeof(GLNode)); + if(!*L) { + exit(OVERFLOW); + } + + (*L)->tag = List; + (*L)->Node.hp = NULL; + (*L)->tp = NULL; + + return OK; +} + +/* + * + * + * ַSL + */ +Status CreateGList(GList* L, SString S) { + SString emp, hsub, sub, tmp; + + if(L == NULL) { + return ERROR; + } + + // ַSеĿհףɴӡַո + ClearBlank(S); + + if(StrEmpty(S)) { + return ERROR; + } + + // Ϊ˲ƻS + StrCopy(sub, S); + + /* + * ִеʱ + * ٴִеʱѾȥ + */ + sever(hsub, sub); + + *L = (GList) malloc(sizeof(GLNode)); + if(*L == NULL) { + exit(OVERFLOW); + } + + StrAssign(emp, "()"); + + if(!StrCompare(hsub, emp)) { + (*L)->tag = List; + (*L)->Node.hp = NULL; + } else { + if(StrLength(hsub) == 1) { + (*L)->tag = Atom; + (*L)->Node.atom = hsub[1]; + } else { + (*L)->tag = List; + + SubString(tmp, hsub, 2, StrLength(hsub) - 2); + + CreateGList(&((*L)->Node.hp), tmp); + } + } + + // ڶβ˳ݹ + if(StrEmpty(sub)) { + (*L)->tp = NULL; + } else { + // ݹβ + CreateGList(&((*L)->tp), sub); + } + + return OK; +} + +/* + * + * + * ͷŹռڴ档 + */ +Status DestroyGList(GList* L) { + GList head, tail; + + if(L == NULL || *L == NULL) { + return ERROR; + } + + // ӱ + if((*L)->tag == List) { + head = (*L)->Node.hp; // ͷ + tail = (*L)->tp; // β + + free(*L); + *L = NULL; + + // ݹ鴦ͷ + if(head != NULL) { + DestroyGList(&head); + } + + // ݹ鴦β + if(tail != NULL) { + DestroyGList(&tail); + } + + // ԭӽ + } else { + tail = (*L)->tp; // β + + free(*L); + *L = NULL; + + if(tail != NULL) { + DestroyGList(&tail); + } + } + + return OK; +} + +/* + * + * + * ɹLƵõT + */ +Status CopyGList(GList* T, GList L) { + + if(L == NULL) { + return ERROR; + } + + *T = (GList) malloc(sizeof(GLNode)); + if(*T == NULL) { + exit(OVERFLOW); + } + + // ԭ + if(L->tag == Atom) { + (*T)->tag = Atom; + (*T)->Node.atom = L->Node.atom; + + // ӱ + } else { + (*T)->tag = List; + + // Ʊͷ + if(L->Node.hp != NULL) { + CopyGList(&((*T)->Node.hp), L->Node.hp); + } else { + (*T)->Node.hp = NULL; + } + } + + // Ʊβ + if(L->tp != NULL) { + CopyGList(&((*T)->tp), L->tp); + } else { + (*T)->tp = NULL; + } + + return OK; +} + +/* + * + * + * عijȡ + */ +int GListLength(GList L) { + int count = 0; + GList p; + + // + if(L == NULL) { + return -1; + } + + p = L->Node.hp; + + while(p != NULL) { + ++count; + p = p->tp; + } + + return count; +} + +/* + * + * + * ع + */ +int GListDepth(GList L) { + int max, deep; + GList p; + + max = 0; + + // + if(L == NULL) { + return -1; + } + + // ձΪ1 + if(L->tag == List && !L->Node.hp) { + return 1; + } + + // ԭΪ0 + if(L->tag == Atom) { + return 0; + } + + // ݹӱ + for(p = L->Node.hp; p != NULL; p = p->tp) { + // pΪͷָӱ + deep = GListDepth(p); + if(deep > max) { + max = deep; + } + } + + return max + 1; +} + +/* + * п + * + * жϹǷΪա + */ +Status GListEmpty(GList L) { + // + if(L == NULL) { + return ERROR; + } + + if(L->tag == List && L->Node.hp == NULL && L->tp == NULL) { + return TRUE; + } else { + return ERROR; + } +} + +/* + * ͷ + */ +GList GetHead(GList L) { + GList p, q; + + // ڻΪձ޷ȡͷ + if(L == NULL || L->Node.hp == NULL) { + return NULL; + } + + q = L->Node.hp->tp; // ʱLıβϢ + L->Node.hp->tp = NULL; // ȥLıβ + + CopyGList(&p, L->Node.hp); // ƱͷϢαβ + + L->Node.hp->tp = q; // ָLıβϢ + + return p; +} + +/* + * β + */ +GList GetTail(GList L) { + GList p, q; + + // ڻΪձ޷ȡβ + if(L == NULL || L->Node.hp == NULL) { + return NULL; + } + + q = L->Node.hp; // ʱLıͷϢ + L->Node.hp = q->tp; // ժLıͷ + + CopyGList(&p, L); // ƱβϢαͷ + + q->tp = L->Node.hp; // ָLıͷϢ + L->Node.hp = q; + + return p; +} + +/* + * + * + * ԪeΪLĵһԪء + */ +Status InsertFirst(GList* L, GList e) { + + // + if(L == NULL || *L == NULL) { + return ERROR; + } + + if(e == NULL) { + return ERROR; + } + + e->tp = (*L)->Node.hp; + (*L)->Node.hp = e; + + return OK; +} + +/* + * ɾ + * + * LĵһԪɾeء + */ +Status DeleteFirst(GList* L, GList* e) { + GList p; + + // ڻΪձ޷ɾͷ + if(*L == NULL || (*L)->Node.hp == NULL) { + return ERROR; + } + + p = (*L)->Node.hp; + (*L)->Node.hp = p->tp; + p->tp = NULL; + + *e = p; + + return OK; +} + +/* + * + * + * visitʹL + */ +void Traverse(GList L, void(Visit)(AtomType)) { + if(L == NULL) { + return; + } + + if(L->tag == List) { + Traverse(L->Node.hp, Visit); + } else { + Visit(L->Node.atom); + } + + Traverse(L->tp, Visit); +} + +/* + * ͼλ + * + * L + */ +void PrintGraph(GList L) { + Print(L); + printf("\n"); +} + +/* + * ͼλڲʵ֡ + */ +static void Print(GList L) { + if(L == NULL) { + return; + } + + // + if(L->tag == List) { + printf("("); + + if(L->Node.hp) { + Print(L->Node.hp); + } + + if(L->tp) { + printf("),"); + Print(L->tp); + } else { + printf(")"); + } + + // ԭӽ + } else { + printf("%c", L->Node.atom); + if(L->tp) { + printf(","); + Print(L->tp); + } + } +} + +/* + * ǿմstrָ֣hsubΪһ','֮ǰӴstrΪһ','֮Ӵ + * + *ע + * 1.ַstrȷ޿հ׷ţ + * strſȥҲδȥ + * 2.ɺstrҲᷢ仯 + */ +static void sever(SString hstr, SString str) { + int i, k, n; + SString ch; + + n = StrLength(str); + + i = 0; // ַʱα + k = 0; // δ + + do { + ++i; + + // ȡstrһַ + SubString(ch, str, i, 1); + + if(ch[1] == '(') { + ++k; + } + if(ch[1] == ')') { + --k; + } + } while(i < n && (ch[1] != ',' || k != 0)); + + if(i < n) { + SubString(hstr, str, 1, i - 1); + SubString(str, str, i + 1, n - i); + } else { + StrCopy(hstr, str); + ClearString(str); + } +} diff --git a/VisualC++/ExerciseBook/05.31/GList-E.h b/VisualC++/ExerciseBook/05.31/GList-E.h new file mode 100644 index 0000000..fa9af82 --- /dev/null +++ b/VisualC++/ExerciseBook/05.31/GList-E.h @@ -0,0 +1,146 @@ +/*=========================== + * չ洢ʾ + ============================*/ + +#ifndef GLIST_E_H +#define GLIST_E_H + +#include +#include // ṩ mallocreallocfreeexit ԭ +#include "Status.h" //**01 **// +#include "SString.h" //**04 **// + +/* ԭԪ */ +typedef char AtomType; //ԭ + +/* + * + * + * Atom-0ԭӽ + * List-1 + */ +typedef enum { Atom, List } ElemTag; + +/* չ洢ʾͶ */ +typedef struct GLNode { + ElemTag tag; // ǣԭӽͱ + + // ԭӽͱϲ + union + { + AtomType atom; // atomԭӽֵAtomTypeû + struct GLNode* hp; // ָͷ + } Node; + struct GLNode* tp; // ָβ +} GLNode; + +/* */ +typedef GLNode* GList; + + +/* + * ʼ + * + * ʼյĹΪ0Ϊ1 + * + *ע + * Ҫÿһſ + */ +Status InitGList(GList* L); + +/* + * + * + * ַSL + */ +Status CreateGList(GList* L, SString S); + +/* + * + * + * ͷŹռڴ档 + */ +Status DestroyGList(GList* L); + +/* + * + * + * ɹLƵõT + */ +Status CopyGList(GList* T, GList L); + +/* + * + * + * عijȡ + */ +int GListLength(GList L); + +/* + * + * + * ع + */ +int GListDepth(GList L); + +/* + * п + * + * жϹǷΪա + */ +Status GListEmpty(GList L); + +/* + * ͷ + */ +GList GetHead(GList L); + +/* + * β + */ +GList GetTail(GList L); + +/* + * + * + * ԪeΪLĵһԪء + */ +Status InsertFirst(GList* L, GList e); + +/* + * ɾ + * + * LĵһԪɾeء + */ +Status DeleteFirst(GList* L, GList* e); + +/* + * + * + * visitʹL + */ +void Traverse(GList L, void(Visit)(AtomType)); + +/* + * ͼλ + * + * L + */ +void PrintGraph(GList L); + +/* + * ͼλڲʵ֡ + */ +static void Print(GList L); + +/* + * ǿմstrָ֣hsubΪһ','֮ǰӴstrΪһ','֮Ӵ + * + *ע + * 1.ַstrȷ޿հ׷ţ + * strſȥҲδȥ + * 2.ɺstrҲᷢ仯 + */ +static void sever(SString hstr, SString str); + +#endif diff --git a/VisualC++/ExerciseBook/05.31/SString.c b/VisualC++/ExerciseBook/05.31/SString.c new file mode 100644 index 0000000..7a96fcf --- /dev/null +++ b/VisualC++/ExerciseBook/05.31/SString.c @@ -0,0 +1,195 @@ +/*============================= + * Ķ˳洢ʾ˳򴮣 + * + * 㷨: 4.14.24.34.5 + ==============================*/ + +#include "SString.h" //**04 **// + +/* + * ʼ + * + * һֵΪcharsĴT + * + *ע + * òСӼ + */ +Status StrAssign(SString T, const char* chars) { + int i, len; + + len = (int) strlen(chars); + + // chars + if(len > MAXSTRLEN) { + return ERROR; + } + + T[0] = len; + for(i = 1; i <= len; i++) { + T[i] = chars[i - 1]; + } + + return OK; +} + +/* + * + * + * Sա + */ +Status ClearString(SString S) { + // ֻҪΪ0Ϳ + S[0] = 0; + return OK; +} + +/* + * п + * + * жϴSǷЧݡ + * + * ֵ + * TRUE : SΪ + * FALSE: SΪ + */ +Status StrEmpty(SString S) { + return S[0] == 0 ? TRUE : FALSE; +} + +/* + * + * + * شSԪصĸ + * + *ע + * òСӼ + */ +int StrLength(SString S) { + return S[0]; +} + +/* + * 㷨4.3 + * + * Ӵ + * + * SubS[pos, pos+len-1] + * ֵָʾǷȡɹ + * + *ע + * òСӼ + */ +Status SubString(SString Sub, SString S, int pos, int len) { + int i; + + if(pos < 1 || pos > S[0] || len < 0 || pos + len - 1 > S[0]) { + return ERROR; + } + + // Ԫ + for(i = 1; i <= len; i++) { + Sub[i] = S[pos + i - 1]; + } + + // ȷ³ + Sub[0] = len; + + return OK; +} + +/* + * ɾ + * + * ɾS[pos, pos+len-1] + */ +Status StrDelete(SString S, int pos, int len) { + int i; + + if(pos < 1 || pos + len - 1 > S[0] || len < 0) { + return ERROR; + } + + // ɾijΪ0ǰ + if(len == 0) { + return OK; + } + + // ѺԪŲǰ棬ǵɾԪ + for(i = pos + len; i <= S[0]; i++) { + S[i - len] = S[i]; + } + + // ȼ + S[0] -= len; + + return OK; +} + +/* + * Ƚ + * + * ȽϴSʹTرȽϽ + * + *ע + * òСӼ + */ +int StrCompare(SString S, SString T) { + int i = 1; + + while(i <= S[0] && i <= T[0]) { + // ַͬʱȽС + if(S[i] != T[i]) { + return S[i] - T[i]; + } + + i++; + } + + return S[0] - T[0]; +} + +/* + * + * + * SƵT + */ +Status StrCopy(SString T, SString S) { + int i; + + // ͬϢһ + for(i = 0; i <= S[0]; i++) { + T[i] = S[i]; + } + + return OK; +} + +/* + * ַSеĿհףɴӡַո + * + *ע + * úڱġ + */ +Status ClearBlank(SString S) { + int i, j; + + // ǿմ + if(S[0] == 0) { + return ERROR; + } + + for(i = 1, j = 0; i <= S[0]; i++) { + // հףԹ + if(S[i] == ' ' || !isprint(S[i])) { + continue; + } + + j++; + + S[j] = S[i]; + } + + S[0] = j; + + return OK; +} diff --git a/VisualC++/ExerciseBook/05.31/SString.h b/VisualC++/ExerciseBook/05.31/SString.h new file mode 100644 index 0000000..0632f18 --- /dev/null +++ b/VisualC++/ExerciseBook/05.31/SString.h @@ -0,0 +1,117 @@ +/*============================= + * Ķ˳洢ʾ˳򴮣 + * + * 㷨: 4.14.24.34.5 + ==============================*/ + +#ifndef SSTRING_H +#define SSTRING_H + +#include +#include // ṩ strlen ԭ +#include // ṩ isprint ԭ +#include "Status.h" //**01 **// + +/* 궨 */ +#define MAXSTRLEN 255 // ˳򴮵󴮳 + +/* + * ˳洢Ͷ + * + * עЧԪشSString1ŵԪʼ洢 + * SString0ŵԪ洢䳤 + */ +typedef unsigned char SString[MAXSTRLEN + 1]; // 0ŵԪŴij + + +/* + * ʾ + * + * ѭ̲ĵдϰߣposָʾַλ()1ʼ + */ + + +/* + * ʼ + * + * һֵΪcharsĴT + * + *ע + * òСӼ + */ +Status StrAssign(SString T, const char* chars); + +/* + * + * + * Sա + */ +Status ClearString(SString S); + +/* + * п + * + * жϴSǷЧݡ + * + * ֵ + * TRUE : SΪ + * FALSE: SΪ + */ +Status StrEmpty(SString S); + +/* + * + * + * شSԪصĸ + * + *ע + * òСӼ + */ +int StrLength(SString S); + +/* + * 㷨4.3 + * + * Ӵ + * + * SubS[pos, pos+len-1] + * ֵָʾǷȡɹ + * + *ע + * òСӼ + */ +Status SubString(SString Sub, SString S, int pos, int len); + +/* + * ɾ + * + * ɾS[pos, pos+len-1] + */ +Status StrDelete(SString S, int pos, int len); + +/* + * Ƚ + * + * ȽϴSʹTرȽϽ + * + *ע + * òСӼ + */ +int StrCompare(SString S, SString T); + +/* + * + * + * SƵT + */ +Status StrCopy(SString T, SString S); + +/* + * ַSеĿհףɴӡַո + * + *ע + * úڱġ + */ +Status ClearBlank(SString S); + +#endif diff --git a/VisualC++/ExerciseBook/05.32.1/05.32.1.c b/VisualC++/ExerciseBook/05.32.1/05.32.1.c new file mode 100644 index 0000000..49d7e91 --- /dev/null +++ b/VisualC++/ExerciseBook/05.32.1/05.32.1.c @@ -0,0 +1,64 @@ +#include +#include "Status.h" //**01 **// +#include "SString.h" //**04 **// +#include "GList-HT.h" //**05 ͹**// + +/* + * жϹǷȣͷβ洢ʾ + */ +Status Algo_5_32_1(GList A, GList B); + + +int main(int argc, char* argv[]) { + GList A, B; + char* a = "((),(e),(a,(b,c,d)))"; + char* b = "((),(e),(a,(b,c,f)))"; + SString Sa, Sb; + + printf(" AB ...\n"); + StrAssign(Sa, a); + CreateGList(&A, Sa); + StrAssign(Sb, b); + CreateGList(&B, Sb); + printf("A = "); + PrintGraph(A); + printf("B = "); + PrintGraph(B); + + Algo_5_32_1(A, B) ? printf("ȣ\n") : printf("ȣ\n"); + + return 0; +} + + +/* + * жϹǷȣͷβ洢ʾ + */ +Status Algo_5_32_1(GList A, GList B) { + if(!A && !B) { + return TRUE; // ձ + } + + // Ϊ + if(A && B) { + // Ԫͬ + if(A->tag == B->tag) { + // ԭӽ + if(A->tag == Atom) { + if(A->Node.atom == B->Node.atom) { + return TRUE; + } + + // + } else { + if(Algo_5_32_1(A->Node.ptr.hp, B->Node.ptr.hp) == TRUE) { + if(Algo_5_32_1(A->Node.ptr.tp, B->Node.ptr.tp) == TRUE) { + return TRUE; + } + } + } + } + } + + return FALSE; +} diff --git a/VisualC++/ExerciseBook/05.32.1/05.32.1.vcxproj b/VisualC++/ExerciseBook/05.32.1/05.32.1.vcxproj new file mode 100644 index 0000000..b0abe34 --- /dev/null +++ b/VisualC++/ExerciseBook/05.32.1/05.32.1.vcxproj @@ -0,0 +1,78 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {CF15AF01-BA4A-45D2-89DC-98FF7B722AB0} + My05321 + + + + Application + true + MultiByte + + + Application + false + true + MultiByte + + + + + + + + + + + + + $(SolutionDir)\..\Status;$(IncludePath) + + + + Level3 + Disabled + + + true + $(SolutionDir)\..\Status\Status.lib;%(AdditionalDependencies) + Console + + + + + Level3 + MaxSpeed + true + true + + + true + true + true + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/05.32.1/05.32.1.vcxproj.filters b/VisualC++/ExerciseBook/05.32.1/05.32.1.vcxproj.filters new file mode 100644 index 0000000..60850ec --- /dev/null +++ b/VisualC++/ExerciseBook/05.32.1/05.32.1.vcxproj.filters @@ -0,0 +1,36 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + 源文件 + + + 源文件 + + + 源文件 + + + + + 头文件 + + + 头文件 + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/05.32.1/05.32.1.vcxproj.user b/VisualC++/ExerciseBook/05.32.1/05.32.1.vcxproj.user new file mode 100644 index 0000000..ace9a86 --- /dev/null +++ b/VisualC++/ExerciseBook/05.32.1/05.32.1.vcxproj.user @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/05.32.1/GList-HT.c b/VisualC++/ExerciseBook/05.32.1/GList-HT.c new file mode 100644 index 0000000..bad30df --- /dev/null +++ b/VisualC++/ExerciseBook/05.32.1/GList-HT.c @@ -0,0 +1,418 @@ +/*============================ + * ͷβ洢ʾ + * + * 㷨: 5.55.65.75.8 + =============================*/ + +#include "GList-HT.h" //**05 ͹**// + +/* + * ʼ + * + * ʼյĹΪ0Ϊ1 + * + *ע + * Ҫÿһȥſ + */ +Status InitGList(GList* L) { + if(L == NULL) { + return ERROR; + } + + *L = NULL; + + return OK; +} + +/* + * 㷨5.7 + * + * + * + * ַSL + */ +Status CreateGList(GList* L, SString S) { + SString emp; // չַ + SString hsub, sub; + GList p, q; + + if(L == NULL) { + return ERROR; + } + + // ַSеĿհףɴӡַո + ClearBlank(S); + + if(StrEmpty(S)) { + return ERROR; + } + + StrAssign(emp, "()"); + + /* + * 봮Ϊ()ҪյĹ + * + *ע + * ̲Ĵġ + * StrCompareķֵָʾַĴСָʾַǷȡ + * S()ȣֵӦ0 + */ + if(!StrCompare(S, emp)) { + *L = NULL; + } else { + *L = (GList) malloc(sizeof(GLNode)); + if(*L == NULL) { + exit(OVERFLOW); + } + + // ԭ + if(StrLength(S) == 1) { + (*L)->tag = Atom; + (*L)->Node.atom = S[1]; + } else { + (*L)->tag = List; + + p = *L; + + // ȥ + SubString(sub, S, 2, StrLength(S) - 2); + + // ظnӱ + do { + // subзͷhsubɺsubҲᷢ仯 + sever(hsub, sub); + + // ݹ鴴 + CreateGList(&(p->Node.ptr.hp), hsub); + + q = p; + + // βΪգҪβ + if(!StrEmpty(sub)) { + p = (GList) malloc(sizeof(GLNode)); + if(p == NULL) { + exit(OVERFLOW); + } + + p->tag = List; + + q->Node.ptr.tp = p; + } + } while(!StrEmpty(sub)); + + q->Node.ptr.tp = NULL; + } + } + + return OK; +} + +/* + * + * + * ͷŹռڴ档 + */ +Status DestroyGList(GList* L) { + GList head, tail; + + if(L == NULL || *L == NULL) { + return ERROR; + } + + // ɾԭӽ + if((*L)->tag == Atom) { + free(*L); + *L = NULL; + + // ɾӱ + } else { + head = (*L)->Node.ptr.hp; + tail = (*L)->Node.ptr.tp; + free(*L); + *L = NULL; + DestroyGList(&head); + DestroyGList(&tail); + } + + return OK; +} + +/* + * 㷨5.6 + * + * + * + * ɹLƵõT + */ +Status CopyGList(GList* T, GList L) { + if(T == NULL) { + return ERROR; + } + + if(L == NULL) { + *T = NULL; + } else { + // ½ + *T = (GList) malloc(sizeof(GLNode)); + if(*T == NULL) { + exit(OVERFLOW); + } + + (*T)->tag = L->tag; + + // Ƶԭ + if(L->tag == Atom) { + (*T)->Node.atom = L->Node.atom; + + // Ʊͷͱβ + } else { + CopyGList(&((*T)->Node.ptr.hp), L->Node.ptr.hp); + CopyGList(&((*T)->Node.ptr.tp), L->Node.ptr.tp); + } + } + + return OK; +} + +/* + * + * + * عijȡ + */ +int GListLength(GList L) { + int count; + + for(count = 0; L != NULL; count++, L = L->Node.ptr.tp) { + } + + return count; +} + +/* + * 㷨5.5 + * + * + * + * ع + */ +int GListDepth(GList L) { + int max, deep; + GList p; + + // ձΪ1 + if(L == NULL) { + return 1; + } + + // ԭΪ0 + if(L->tag == Atom) { + return 0; + } + + // ݹӱ + for(max = 0, p = L; p != NULL; p = p->Node.ptr.tp) { + deep = GListDepth(p->Node.ptr.hp); + if(deep > max) { + max = deep; + } + } + + // ǿձǸԪȼһ + return max + 1; +} + +/* + * п + * + * жϹǷΪա + */ +Status GListEmpty(GList L) { + return L == NULL ? TRUE : FALSE; +} + +/* + * ͷ + */ +GList GetHead(GList L) { + GList p; + + // ձޱͷﲻܷNULLȻֲʧ˻Ƿ˿ձ + if(L == NULL) { + exit(ERROR); + } + + CopyGList(&p, L->Node.ptr.hp); + + return p; +} + +/* + * β + */ +GList GetTail(GList L) { + GList p; + + // ձޱβﲻܷNULLȻֲʧ˻Ƿ˿ձ + if(L == NULL) { + exit(ERROR); + } + + CopyGList(&p, L->Node.ptr.tp); + + return p; +} + +/* + * + * + * ԪeΪLĵһԪء + */ +Status InsertFirst(GList* L, GList e) { + GList g; + + if(L == NULL) { + return ERROR; + } + + g = (GList) malloc(sizeof(GLNode)); + if(g == NULL) { + exit(OVERFLOW); + } + + g->tag = List; + g->Node.ptr.hp = e; + g->Node.ptr.tp = *L; + *L = g; + + return OK; +} + +/* + * ɾ + * + * LĵһԪɾeء + */ +Status DeleteFirst(GList* L, GList* e) { + GList p; + + // ձ޷ɾ + if(L == NULL || *L == NULL) { + return ERROR; + } + + p = *L; + *L = (*L)->Node.ptr.tp; + + CopyGList(e, p->Node.ptr.hp); + + free(p); + + return OK; +} + +/* + * + * + * visitʹL + */ +void Traverse(GList L, void(Visit)(AtomType)) { + + if(L == NULL) { + return; + } + + if(L->tag == Atom) { + Visit(L->Node.atom); + } else { + Traverse(L->Node.ptr.hp, Visit); + Traverse(L->Node.ptr.tp, Visit); + } + +} + +/* + * ͼλ + * + * L + */ +void PrintGraph(GList L) { + Print(L, Head); + printf("\n"); +} + +/* + * ͼλڲʵ֣markͼλǡ + */ +static void Print(GList L, Mark mark) { + // LΪ + if(L == NULL) { + if(mark == Head) { + printf("("); + } + + printf(")"); + + // LΪʱ + } else { + // ԭӽ㣬ԭ + if(L->tag == Atom) { + printf("%c", L->Node.atom); + + // ӱ㣬ҪԱͷβֱ + } else { + if(mark == Head) { + printf("("); + } else { + printf(","); + } + + Print(L->Node.ptr.hp, Head); + Print(L->Node.ptr.tp, Tail); + } + } +} + +/* + * 㷨5.8 + * + * ǿմstrָ֣hsubΪһ','֮ǰӴstrΪһ','֮Ӵ + * + *ע + * 1.ַstrȷ޿հ׷ţstrѾȥš + * 2.ɺstrҲᷢ仯 + */ +static void sever(SString hstr, SString str) { + int i, k, n; + SString ch; + + n = StrLength(str); + + i = 0; // ַʱα + k = 0; // δ + + do { + ++i; + + // ȡstrһַ + SubString(ch, str, i, 1); + + if(ch[1] == '(') { + ++k; + } + + if(ch[1] == ')') { + --k; + } + } while(i < n && (ch[1] != ',' || k != 0)); + + // ڶ + if(i < n) { + SubString(hstr, str, 1, i - 1); + SubString(str, str, i + 1, n - i); + + // ֻһ + } else { + StrCopy(hstr, str); + ClearString(str); + } +} diff --git a/VisualC++/ExerciseBook/05.32.1/GList-HT.h b/VisualC++/ExerciseBook/05.32.1/GList-HT.h new file mode 100644 index 0000000..508b96f --- /dev/null +++ b/VisualC++/ExerciseBook/05.32.1/GList-HT.h @@ -0,0 +1,164 @@ +/*============================ + * ͷβ洢ʾ + * + * 㷨: 5.55.65.75.8 + =============================*/ + +#ifndef GLIST_HT_H +#define GLIST_HT_H + +#include +#include // ṩ mallocreallocfreeexit ԭ +#include "Status.h" //**01 **// +#include "SString.h" //**04 **// + +/* ԭԪ */ +typedef char AtomType; + +/* + * + * + * Atom-0ԭӽ + * List-1 + */ +typedef enum { Atom, List } ElemTag; + +/* ͷβ洢ʾͶ */ +typedef struct GLNode { + ElemTag tag; // ǣԭӽͱ + + // ԭӽͱϲ + union { + AtomType atom; // atomԭӽֵAtomTypeû + struct { + struct GLNode* hp; // ָͷ + struct GLNode* tp; // ָβ + } ptr; // ָ + } Node; +} GLNode; + +/* */ +typedef GLNode* GList; + +/* + * ͼλ + * + * HeadָԱͷ + * TailָԱβ + */ +typedef enum { Head, Tail } Mark; + + +/* + * ʼ + * + * ʼյĹΪ0Ϊ1 + * + *ע + * Ҫÿһȥſ + */ +Status InitGList(GList* L); + +/* + * 㷨5.7 + * + * + * + * ַSL + */ +Status CreateGList(GList* L, SString S); + +/* + * + * + * ͷŹռڴ档 + */ +Status DestroyGList(GList* L); + +/* + * 㷨5.6 + * + * + * + * ɹLƵõT + */ +Status CopyGList(GList* T, GList L); + +/* + * + * + * عijȡ + */ +int GListLength(GList L); + +/* + * 㷨5.5 + * + * + * + * ع + */ +int GListDepth(GList L); + +/* + * п + * + * жϹǷΪա + */ +Status GListEmpty(GList L); + +/* + * ͷ + */ +GList GetHead(GList L); + +/* + * β + */ +GList GetTail(GList L); + +/* + * + * + * ԪeΪLĵһԪء + */ +Status InsertFirst(GList* L, GList e); + +/* + * ɾ + * + * LĵһԪɾeء + */ +Status DeleteFirst(GList* L, GList* e); + +/* + * + * + * visitʹL + */ +void Traverse(GList L, void (Visit)(AtomType)); + +/* + * ͼλ + * + * L + */ +void PrintGraph(GList L); + +/* + * ͼλڲʵ֣markͼλǡ + */ +static void Print(GList L, Mark mark); + +/* + * 㷨5.8 + * + * ǿմstrָ֣hsubΪһ','֮ǰӴstrΪһ','֮Ӵ + * + *ע + * 1.ַstrȷ޿հ׷ţstrѾȥš + * 2.ɺstrҲᷢ仯 + */ +static void sever(SString hstr, SString str); + +#endif diff --git a/VisualC++/ExerciseBook/05.32.1/SString.c b/VisualC++/ExerciseBook/05.32.1/SString.c new file mode 100644 index 0000000..7a96fcf --- /dev/null +++ b/VisualC++/ExerciseBook/05.32.1/SString.c @@ -0,0 +1,195 @@ +/*============================= + * Ķ˳洢ʾ˳򴮣 + * + * 㷨: 4.14.24.34.5 + ==============================*/ + +#include "SString.h" //**04 **// + +/* + * ʼ + * + * һֵΪcharsĴT + * + *ע + * òСӼ + */ +Status StrAssign(SString T, const char* chars) { + int i, len; + + len = (int) strlen(chars); + + // chars + if(len > MAXSTRLEN) { + return ERROR; + } + + T[0] = len; + for(i = 1; i <= len; i++) { + T[i] = chars[i - 1]; + } + + return OK; +} + +/* + * + * + * Sա + */ +Status ClearString(SString S) { + // ֻҪΪ0Ϳ + S[0] = 0; + return OK; +} + +/* + * п + * + * жϴSǷЧݡ + * + * ֵ + * TRUE : SΪ + * FALSE: SΪ + */ +Status StrEmpty(SString S) { + return S[0] == 0 ? TRUE : FALSE; +} + +/* + * + * + * شSԪصĸ + * + *ע + * òСӼ + */ +int StrLength(SString S) { + return S[0]; +} + +/* + * 㷨4.3 + * + * Ӵ + * + * SubS[pos, pos+len-1] + * ֵָʾǷȡɹ + * + *ע + * òСӼ + */ +Status SubString(SString Sub, SString S, int pos, int len) { + int i; + + if(pos < 1 || pos > S[0] || len < 0 || pos + len - 1 > S[0]) { + return ERROR; + } + + // Ԫ + for(i = 1; i <= len; i++) { + Sub[i] = S[pos + i - 1]; + } + + // ȷ³ + Sub[0] = len; + + return OK; +} + +/* + * ɾ + * + * ɾS[pos, pos+len-1] + */ +Status StrDelete(SString S, int pos, int len) { + int i; + + if(pos < 1 || pos + len - 1 > S[0] || len < 0) { + return ERROR; + } + + // ɾijΪ0ǰ + if(len == 0) { + return OK; + } + + // ѺԪŲǰ棬ǵɾԪ + for(i = pos + len; i <= S[0]; i++) { + S[i - len] = S[i]; + } + + // ȼ + S[0] -= len; + + return OK; +} + +/* + * Ƚ + * + * ȽϴSʹTرȽϽ + * + *ע + * òСӼ + */ +int StrCompare(SString S, SString T) { + int i = 1; + + while(i <= S[0] && i <= T[0]) { + // ַͬʱȽС + if(S[i] != T[i]) { + return S[i] - T[i]; + } + + i++; + } + + return S[0] - T[0]; +} + +/* + * + * + * SƵT + */ +Status StrCopy(SString T, SString S) { + int i; + + // ͬϢһ + for(i = 0; i <= S[0]; i++) { + T[i] = S[i]; + } + + return OK; +} + +/* + * ַSеĿհףɴӡַո + * + *ע + * úڱġ + */ +Status ClearBlank(SString S) { + int i, j; + + // ǿմ + if(S[0] == 0) { + return ERROR; + } + + for(i = 1, j = 0; i <= S[0]; i++) { + // հףԹ + if(S[i] == ' ' || !isprint(S[i])) { + continue; + } + + j++; + + S[j] = S[i]; + } + + S[0] = j; + + return OK; +} diff --git a/VisualC++/ExerciseBook/05.32.1/SString.h b/VisualC++/ExerciseBook/05.32.1/SString.h new file mode 100644 index 0000000..0632f18 --- /dev/null +++ b/VisualC++/ExerciseBook/05.32.1/SString.h @@ -0,0 +1,117 @@ +/*============================= + * Ķ˳洢ʾ˳򴮣 + * + * 㷨: 4.14.24.34.5 + ==============================*/ + +#ifndef SSTRING_H +#define SSTRING_H + +#include +#include // ṩ strlen ԭ +#include // ṩ isprint ԭ +#include "Status.h" //**01 **// + +/* 궨 */ +#define MAXSTRLEN 255 // ˳򴮵󴮳 + +/* + * ˳洢Ͷ + * + * עЧԪشSString1ŵԪʼ洢 + * SString0ŵԪ洢䳤 + */ +typedef unsigned char SString[MAXSTRLEN + 1]; // 0ŵԪŴij + + +/* + * ʾ + * + * ѭ̲ĵдϰߣposָʾַλ()1ʼ + */ + + +/* + * ʼ + * + * һֵΪcharsĴT + * + *ע + * òСӼ + */ +Status StrAssign(SString T, const char* chars); + +/* + * + * + * Sա + */ +Status ClearString(SString S); + +/* + * п + * + * жϴSǷЧݡ + * + * ֵ + * TRUE : SΪ + * FALSE: SΪ + */ +Status StrEmpty(SString S); + +/* + * + * + * شSԪصĸ + * + *ע + * òСӼ + */ +int StrLength(SString S); + +/* + * 㷨4.3 + * + * Ӵ + * + * SubS[pos, pos+len-1] + * ֵָʾǷȡɹ + * + *ע + * òСӼ + */ +Status SubString(SString Sub, SString S, int pos, int len); + +/* + * ɾ + * + * ɾS[pos, pos+len-1] + */ +Status StrDelete(SString S, int pos, int len); + +/* + * Ƚ + * + * ȽϴSʹTرȽϽ + * + *ע + * òСӼ + */ +int StrCompare(SString S, SString T); + +/* + * + * + * SƵT + */ +Status StrCopy(SString T, SString S); + +/* + * ַSеĿհףɴӡַո + * + *ע + * úڱġ + */ +Status ClearBlank(SString S); + +#endif diff --git a/VisualC++/ExerciseBook/05.32.2/05.32.2.c b/VisualC++/ExerciseBook/05.32.2/05.32.2.c new file mode 100644 index 0000000..adc2453 --- /dev/null +++ b/VisualC++/ExerciseBook/05.32.2/05.32.2.c @@ -0,0 +1,66 @@ +#include +#include "Status.h" //**01 **// +#include "SString.h" //**04 **// +#include "GList-E.h" //**05 ͹**// + +/* + * жϹǷȣչ洢ʾ + */ +Status Algo_5_32_2(GList A, GList B); + + +int main(int argc, char* argv[]) { + GList A, B; + char* a = "((),(e),(a,(b,c,d)))"; + char* b = "((),(e),(a,(b,c,f)))"; + SString Sa, Sb; + + printf(" AB ...\n"); + StrAssign(Sa, a); + CreateGList(&A, Sa); + StrAssign(Sb, b); + CreateGList(&B, Sb); + printf("A = "); + PrintGraph(A); + printf("B = "); + PrintGraph(B); + + Algo_5_32_2(A, B) ? printf("ȣ\n") : printf("ȣ\n"); + + return 0; +} + + +/* + * жϹǷȣչ洢ʾ + */ +Status Algo_5_32_2(GList A, GList B) { + if(!A && !B) { + return TRUE; // ձ + } + + // Ϊ + if(A && B) { + // Ԫͬ + if(A->tag == B->tag) { + // ԭӽ + if(A->tag == Atom) { + if(A->Node.atom == B->Node.atom) { + if(Algo_5_32_2(A->tp, B->tp) == TRUE) { + return TRUE; + } + } + + // + } else { + if(Algo_5_32_2(A->Node.hp, B->Node.hp) == TRUE) { + if(Algo_5_32_2(A->tp, B->tp) == TRUE) { + return TRUE; + } + } + } + } + } + + return FALSE; +} diff --git a/VisualC++/ExerciseBook/05.32.2/05.32.2.vcxproj b/VisualC++/ExerciseBook/05.32.2/05.32.2.vcxproj new file mode 100644 index 0000000..b451459 --- /dev/null +++ b/VisualC++/ExerciseBook/05.32.2/05.32.2.vcxproj @@ -0,0 +1,78 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {2C7DDD17-6590-4684-826B-AEC0A0E4221A} + My05322 + + + + Application + true + MultiByte + + + Application + false + true + MultiByte + + + + + + + + + + + + + $(SolutionDir)\..\Status;$(IncludePath) + + + + Level3 + Disabled + + + true + $(SolutionDir)\..\Status\Status.lib;%(AdditionalDependencies) + Console + + + + + Level3 + MaxSpeed + true + true + + + true + true + true + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/05.32.2/05.32.2.vcxproj.filters b/VisualC++/ExerciseBook/05.32.2/05.32.2.vcxproj.filters new file mode 100644 index 0000000..2fef25a --- /dev/null +++ b/VisualC++/ExerciseBook/05.32.2/05.32.2.vcxproj.filters @@ -0,0 +1,36 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + 源文件 + + + 源文件 + + + 源文件 + + + + + 头文件 + + + 头文件 + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/05.32.2/05.32.2.vcxproj.user b/VisualC++/ExerciseBook/05.32.2/05.32.2.vcxproj.user new file mode 100644 index 0000000..ace9a86 --- /dev/null +++ b/VisualC++/ExerciseBook/05.32.2/05.32.2.vcxproj.user @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/05.32.2/GList-E.c b/VisualC++/ExerciseBook/05.32.2/GList-E.c new file mode 100644 index 0000000..3fc0ad9 --- /dev/null +++ b/VisualC++/ExerciseBook/05.32.2/GList-E.c @@ -0,0 +1,449 @@ +/*=========================== + * չ洢ʾ + ============================*/ + +#include "GList-E.h" //**05 ͹**// + +/* + * ʼ + * + * ʼյĹΪ0Ϊ1 + * + *ע + * Ҫÿһſ + */ +Status InitGList(GList* L) { + if(L == NULL) { + return ERROR; + } + + *L = (GList) malloc(sizeof(GLNode)); + if(!*L) { + exit(OVERFLOW); + } + + (*L)->tag = List; + (*L)->Node.hp = NULL; + (*L)->tp = NULL; + + return OK; +} + +/* + * + * + * ַSL + */ +Status CreateGList(GList* L, SString S) { + SString emp, hsub, sub, tmp; + + if(L == NULL) { + return ERROR; + } + + // ַSеĿհףɴӡַո + ClearBlank(S); + + if(StrEmpty(S)) { + return ERROR; + } + + // Ϊ˲ƻS + StrCopy(sub, S); + + /* + * ִеʱ + * ٴִеʱѾȥ + */ + sever(hsub, sub); + + *L = (GList) malloc(sizeof(GLNode)); + if(*L == NULL) { + exit(OVERFLOW); + } + + StrAssign(emp, "()"); + + if(!StrCompare(hsub, emp)) { + (*L)->tag = List; + (*L)->Node.hp = NULL; + } else { + if(StrLength(hsub) == 1) { + (*L)->tag = Atom; + (*L)->Node.atom = hsub[1]; + } else { + (*L)->tag = List; + + SubString(tmp, hsub, 2, StrLength(hsub) - 2); + + CreateGList(&((*L)->Node.hp), tmp); + } + } + + // ڶβ˳ݹ + if(StrEmpty(sub)) { + (*L)->tp = NULL; + } else { + // ݹβ + CreateGList(&((*L)->tp), sub); + } + + return OK; +} + +/* + * + * + * ͷŹռڴ档 + */ +Status DestroyGList(GList* L) { + GList head, tail; + + if(L == NULL || *L == NULL) { + return ERROR; + } + + // ӱ + if((*L)->tag == List) { + head = (*L)->Node.hp; // ͷ + tail = (*L)->tp; // β + + free(*L); + *L = NULL; + + // ݹ鴦ͷ + if(head != NULL) { + DestroyGList(&head); + } + + // ݹ鴦β + if(tail != NULL) { + DestroyGList(&tail); + } + + // ԭӽ + } else { + tail = (*L)->tp; // β + + free(*L); + *L = NULL; + + if(tail != NULL) { + DestroyGList(&tail); + } + } + + return OK; +} + +/* + * + * + * ɹLƵõT + */ +Status CopyGList(GList* T, GList L) { + + if(L == NULL) { + return ERROR; + } + + *T = (GList) malloc(sizeof(GLNode)); + if(*T == NULL) { + exit(OVERFLOW); + } + + // ԭ + if(L->tag == Atom) { + (*T)->tag = Atom; + (*T)->Node.atom = L->Node.atom; + + // ӱ + } else { + (*T)->tag = List; + + // Ʊͷ + if(L->Node.hp != NULL) { + CopyGList(&((*T)->Node.hp), L->Node.hp); + } else { + (*T)->Node.hp = NULL; + } + } + + // Ʊβ + if(L->tp != NULL) { + CopyGList(&((*T)->tp), L->tp); + } else { + (*T)->tp = NULL; + } + + return OK; +} + +/* + * + * + * عijȡ + */ +int GListLength(GList L) { + int count = 0; + GList p; + + // + if(L == NULL) { + return -1; + } + + p = L->Node.hp; + + while(p != NULL) { + ++count; + p = p->tp; + } + + return count; +} + +/* + * + * + * ع + */ +int GListDepth(GList L) { + int max, deep; + GList p; + + max = 0; + + // + if(L == NULL) { + return -1; + } + + // ձΪ1 + if(L->tag == List && !L->Node.hp) { + return 1; + } + + // ԭΪ0 + if(L->tag == Atom) { + return 0; + } + + // ݹӱ + for(p = L->Node.hp; p != NULL; p = p->tp) { + // pΪͷָӱ + deep = GListDepth(p); + if(deep > max) { + max = deep; + } + } + + return max + 1; +} + +/* + * п + * + * жϹǷΪա + */ +Status GListEmpty(GList L) { + // + if(L == NULL) { + return ERROR; + } + + if(L->tag == List && L->Node.hp == NULL && L->tp == NULL) { + return TRUE; + } else { + return ERROR; + } +} + +/* + * ͷ + */ +GList GetHead(GList L) { + GList p, q; + + // ڻΪձ޷ȡͷ + if(L == NULL || L->Node.hp == NULL) { + return NULL; + } + + q = L->Node.hp->tp; // ʱLıβϢ + L->Node.hp->tp = NULL; // ȥLıβ + + CopyGList(&p, L->Node.hp); // ƱͷϢαβ + + L->Node.hp->tp = q; // ָLıβϢ + + return p; +} + +/* + * β + */ +GList GetTail(GList L) { + GList p, q; + + // ڻΪձ޷ȡβ + if(L == NULL || L->Node.hp == NULL) { + return NULL; + } + + q = L->Node.hp; // ʱLıͷϢ + L->Node.hp = q->tp; // ժLıͷ + + CopyGList(&p, L); // ƱβϢαͷ + + q->tp = L->Node.hp; // ָLıͷϢ + L->Node.hp = q; + + return p; +} + +/* + * + * + * ԪeΪLĵһԪء + */ +Status InsertFirst(GList* L, GList e) { + + // + if(L == NULL || *L == NULL) { + return ERROR; + } + + if(e == NULL) { + return ERROR; + } + + e->tp = (*L)->Node.hp; + (*L)->Node.hp = e; + + return OK; +} + +/* + * ɾ + * + * LĵһԪɾeء + */ +Status DeleteFirst(GList* L, GList* e) { + GList p; + + // ڻΪձ޷ɾͷ + if(*L == NULL || (*L)->Node.hp == NULL) { + return ERROR; + } + + p = (*L)->Node.hp; + (*L)->Node.hp = p->tp; + p->tp = NULL; + + *e = p; + + return OK; +} + +/* + * + * + * visitʹL + */ +void Traverse(GList L, void(Visit)(AtomType)) { + if(L == NULL) { + return; + } + + if(L->tag == List) { + Traverse(L->Node.hp, Visit); + } else { + Visit(L->Node.atom); + } + + Traverse(L->tp, Visit); +} + +/* + * ͼλ + * + * L + */ +void PrintGraph(GList L) { + Print(L); + printf("\n"); +} + +/* + * ͼλڲʵ֡ + */ +static void Print(GList L) { + if(L == NULL) { + return; + } + + // + if(L->tag == List) { + printf("("); + + if(L->Node.hp) { + Print(L->Node.hp); + } + + if(L->tp) { + printf("),"); + Print(L->tp); + } else { + printf(")"); + } + + // ԭӽ + } else { + printf("%c", L->Node.atom); + if(L->tp) { + printf(","); + Print(L->tp); + } + } +} + +/* + * ǿմstrָ֣hsubΪһ','֮ǰӴstrΪһ','֮Ӵ + * + *ע + * 1.ַstrȷ޿հ׷ţ + * strſȥҲδȥ + * 2.ɺstrҲᷢ仯 + */ +static void sever(SString hstr, SString str) { + int i, k, n; + SString ch; + + n = StrLength(str); + + i = 0; // ַʱα + k = 0; // δ + + do { + ++i; + + // ȡstrһַ + SubString(ch, str, i, 1); + + if(ch[1] == '(') { + ++k; + } + if(ch[1] == ')') { + --k; + } + } while(i < n && (ch[1] != ',' || k != 0)); + + if(i < n) { + SubString(hstr, str, 1, i - 1); + SubString(str, str, i + 1, n - i); + } else { + StrCopy(hstr, str); + ClearString(str); + } +} diff --git a/VisualC++/ExerciseBook/05.32.2/GList-E.h b/VisualC++/ExerciseBook/05.32.2/GList-E.h new file mode 100644 index 0000000..fa9af82 --- /dev/null +++ b/VisualC++/ExerciseBook/05.32.2/GList-E.h @@ -0,0 +1,146 @@ +/*=========================== + * չ洢ʾ + ============================*/ + +#ifndef GLIST_E_H +#define GLIST_E_H + +#include +#include // ṩ mallocreallocfreeexit ԭ +#include "Status.h" //**01 **// +#include "SString.h" //**04 **// + +/* ԭԪ */ +typedef char AtomType; //ԭ + +/* + * + * + * Atom-0ԭӽ + * List-1 + */ +typedef enum { Atom, List } ElemTag; + +/* չ洢ʾͶ */ +typedef struct GLNode { + ElemTag tag; // ǣԭӽͱ + + // ԭӽͱϲ + union + { + AtomType atom; // atomԭӽֵAtomTypeû + struct GLNode* hp; // ָͷ + } Node; + struct GLNode* tp; // ָβ +} GLNode; + +/* */ +typedef GLNode* GList; + + +/* + * ʼ + * + * ʼյĹΪ0Ϊ1 + * + *ע + * Ҫÿһſ + */ +Status InitGList(GList* L); + +/* + * + * + * ַSL + */ +Status CreateGList(GList* L, SString S); + +/* + * + * + * ͷŹռڴ档 + */ +Status DestroyGList(GList* L); + +/* + * + * + * ɹLƵõT + */ +Status CopyGList(GList* T, GList L); + +/* + * + * + * عijȡ + */ +int GListLength(GList L); + +/* + * + * + * ع + */ +int GListDepth(GList L); + +/* + * п + * + * жϹǷΪա + */ +Status GListEmpty(GList L); + +/* + * ͷ + */ +GList GetHead(GList L); + +/* + * β + */ +GList GetTail(GList L); + +/* + * + * + * ԪeΪLĵһԪء + */ +Status InsertFirst(GList* L, GList e); + +/* + * ɾ + * + * LĵһԪɾeء + */ +Status DeleteFirst(GList* L, GList* e); + +/* + * + * + * visitʹL + */ +void Traverse(GList L, void(Visit)(AtomType)); + +/* + * ͼλ + * + * L + */ +void PrintGraph(GList L); + +/* + * ͼλڲʵ֡ + */ +static void Print(GList L); + +/* + * ǿմstrָ֣hsubΪһ','֮ǰӴstrΪһ','֮Ӵ + * + *ע + * 1.ַstrȷ޿հ׷ţ + * strſȥҲδȥ + * 2.ɺstrҲᷢ仯 + */ +static void sever(SString hstr, SString str); + +#endif diff --git a/VisualC++/ExerciseBook/05.32.2/SString.c b/VisualC++/ExerciseBook/05.32.2/SString.c new file mode 100644 index 0000000..7a96fcf --- /dev/null +++ b/VisualC++/ExerciseBook/05.32.2/SString.c @@ -0,0 +1,195 @@ +/*============================= + * Ķ˳洢ʾ˳򴮣 + * + * 㷨: 4.14.24.34.5 + ==============================*/ + +#include "SString.h" //**04 **// + +/* + * ʼ + * + * һֵΪcharsĴT + * + *ע + * òСӼ + */ +Status StrAssign(SString T, const char* chars) { + int i, len; + + len = (int) strlen(chars); + + // chars + if(len > MAXSTRLEN) { + return ERROR; + } + + T[0] = len; + for(i = 1; i <= len; i++) { + T[i] = chars[i - 1]; + } + + return OK; +} + +/* + * + * + * Sա + */ +Status ClearString(SString S) { + // ֻҪΪ0Ϳ + S[0] = 0; + return OK; +} + +/* + * п + * + * жϴSǷЧݡ + * + * ֵ + * TRUE : SΪ + * FALSE: SΪ + */ +Status StrEmpty(SString S) { + return S[0] == 0 ? TRUE : FALSE; +} + +/* + * + * + * شSԪصĸ + * + *ע + * òСӼ + */ +int StrLength(SString S) { + return S[0]; +} + +/* + * 㷨4.3 + * + * Ӵ + * + * SubS[pos, pos+len-1] + * ֵָʾǷȡɹ + * + *ע + * òСӼ + */ +Status SubString(SString Sub, SString S, int pos, int len) { + int i; + + if(pos < 1 || pos > S[0] || len < 0 || pos + len - 1 > S[0]) { + return ERROR; + } + + // Ԫ + for(i = 1; i <= len; i++) { + Sub[i] = S[pos + i - 1]; + } + + // ȷ³ + Sub[0] = len; + + return OK; +} + +/* + * ɾ + * + * ɾS[pos, pos+len-1] + */ +Status StrDelete(SString S, int pos, int len) { + int i; + + if(pos < 1 || pos + len - 1 > S[0] || len < 0) { + return ERROR; + } + + // ɾijΪ0ǰ + if(len == 0) { + return OK; + } + + // ѺԪŲǰ棬ǵɾԪ + for(i = pos + len; i <= S[0]; i++) { + S[i - len] = S[i]; + } + + // ȼ + S[0] -= len; + + return OK; +} + +/* + * Ƚ + * + * ȽϴSʹTرȽϽ + * + *ע + * òСӼ + */ +int StrCompare(SString S, SString T) { + int i = 1; + + while(i <= S[0] && i <= T[0]) { + // ַͬʱȽС + if(S[i] != T[i]) { + return S[i] - T[i]; + } + + i++; + } + + return S[0] - T[0]; +} + +/* + * + * + * SƵT + */ +Status StrCopy(SString T, SString S) { + int i; + + // ͬϢһ + for(i = 0; i <= S[0]; i++) { + T[i] = S[i]; + } + + return OK; +} + +/* + * ַSеĿհףɴӡַո + * + *ע + * úڱġ + */ +Status ClearBlank(SString S) { + int i, j; + + // ǿմ + if(S[0] == 0) { + return ERROR; + } + + for(i = 1, j = 0; i <= S[0]; i++) { + // հףԹ + if(S[i] == ' ' || !isprint(S[i])) { + continue; + } + + j++; + + S[j] = S[i]; + } + + S[0] = j; + + return OK; +} diff --git a/VisualC++/ExerciseBook/05.32.2/SString.h b/VisualC++/ExerciseBook/05.32.2/SString.h new file mode 100644 index 0000000..0632f18 --- /dev/null +++ b/VisualC++/ExerciseBook/05.32.2/SString.h @@ -0,0 +1,117 @@ +/*============================= + * Ķ˳洢ʾ˳򴮣 + * + * 㷨: 4.14.24.34.5 + ==============================*/ + +#ifndef SSTRING_H +#define SSTRING_H + +#include +#include // ṩ strlen ԭ +#include // ṩ isprint ԭ +#include "Status.h" //**01 **// + +/* 궨 */ +#define MAXSTRLEN 255 // ˳򴮵󴮳 + +/* + * ˳洢Ͷ + * + * עЧԪشSString1ŵԪʼ洢 + * SString0ŵԪ洢䳤 + */ +typedef unsigned char SString[MAXSTRLEN + 1]; // 0ŵԪŴij + + +/* + * ʾ + * + * ѭ̲ĵдϰߣposָʾַλ()1ʼ + */ + + +/* + * ʼ + * + * һֵΪcharsĴT + * + *ע + * òСӼ + */ +Status StrAssign(SString T, const char* chars); + +/* + * + * + * Sա + */ +Status ClearString(SString S); + +/* + * п + * + * жϴSǷЧݡ + * + * ֵ + * TRUE : SΪ + * FALSE: SΪ + */ +Status StrEmpty(SString S); + +/* + * + * + * شSԪصĸ + * + *ע + * òСӼ + */ +int StrLength(SString S); + +/* + * 㷨4.3 + * + * Ӵ + * + * SubS[pos, pos+len-1] + * ֵָʾǷȡɹ + * + *ע + * òСӼ + */ +Status SubString(SString Sub, SString S, int pos, int len); + +/* + * ɾ + * + * ɾS[pos, pos+len-1] + */ +Status StrDelete(SString S, int pos, int len); + +/* + * Ƚ + * + * ȽϴSʹTرȽϽ + * + *ע + * òСӼ + */ +int StrCompare(SString S, SString T); + +/* + * + * + * SƵT + */ +Status StrCopy(SString T, SString S); + +/* + * ַSеĿհףɴӡַո + * + *ע + * úڱġ + */ +Status ClearBlank(SString S); + +#endif diff --git a/VisualC++/ExerciseBook/05.33.1/05.33.1.c b/VisualC++/ExerciseBook/05.33.1/05.33.1.c new file mode 100644 index 0000000..0ee6f53 --- /dev/null +++ b/VisualC++/ExerciseBook/05.33.1/05.33.1.c @@ -0,0 +1,47 @@ +#include +#include "SString.h" //**04 **// +#include "GList-HT.h" //**05 ͹**// + +/* + * ԭڲΣͷβ洢ʾ + */ +void Algo_5_33_1(GList L, int d); + + +int main(int argc, char* argv[]) { + GList L; + char* s = "((),(e),(a,(b,c,d)))"; + SString S; + + printf(" L ...\n"); + StrAssign(S, s); + CreateGList(&L, S); + printf("L = "); + PrintGraph(L); + + Algo_5_33_1(L, 0); + + return 0; +} + + +/* + * ԭڲΣͷβ洢ʾ + */ +void Algo_5_33_1(GList L, int d) { + int i = d; // dijֵֵΪ0 + + if(L == NULL) { + return; + } + + if(L->tag == Atom) { + printf("%c -> %d\n", L->Node.atom, i); + } + + // ͷָָĻһ + if(L->tag == List) { + Algo_5_33_1(L->Node.ptr.hp, i + 1); + Algo_5_33_1(L->Node.ptr.tp, i); + } +} diff --git a/VisualC++/ExerciseBook/05.33.1/05.33.1.vcxproj b/VisualC++/ExerciseBook/05.33.1/05.33.1.vcxproj new file mode 100644 index 0000000..5b205e9 --- /dev/null +++ b/VisualC++/ExerciseBook/05.33.1/05.33.1.vcxproj @@ -0,0 +1,78 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {4862063F-4D32-4C02-AF63-35381605EDFE} + My05331 + + + + Application + true + MultiByte + + + Application + false + true + MultiByte + + + + + + + + + + + + + $(SolutionDir)\..\Status;$(IncludePath) + + + + Level3 + Disabled + + + true + $(SolutionDir)\..\Status\Status.lib;%(AdditionalDependencies) + Console + + + + + Level3 + MaxSpeed + true + true + + + true + true + true + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/05.33.1/05.33.1.vcxproj.filters b/VisualC++/ExerciseBook/05.33.1/05.33.1.vcxproj.filters new file mode 100644 index 0000000..313eca2 --- /dev/null +++ b/VisualC++/ExerciseBook/05.33.1/05.33.1.vcxproj.filters @@ -0,0 +1,36 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + 源文件 + + + 源文件 + + + 源文件 + + + + + 头文件 + + + 头文件 + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/05.33.1/05.33.1.vcxproj.user b/VisualC++/ExerciseBook/05.33.1/05.33.1.vcxproj.user new file mode 100644 index 0000000..ace9a86 --- /dev/null +++ b/VisualC++/ExerciseBook/05.33.1/05.33.1.vcxproj.user @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/05.33.1/GList-HT.c b/VisualC++/ExerciseBook/05.33.1/GList-HT.c new file mode 100644 index 0000000..bad30df --- /dev/null +++ b/VisualC++/ExerciseBook/05.33.1/GList-HT.c @@ -0,0 +1,418 @@ +/*============================ + * ͷβ洢ʾ + * + * 㷨: 5.55.65.75.8 + =============================*/ + +#include "GList-HT.h" //**05 ͹**// + +/* + * ʼ + * + * ʼյĹΪ0Ϊ1 + * + *ע + * Ҫÿһȥſ + */ +Status InitGList(GList* L) { + if(L == NULL) { + return ERROR; + } + + *L = NULL; + + return OK; +} + +/* + * 㷨5.7 + * + * + * + * ַSL + */ +Status CreateGList(GList* L, SString S) { + SString emp; // չַ + SString hsub, sub; + GList p, q; + + if(L == NULL) { + return ERROR; + } + + // ַSеĿհףɴӡַո + ClearBlank(S); + + if(StrEmpty(S)) { + return ERROR; + } + + StrAssign(emp, "()"); + + /* + * 봮Ϊ()ҪյĹ + * + *ע + * ̲Ĵġ + * StrCompareķֵָʾַĴСָʾַǷȡ + * S()ȣֵӦ0 + */ + if(!StrCompare(S, emp)) { + *L = NULL; + } else { + *L = (GList) malloc(sizeof(GLNode)); + if(*L == NULL) { + exit(OVERFLOW); + } + + // ԭ + if(StrLength(S) == 1) { + (*L)->tag = Atom; + (*L)->Node.atom = S[1]; + } else { + (*L)->tag = List; + + p = *L; + + // ȥ + SubString(sub, S, 2, StrLength(S) - 2); + + // ظnӱ + do { + // subзͷhsubɺsubҲᷢ仯 + sever(hsub, sub); + + // ݹ鴴 + CreateGList(&(p->Node.ptr.hp), hsub); + + q = p; + + // βΪգҪβ + if(!StrEmpty(sub)) { + p = (GList) malloc(sizeof(GLNode)); + if(p == NULL) { + exit(OVERFLOW); + } + + p->tag = List; + + q->Node.ptr.tp = p; + } + } while(!StrEmpty(sub)); + + q->Node.ptr.tp = NULL; + } + } + + return OK; +} + +/* + * + * + * ͷŹռڴ档 + */ +Status DestroyGList(GList* L) { + GList head, tail; + + if(L == NULL || *L == NULL) { + return ERROR; + } + + // ɾԭӽ + if((*L)->tag == Atom) { + free(*L); + *L = NULL; + + // ɾӱ + } else { + head = (*L)->Node.ptr.hp; + tail = (*L)->Node.ptr.tp; + free(*L); + *L = NULL; + DestroyGList(&head); + DestroyGList(&tail); + } + + return OK; +} + +/* + * 㷨5.6 + * + * + * + * ɹLƵõT + */ +Status CopyGList(GList* T, GList L) { + if(T == NULL) { + return ERROR; + } + + if(L == NULL) { + *T = NULL; + } else { + // ½ + *T = (GList) malloc(sizeof(GLNode)); + if(*T == NULL) { + exit(OVERFLOW); + } + + (*T)->tag = L->tag; + + // Ƶԭ + if(L->tag == Atom) { + (*T)->Node.atom = L->Node.atom; + + // Ʊͷͱβ + } else { + CopyGList(&((*T)->Node.ptr.hp), L->Node.ptr.hp); + CopyGList(&((*T)->Node.ptr.tp), L->Node.ptr.tp); + } + } + + return OK; +} + +/* + * + * + * عijȡ + */ +int GListLength(GList L) { + int count; + + for(count = 0; L != NULL; count++, L = L->Node.ptr.tp) { + } + + return count; +} + +/* + * 㷨5.5 + * + * + * + * ع + */ +int GListDepth(GList L) { + int max, deep; + GList p; + + // ձΪ1 + if(L == NULL) { + return 1; + } + + // ԭΪ0 + if(L->tag == Atom) { + return 0; + } + + // ݹӱ + for(max = 0, p = L; p != NULL; p = p->Node.ptr.tp) { + deep = GListDepth(p->Node.ptr.hp); + if(deep > max) { + max = deep; + } + } + + // ǿձǸԪȼһ + return max + 1; +} + +/* + * п + * + * жϹǷΪա + */ +Status GListEmpty(GList L) { + return L == NULL ? TRUE : FALSE; +} + +/* + * ͷ + */ +GList GetHead(GList L) { + GList p; + + // ձޱͷﲻܷNULLȻֲʧ˻Ƿ˿ձ + if(L == NULL) { + exit(ERROR); + } + + CopyGList(&p, L->Node.ptr.hp); + + return p; +} + +/* + * β + */ +GList GetTail(GList L) { + GList p; + + // ձޱβﲻܷNULLȻֲʧ˻Ƿ˿ձ + if(L == NULL) { + exit(ERROR); + } + + CopyGList(&p, L->Node.ptr.tp); + + return p; +} + +/* + * + * + * ԪeΪLĵһԪء + */ +Status InsertFirst(GList* L, GList e) { + GList g; + + if(L == NULL) { + return ERROR; + } + + g = (GList) malloc(sizeof(GLNode)); + if(g == NULL) { + exit(OVERFLOW); + } + + g->tag = List; + g->Node.ptr.hp = e; + g->Node.ptr.tp = *L; + *L = g; + + return OK; +} + +/* + * ɾ + * + * LĵһԪɾeء + */ +Status DeleteFirst(GList* L, GList* e) { + GList p; + + // ձ޷ɾ + if(L == NULL || *L == NULL) { + return ERROR; + } + + p = *L; + *L = (*L)->Node.ptr.tp; + + CopyGList(e, p->Node.ptr.hp); + + free(p); + + return OK; +} + +/* + * + * + * visitʹL + */ +void Traverse(GList L, void(Visit)(AtomType)) { + + if(L == NULL) { + return; + } + + if(L->tag == Atom) { + Visit(L->Node.atom); + } else { + Traverse(L->Node.ptr.hp, Visit); + Traverse(L->Node.ptr.tp, Visit); + } + +} + +/* + * ͼλ + * + * L + */ +void PrintGraph(GList L) { + Print(L, Head); + printf("\n"); +} + +/* + * ͼλڲʵ֣markͼλǡ + */ +static void Print(GList L, Mark mark) { + // LΪ + if(L == NULL) { + if(mark == Head) { + printf("("); + } + + printf(")"); + + // LΪʱ + } else { + // ԭӽ㣬ԭ + if(L->tag == Atom) { + printf("%c", L->Node.atom); + + // ӱ㣬ҪԱͷβֱ + } else { + if(mark == Head) { + printf("("); + } else { + printf(","); + } + + Print(L->Node.ptr.hp, Head); + Print(L->Node.ptr.tp, Tail); + } + } +} + +/* + * 㷨5.8 + * + * ǿմstrָ֣hsubΪһ','֮ǰӴstrΪһ','֮Ӵ + * + *ע + * 1.ַstrȷ޿հ׷ţstrѾȥš + * 2.ɺstrҲᷢ仯 + */ +static void sever(SString hstr, SString str) { + int i, k, n; + SString ch; + + n = StrLength(str); + + i = 0; // ַʱα + k = 0; // δ + + do { + ++i; + + // ȡstrһַ + SubString(ch, str, i, 1); + + if(ch[1] == '(') { + ++k; + } + + if(ch[1] == ')') { + --k; + } + } while(i < n && (ch[1] != ',' || k != 0)); + + // ڶ + if(i < n) { + SubString(hstr, str, 1, i - 1); + SubString(str, str, i + 1, n - i); + + // ֻһ + } else { + StrCopy(hstr, str); + ClearString(str); + } +} diff --git a/VisualC++/ExerciseBook/05.33.1/GList-HT.h b/VisualC++/ExerciseBook/05.33.1/GList-HT.h new file mode 100644 index 0000000..508b96f --- /dev/null +++ b/VisualC++/ExerciseBook/05.33.1/GList-HT.h @@ -0,0 +1,164 @@ +/*============================ + * ͷβ洢ʾ + * + * 㷨: 5.55.65.75.8 + =============================*/ + +#ifndef GLIST_HT_H +#define GLIST_HT_H + +#include +#include // ṩ mallocreallocfreeexit ԭ +#include "Status.h" //**01 **// +#include "SString.h" //**04 **// + +/* ԭԪ */ +typedef char AtomType; + +/* + * + * + * Atom-0ԭӽ + * List-1 + */ +typedef enum { Atom, List } ElemTag; + +/* ͷβ洢ʾͶ */ +typedef struct GLNode { + ElemTag tag; // ǣԭӽͱ + + // ԭӽͱϲ + union { + AtomType atom; // atomԭӽֵAtomTypeû + struct { + struct GLNode* hp; // ָͷ + struct GLNode* tp; // ָβ + } ptr; // ָ + } Node; +} GLNode; + +/* */ +typedef GLNode* GList; + +/* + * ͼλ + * + * HeadָԱͷ + * TailָԱβ + */ +typedef enum { Head, Tail } Mark; + + +/* + * ʼ + * + * ʼյĹΪ0Ϊ1 + * + *ע + * Ҫÿһȥſ + */ +Status InitGList(GList* L); + +/* + * 㷨5.7 + * + * + * + * ַSL + */ +Status CreateGList(GList* L, SString S); + +/* + * + * + * ͷŹռڴ档 + */ +Status DestroyGList(GList* L); + +/* + * 㷨5.6 + * + * + * + * ɹLƵõT + */ +Status CopyGList(GList* T, GList L); + +/* + * + * + * عijȡ + */ +int GListLength(GList L); + +/* + * 㷨5.5 + * + * + * + * ع + */ +int GListDepth(GList L); + +/* + * п + * + * жϹǷΪա + */ +Status GListEmpty(GList L); + +/* + * ͷ + */ +GList GetHead(GList L); + +/* + * β + */ +GList GetTail(GList L); + +/* + * + * + * ԪeΪLĵһԪء + */ +Status InsertFirst(GList* L, GList e); + +/* + * ɾ + * + * LĵһԪɾeء + */ +Status DeleteFirst(GList* L, GList* e); + +/* + * + * + * visitʹL + */ +void Traverse(GList L, void (Visit)(AtomType)); + +/* + * ͼλ + * + * L + */ +void PrintGraph(GList L); + +/* + * ͼλڲʵ֣markͼλǡ + */ +static void Print(GList L, Mark mark); + +/* + * 㷨5.8 + * + * ǿմstrָ֣hsubΪһ','֮ǰӴstrΪһ','֮Ӵ + * + *ע + * 1.ַstrȷ޿հ׷ţstrѾȥš + * 2.ɺstrҲᷢ仯 + */ +static void sever(SString hstr, SString str); + +#endif diff --git a/VisualC++/ExerciseBook/05.33.1/SString.c b/VisualC++/ExerciseBook/05.33.1/SString.c new file mode 100644 index 0000000..7a96fcf --- /dev/null +++ b/VisualC++/ExerciseBook/05.33.1/SString.c @@ -0,0 +1,195 @@ +/*============================= + * Ķ˳洢ʾ˳򴮣 + * + * 㷨: 4.14.24.34.5 + ==============================*/ + +#include "SString.h" //**04 **// + +/* + * ʼ + * + * һֵΪcharsĴT + * + *ע + * òСӼ + */ +Status StrAssign(SString T, const char* chars) { + int i, len; + + len = (int) strlen(chars); + + // chars + if(len > MAXSTRLEN) { + return ERROR; + } + + T[0] = len; + for(i = 1; i <= len; i++) { + T[i] = chars[i - 1]; + } + + return OK; +} + +/* + * + * + * Sա + */ +Status ClearString(SString S) { + // ֻҪΪ0Ϳ + S[0] = 0; + return OK; +} + +/* + * п + * + * жϴSǷЧݡ + * + * ֵ + * TRUE : SΪ + * FALSE: SΪ + */ +Status StrEmpty(SString S) { + return S[0] == 0 ? TRUE : FALSE; +} + +/* + * + * + * شSԪصĸ + * + *ע + * òСӼ + */ +int StrLength(SString S) { + return S[0]; +} + +/* + * 㷨4.3 + * + * Ӵ + * + * SubS[pos, pos+len-1] + * ֵָʾǷȡɹ + * + *ע + * òСӼ + */ +Status SubString(SString Sub, SString S, int pos, int len) { + int i; + + if(pos < 1 || pos > S[0] || len < 0 || pos + len - 1 > S[0]) { + return ERROR; + } + + // Ԫ + for(i = 1; i <= len; i++) { + Sub[i] = S[pos + i - 1]; + } + + // ȷ³ + Sub[0] = len; + + return OK; +} + +/* + * ɾ + * + * ɾS[pos, pos+len-1] + */ +Status StrDelete(SString S, int pos, int len) { + int i; + + if(pos < 1 || pos + len - 1 > S[0] || len < 0) { + return ERROR; + } + + // ɾijΪ0ǰ + if(len == 0) { + return OK; + } + + // ѺԪŲǰ棬ǵɾԪ + for(i = pos + len; i <= S[0]; i++) { + S[i - len] = S[i]; + } + + // ȼ + S[0] -= len; + + return OK; +} + +/* + * Ƚ + * + * ȽϴSʹTرȽϽ + * + *ע + * òСӼ + */ +int StrCompare(SString S, SString T) { + int i = 1; + + while(i <= S[0] && i <= T[0]) { + // ַͬʱȽС + if(S[i] != T[i]) { + return S[i] - T[i]; + } + + i++; + } + + return S[0] - T[0]; +} + +/* + * + * + * SƵT + */ +Status StrCopy(SString T, SString S) { + int i; + + // ͬϢһ + for(i = 0; i <= S[0]; i++) { + T[i] = S[i]; + } + + return OK; +} + +/* + * ַSеĿհףɴӡַո + * + *ע + * úڱġ + */ +Status ClearBlank(SString S) { + int i, j; + + // ǿմ + if(S[0] == 0) { + return ERROR; + } + + for(i = 1, j = 0; i <= S[0]; i++) { + // հףԹ + if(S[i] == ' ' || !isprint(S[i])) { + continue; + } + + j++; + + S[j] = S[i]; + } + + S[0] = j; + + return OK; +} diff --git a/VisualC++/ExerciseBook/05.33.1/SString.h b/VisualC++/ExerciseBook/05.33.1/SString.h new file mode 100644 index 0000000..0632f18 --- /dev/null +++ b/VisualC++/ExerciseBook/05.33.1/SString.h @@ -0,0 +1,117 @@ +/*============================= + * Ķ˳洢ʾ˳򴮣 + * + * 㷨: 4.14.24.34.5 + ==============================*/ + +#ifndef SSTRING_H +#define SSTRING_H + +#include +#include // ṩ strlen ԭ +#include // ṩ isprint ԭ +#include "Status.h" //**01 **// + +/* 궨 */ +#define MAXSTRLEN 255 // ˳򴮵󴮳 + +/* + * ˳洢Ͷ + * + * עЧԪشSString1ŵԪʼ洢 + * SString0ŵԪ洢䳤 + */ +typedef unsigned char SString[MAXSTRLEN + 1]; // 0ŵԪŴij + + +/* + * ʾ + * + * ѭ̲ĵдϰߣposָʾַλ()1ʼ + */ + + +/* + * ʼ + * + * һֵΪcharsĴT + * + *ע + * òСӼ + */ +Status StrAssign(SString T, const char* chars); + +/* + * + * + * Sա + */ +Status ClearString(SString S); + +/* + * п + * + * жϴSǷЧݡ + * + * ֵ + * TRUE : SΪ + * FALSE: SΪ + */ +Status StrEmpty(SString S); + +/* + * + * + * شSԪصĸ + * + *ע + * òСӼ + */ +int StrLength(SString S); + +/* + * 㷨4.3 + * + * Ӵ + * + * SubS[pos, pos+len-1] + * ֵָʾǷȡɹ + * + *ע + * òСӼ + */ +Status SubString(SString Sub, SString S, int pos, int len); + +/* + * ɾ + * + * ɾS[pos, pos+len-1] + */ +Status StrDelete(SString S, int pos, int len); + +/* + * Ƚ + * + * ȽϴSʹTرȽϽ + * + *ע + * òСӼ + */ +int StrCompare(SString S, SString T); + +/* + * + * + * SƵT + */ +Status StrCopy(SString T, SString S); + +/* + * ַSеĿհףɴӡַո + * + *ע + * úڱġ + */ +Status ClearBlank(SString S); + +#endif diff --git a/VisualC++/ExerciseBook/05.33.2/05.33.2.c b/VisualC++/ExerciseBook/05.33.2/05.33.2.c new file mode 100644 index 0000000..11aa567 --- /dev/null +++ b/VisualC++/ExerciseBook/05.33.2/05.33.2.c @@ -0,0 +1,48 @@ +#include +#include "SString.h" //**04 **// +#include "GList-E.h" //**05 ͹**// + +/* + * ԭڲΣչ洢ʾ + */ +void Algo_5_33_2(GList L, int d); + + +int main(int argc, char* argv[]) { + GList L; + char* s = "((),(e),(a,(b,c,d)))"; + SString S; + + printf(" L ...\n"); + StrAssign(S, s); + CreateGList(&L, S); + printf("L = "); + PrintGraph(L); + + Algo_5_33_2(L, 0); + + return 0; +} + + +/* + * ԭڲΣչ洢ʾ + */ +void Algo_5_33_2(GList L, int d) { + int i = d; // dֵΪ0 + + if(L == NULL) { + return; + } + + if(L->tag == Atom) { + printf("%c -> %d\n", L->Node.atom, i); + } + + + if(L->tag == List) { + Algo_5_33_2(L->Node.hp, i + 1); // ͷָָĻһ + } + + Algo_5_33_2(L->tp, i); +} diff --git a/VisualC++/ExerciseBook/05.33.2/05.33.2.vcxproj b/VisualC++/ExerciseBook/05.33.2/05.33.2.vcxproj new file mode 100644 index 0000000..4a7a6f2 --- /dev/null +++ b/VisualC++/ExerciseBook/05.33.2/05.33.2.vcxproj @@ -0,0 +1,78 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {D7EEED63-8BE4-4754-9657-D2276236E34A} + My05332 + + + + Application + true + MultiByte + + + Application + false + true + MultiByte + + + + + + + + + + + + + $(SolutionDir)\..\Status;$(IncludePath) + + + + Level3 + Disabled + + + true + $(SolutionDir)\..\Status\Status.lib;%(AdditionalDependencies) + Console + + + + + Level3 + MaxSpeed + true + true + + + true + true + true + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/05.33.2/05.33.2.vcxproj.filters b/VisualC++/ExerciseBook/05.33.2/05.33.2.vcxproj.filters new file mode 100644 index 0000000..e8be8db --- /dev/null +++ b/VisualC++/ExerciseBook/05.33.2/05.33.2.vcxproj.filters @@ -0,0 +1,36 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + 源文件 + + + 源文件 + + + 源文件 + + + + + 头文件 + + + 头文件 + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/05.33.2/05.33.2.vcxproj.user b/VisualC++/ExerciseBook/05.33.2/05.33.2.vcxproj.user new file mode 100644 index 0000000..ace9a86 --- /dev/null +++ b/VisualC++/ExerciseBook/05.33.2/05.33.2.vcxproj.user @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/05.33.2/GList-E.c b/VisualC++/ExerciseBook/05.33.2/GList-E.c new file mode 100644 index 0000000..3fc0ad9 --- /dev/null +++ b/VisualC++/ExerciseBook/05.33.2/GList-E.c @@ -0,0 +1,449 @@ +/*=========================== + * չ洢ʾ + ============================*/ + +#include "GList-E.h" //**05 ͹**// + +/* + * ʼ + * + * ʼյĹΪ0Ϊ1 + * + *ע + * Ҫÿһſ + */ +Status InitGList(GList* L) { + if(L == NULL) { + return ERROR; + } + + *L = (GList) malloc(sizeof(GLNode)); + if(!*L) { + exit(OVERFLOW); + } + + (*L)->tag = List; + (*L)->Node.hp = NULL; + (*L)->tp = NULL; + + return OK; +} + +/* + * + * + * ַSL + */ +Status CreateGList(GList* L, SString S) { + SString emp, hsub, sub, tmp; + + if(L == NULL) { + return ERROR; + } + + // ַSеĿհףɴӡַո + ClearBlank(S); + + if(StrEmpty(S)) { + return ERROR; + } + + // Ϊ˲ƻS + StrCopy(sub, S); + + /* + * ִеʱ + * ٴִеʱѾȥ + */ + sever(hsub, sub); + + *L = (GList) malloc(sizeof(GLNode)); + if(*L == NULL) { + exit(OVERFLOW); + } + + StrAssign(emp, "()"); + + if(!StrCompare(hsub, emp)) { + (*L)->tag = List; + (*L)->Node.hp = NULL; + } else { + if(StrLength(hsub) == 1) { + (*L)->tag = Atom; + (*L)->Node.atom = hsub[1]; + } else { + (*L)->tag = List; + + SubString(tmp, hsub, 2, StrLength(hsub) - 2); + + CreateGList(&((*L)->Node.hp), tmp); + } + } + + // ڶβ˳ݹ + if(StrEmpty(sub)) { + (*L)->tp = NULL; + } else { + // ݹβ + CreateGList(&((*L)->tp), sub); + } + + return OK; +} + +/* + * + * + * ͷŹռڴ档 + */ +Status DestroyGList(GList* L) { + GList head, tail; + + if(L == NULL || *L == NULL) { + return ERROR; + } + + // ӱ + if((*L)->tag == List) { + head = (*L)->Node.hp; // ͷ + tail = (*L)->tp; // β + + free(*L); + *L = NULL; + + // ݹ鴦ͷ + if(head != NULL) { + DestroyGList(&head); + } + + // ݹ鴦β + if(tail != NULL) { + DestroyGList(&tail); + } + + // ԭӽ + } else { + tail = (*L)->tp; // β + + free(*L); + *L = NULL; + + if(tail != NULL) { + DestroyGList(&tail); + } + } + + return OK; +} + +/* + * + * + * ɹLƵõT + */ +Status CopyGList(GList* T, GList L) { + + if(L == NULL) { + return ERROR; + } + + *T = (GList) malloc(sizeof(GLNode)); + if(*T == NULL) { + exit(OVERFLOW); + } + + // ԭ + if(L->tag == Atom) { + (*T)->tag = Atom; + (*T)->Node.atom = L->Node.atom; + + // ӱ + } else { + (*T)->tag = List; + + // Ʊͷ + if(L->Node.hp != NULL) { + CopyGList(&((*T)->Node.hp), L->Node.hp); + } else { + (*T)->Node.hp = NULL; + } + } + + // Ʊβ + if(L->tp != NULL) { + CopyGList(&((*T)->tp), L->tp); + } else { + (*T)->tp = NULL; + } + + return OK; +} + +/* + * + * + * عijȡ + */ +int GListLength(GList L) { + int count = 0; + GList p; + + // + if(L == NULL) { + return -1; + } + + p = L->Node.hp; + + while(p != NULL) { + ++count; + p = p->tp; + } + + return count; +} + +/* + * + * + * ع + */ +int GListDepth(GList L) { + int max, deep; + GList p; + + max = 0; + + // + if(L == NULL) { + return -1; + } + + // ձΪ1 + if(L->tag == List && !L->Node.hp) { + return 1; + } + + // ԭΪ0 + if(L->tag == Atom) { + return 0; + } + + // ݹӱ + for(p = L->Node.hp; p != NULL; p = p->tp) { + // pΪͷָӱ + deep = GListDepth(p); + if(deep > max) { + max = deep; + } + } + + return max + 1; +} + +/* + * п + * + * жϹǷΪա + */ +Status GListEmpty(GList L) { + // + if(L == NULL) { + return ERROR; + } + + if(L->tag == List && L->Node.hp == NULL && L->tp == NULL) { + return TRUE; + } else { + return ERROR; + } +} + +/* + * ͷ + */ +GList GetHead(GList L) { + GList p, q; + + // ڻΪձ޷ȡͷ + if(L == NULL || L->Node.hp == NULL) { + return NULL; + } + + q = L->Node.hp->tp; // ʱLıβϢ + L->Node.hp->tp = NULL; // ȥLıβ + + CopyGList(&p, L->Node.hp); // ƱͷϢαβ + + L->Node.hp->tp = q; // ָLıβϢ + + return p; +} + +/* + * β + */ +GList GetTail(GList L) { + GList p, q; + + // ڻΪձ޷ȡβ + if(L == NULL || L->Node.hp == NULL) { + return NULL; + } + + q = L->Node.hp; // ʱLıͷϢ + L->Node.hp = q->tp; // ժLıͷ + + CopyGList(&p, L); // ƱβϢαͷ + + q->tp = L->Node.hp; // ָLıͷϢ + L->Node.hp = q; + + return p; +} + +/* + * + * + * ԪeΪLĵһԪء + */ +Status InsertFirst(GList* L, GList e) { + + // + if(L == NULL || *L == NULL) { + return ERROR; + } + + if(e == NULL) { + return ERROR; + } + + e->tp = (*L)->Node.hp; + (*L)->Node.hp = e; + + return OK; +} + +/* + * ɾ + * + * LĵһԪɾeء + */ +Status DeleteFirst(GList* L, GList* e) { + GList p; + + // ڻΪձ޷ɾͷ + if(*L == NULL || (*L)->Node.hp == NULL) { + return ERROR; + } + + p = (*L)->Node.hp; + (*L)->Node.hp = p->tp; + p->tp = NULL; + + *e = p; + + return OK; +} + +/* + * + * + * visitʹL + */ +void Traverse(GList L, void(Visit)(AtomType)) { + if(L == NULL) { + return; + } + + if(L->tag == List) { + Traverse(L->Node.hp, Visit); + } else { + Visit(L->Node.atom); + } + + Traverse(L->tp, Visit); +} + +/* + * ͼλ + * + * L + */ +void PrintGraph(GList L) { + Print(L); + printf("\n"); +} + +/* + * ͼλڲʵ֡ + */ +static void Print(GList L) { + if(L == NULL) { + return; + } + + // + if(L->tag == List) { + printf("("); + + if(L->Node.hp) { + Print(L->Node.hp); + } + + if(L->tp) { + printf("),"); + Print(L->tp); + } else { + printf(")"); + } + + // ԭӽ + } else { + printf("%c", L->Node.atom); + if(L->tp) { + printf(","); + Print(L->tp); + } + } +} + +/* + * ǿմstrָ֣hsubΪһ','֮ǰӴstrΪһ','֮Ӵ + * + *ע + * 1.ַstrȷ޿հ׷ţ + * strſȥҲδȥ + * 2.ɺstrҲᷢ仯 + */ +static void sever(SString hstr, SString str) { + int i, k, n; + SString ch; + + n = StrLength(str); + + i = 0; // ַʱα + k = 0; // δ + + do { + ++i; + + // ȡstrһַ + SubString(ch, str, i, 1); + + if(ch[1] == '(') { + ++k; + } + if(ch[1] == ')') { + --k; + } + } while(i < n && (ch[1] != ',' || k != 0)); + + if(i < n) { + SubString(hstr, str, 1, i - 1); + SubString(str, str, i + 1, n - i); + } else { + StrCopy(hstr, str); + ClearString(str); + } +} diff --git a/VisualC++/ExerciseBook/05.33.2/GList-E.h b/VisualC++/ExerciseBook/05.33.2/GList-E.h new file mode 100644 index 0000000..fa9af82 --- /dev/null +++ b/VisualC++/ExerciseBook/05.33.2/GList-E.h @@ -0,0 +1,146 @@ +/*=========================== + * չ洢ʾ + ============================*/ + +#ifndef GLIST_E_H +#define GLIST_E_H + +#include +#include // ṩ mallocreallocfreeexit ԭ +#include "Status.h" //**01 **// +#include "SString.h" //**04 **// + +/* ԭԪ */ +typedef char AtomType; //ԭ + +/* + * + * + * Atom-0ԭӽ + * List-1 + */ +typedef enum { Atom, List } ElemTag; + +/* չ洢ʾͶ */ +typedef struct GLNode { + ElemTag tag; // ǣԭӽͱ + + // ԭӽͱϲ + union + { + AtomType atom; // atomԭӽֵAtomTypeû + struct GLNode* hp; // ָͷ + } Node; + struct GLNode* tp; // ָβ +} GLNode; + +/* */ +typedef GLNode* GList; + + +/* + * ʼ + * + * ʼյĹΪ0Ϊ1 + * + *ע + * Ҫÿһſ + */ +Status InitGList(GList* L); + +/* + * + * + * ַSL + */ +Status CreateGList(GList* L, SString S); + +/* + * + * + * ͷŹռڴ档 + */ +Status DestroyGList(GList* L); + +/* + * + * + * ɹLƵõT + */ +Status CopyGList(GList* T, GList L); + +/* + * + * + * عijȡ + */ +int GListLength(GList L); + +/* + * + * + * ع + */ +int GListDepth(GList L); + +/* + * п + * + * жϹǷΪա + */ +Status GListEmpty(GList L); + +/* + * ͷ + */ +GList GetHead(GList L); + +/* + * β + */ +GList GetTail(GList L); + +/* + * + * + * ԪeΪLĵһԪء + */ +Status InsertFirst(GList* L, GList e); + +/* + * ɾ + * + * LĵһԪɾeء + */ +Status DeleteFirst(GList* L, GList* e); + +/* + * + * + * visitʹL + */ +void Traverse(GList L, void(Visit)(AtomType)); + +/* + * ͼλ + * + * L + */ +void PrintGraph(GList L); + +/* + * ͼλڲʵ֡ + */ +static void Print(GList L); + +/* + * ǿմstrָ֣hsubΪһ','֮ǰӴstrΪһ','֮Ӵ + * + *ע + * 1.ַstrȷ޿հ׷ţ + * strſȥҲδȥ + * 2.ɺstrҲᷢ仯 + */ +static void sever(SString hstr, SString str); + +#endif diff --git a/VisualC++/ExerciseBook/05.33.2/SString.c b/VisualC++/ExerciseBook/05.33.2/SString.c new file mode 100644 index 0000000..7a96fcf --- /dev/null +++ b/VisualC++/ExerciseBook/05.33.2/SString.c @@ -0,0 +1,195 @@ +/*============================= + * Ķ˳洢ʾ˳򴮣 + * + * 㷨: 4.14.24.34.5 + ==============================*/ + +#include "SString.h" //**04 **// + +/* + * ʼ + * + * һֵΪcharsĴT + * + *ע + * òСӼ + */ +Status StrAssign(SString T, const char* chars) { + int i, len; + + len = (int) strlen(chars); + + // chars + if(len > MAXSTRLEN) { + return ERROR; + } + + T[0] = len; + for(i = 1; i <= len; i++) { + T[i] = chars[i - 1]; + } + + return OK; +} + +/* + * + * + * Sա + */ +Status ClearString(SString S) { + // ֻҪΪ0Ϳ + S[0] = 0; + return OK; +} + +/* + * п + * + * жϴSǷЧݡ + * + * ֵ + * TRUE : SΪ + * FALSE: SΪ + */ +Status StrEmpty(SString S) { + return S[0] == 0 ? TRUE : FALSE; +} + +/* + * + * + * شSԪصĸ + * + *ע + * òСӼ + */ +int StrLength(SString S) { + return S[0]; +} + +/* + * 㷨4.3 + * + * Ӵ + * + * SubS[pos, pos+len-1] + * ֵָʾǷȡɹ + * + *ע + * òСӼ + */ +Status SubString(SString Sub, SString S, int pos, int len) { + int i; + + if(pos < 1 || pos > S[0] || len < 0 || pos + len - 1 > S[0]) { + return ERROR; + } + + // Ԫ + for(i = 1; i <= len; i++) { + Sub[i] = S[pos + i - 1]; + } + + // ȷ³ + Sub[0] = len; + + return OK; +} + +/* + * ɾ + * + * ɾS[pos, pos+len-1] + */ +Status StrDelete(SString S, int pos, int len) { + int i; + + if(pos < 1 || pos + len - 1 > S[0] || len < 0) { + return ERROR; + } + + // ɾijΪ0ǰ + if(len == 0) { + return OK; + } + + // ѺԪŲǰ棬ǵɾԪ + for(i = pos + len; i <= S[0]; i++) { + S[i - len] = S[i]; + } + + // ȼ + S[0] -= len; + + return OK; +} + +/* + * Ƚ + * + * ȽϴSʹTرȽϽ + * + *ע + * òСӼ + */ +int StrCompare(SString S, SString T) { + int i = 1; + + while(i <= S[0] && i <= T[0]) { + // ַͬʱȽС + if(S[i] != T[i]) { + return S[i] - T[i]; + } + + i++; + } + + return S[0] - T[0]; +} + +/* + * + * + * SƵT + */ +Status StrCopy(SString T, SString S) { + int i; + + // ͬϢһ + for(i = 0; i <= S[0]; i++) { + T[i] = S[i]; + } + + return OK; +} + +/* + * ַSеĿհףɴӡַո + * + *ע + * úڱġ + */ +Status ClearBlank(SString S) { + int i, j; + + // ǿմ + if(S[0] == 0) { + return ERROR; + } + + for(i = 1, j = 0; i <= S[0]; i++) { + // հףԹ + if(S[i] == ' ' || !isprint(S[i])) { + continue; + } + + j++; + + S[j] = S[i]; + } + + S[0] = j; + + return OK; +} diff --git a/VisualC++/ExerciseBook/05.33.2/SString.h b/VisualC++/ExerciseBook/05.33.2/SString.h new file mode 100644 index 0000000..0632f18 --- /dev/null +++ b/VisualC++/ExerciseBook/05.33.2/SString.h @@ -0,0 +1,117 @@ +/*============================= + * Ķ˳洢ʾ˳򴮣 + * + * 㷨: 4.14.24.34.5 + ==============================*/ + +#ifndef SSTRING_H +#define SSTRING_H + +#include +#include // ṩ strlen ԭ +#include // ṩ isprint ԭ +#include "Status.h" //**01 **// + +/* 궨 */ +#define MAXSTRLEN 255 // ˳򴮵󴮳 + +/* + * ˳洢Ͷ + * + * עЧԪشSString1ŵԪʼ洢 + * SString0ŵԪ洢䳤 + */ +typedef unsigned char SString[MAXSTRLEN + 1]; // 0ŵԪŴij + + +/* + * ʾ + * + * ѭ̲ĵдϰߣposָʾַλ()1ʼ + */ + + +/* + * ʼ + * + * һֵΪcharsĴT + * + *ע + * òСӼ + */ +Status StrAssign(SString T, const char* chars); + +/* + * + * + * Sա + */ +Status ClearString(SString S); + +/* + * п + * + * жϴSǷЧݡ + * + * ֵ + * TRUE : SΪ + * FALSE: SΪ + */ +Status StrEmpty(SString S); + +/* + * + * + * شSԪصĸ + * + *ע + * òСӼ + */ +int StrLength(SString S); + +/* + * 㷨4.3 + * + * Ӵ + * + * SubS[pos, pos+len-1] + * ֵָʾǷȡɹ + * + *ע + * òСӼ + */ +Status SubString(SString Sub, SString S, int pos, int len); + +/* + * ɾ + * + * ɾS[pos, pos+len-1] + */ +Status StrDelete(SString S, int pos, int len); + +/* + * Ƚ + * + * ȽϴSʹTرȽϽ + * + *ע + * òСӼ + */ +int StrCompare(SString S, SString T); + +/* + * + * + * SƵT + */ +Status StrCopy(SString T, SString S); + +/* + * ַSеĿհףɴӡַո + * + *ע + * úڱġ + */ +Status ClearBlank(SString S); + +#endif diff --git a/VisualC++/ExerciseBook/05.34.1/05.34.1.c b/VisualC++/ExerciseBook/05.34.1/05.34.1.c new file mode 100644 index 0000000..b3a2013 --- /dev/null +++ b/VisualC++/ExerciseBook/05.34.1/05.34.1.c @@ -0,0 +1,62 @@ +#include +#include "Status.h" //**01 **// +#include "SString.h" //**04 **// +#include "GList-HT.h" //**05 ͹**// + +/* + * ùͷβ洢ʾ + */ +Status Algo_5_34_1(GList* L); + + +int main(int argc, char* argv[]) { + GList L; + char* s = "(a,((b,c),()),(((d),e),f))"; + SString S; + + printf(" L ...\n"); + StrAssign(S, s); + CreateGList(&L, S); + printf("L = "); + PrintGraph(L); + + printf("ù...\n"); + Algo_5_34_1(&L); + printf("L = "); + PrintGraph(L); + + return 0; +} + + +/* + * ùͷβ洢ʾ + */ +Status Algo_5_34_1(GList* L) { + GList head, tail; + + if(L == NULL || *L == NULL) { + return ERROR; + } + + // Ӻǰﵽ + head = *L; + tail = (*L)->Node.ptr.tp; + + // Աͷ + if(head->Node.ptr.hp != NULL && head->Node.ptr.hp->tag == List) { + Algo_5_34_1(&(head->Node.ptr.hp)); + } + + // Աβ + if(tail != NULL) { + Algo_5_34_1(&((*L)->Node.ptr.tp)); + + // ͷβ + *L = (*L)->Node.ptr.tp; + tail->Node.ptr.tp = head; + head->Node.ptr.tp = NULL; + } + + return OK; +} diff --git a/VisualC++/ExerciseBook/05.34.1/05.34.1.vcxproj b/VisualC++/ExerciseBook/05.34.1/05.34.1.vcxproj new file mode 100644 index 0000000..f564b02 --- /dev/null +++ b/VisualC++/ExerciseBook/05.34.1/05.34.1.vcxproj @@ -0,0 +1,78 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {0E9C5F8C-656A-4535-A61F-53E62C8F005A} + My05341 + + + + Application + true + MultiByte + + + Application + false + true + MultiByte + + + + + + + + + + + + + $(SolutionDir)\..\Status;$(IncludePath) + + + + Level3 + Disabled + + + true + $(SolutionDir)\..\Status\Status.lib;%(AdditionalDependencies) + Console + + + + + Level3 + MaxSpeed + true + true + + + true + true + true + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/05.34.1/05.34.1.vcxproj.filters b/VisualC++/ExerciseBook/05.34.1/05.34.1.vcxproj.filters new file mode 100644 index 0000000..f0dbd95 --- /dev/null +++ b/VisualC++/ExerciseBook/05.34.1/05.34.1.vcxproj.filters @@ -0,0 +1,36 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + 源文件 + + + 源文件 + + + 源文件 + + + + + 头文件 + + + 头文件 + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/05.34.1/05.34.1.vcxproj.user b/VisualC++/ExerciseBook/05.34.1/05.34.1.vcxproj.user new file mode 100644 index 0000000..ace9a86 --- /dev/null +++ b/VisualC++/ExerciseBook/05.34.1/05.34.1.vcxproj.user @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/05.34.1/GList-HT.c b/VisualC++/ExerciseBook/05.34.1/GList-HT.c new file mode 100644 index 0000000..bad30df --- /dev/null +++ b/VisualC++/ExerciseBook/05.34.1/GList-HT.c @@ -0,0 +1,418 @@ +/*============================ + * ͷβ洢ʾ + * + * 㷨: 5.55.65.75.8 + =============================*/ + +#include "GList-HT.h" //**05 ͹**// + +/* + * ʼ + * + * ʼյĹΪ0Ϊ1 + * + *ע + * Ҫÿһȥſ + */ +Status InitGList(GList* L) { + if(L == NULL) { + return ERROR; + } + + *L = NULL; + + return OK; +} + +/* + * 㷨5.7 + * + * + * + * ַSL + */ +Status CreateGList(GList* L, SString S) { + SString emp; // չַ + SString hsub, sub; + GList p, q; + + if(L == NULL) { + return ERROR; + } + + // ַSеĿհףɴӡַո + ClearBlank(S); + + if(StrEmpty(S)) { + return ERROR; + } + + StrAssign(emp, "()"); + + /* + * 봮Ϊ()ҪյĹ + * + *ע + * ̲Ĵġ + * StrCompareķֵָʾַĴСָʾַǷȡ + * S()ȣֵӦ0 + */ + if(!StrCompare(S, emp)) { + *L = NULL; + } else { + *L = (GList) malloc(sizeof(GLNode)); + if(*L == NULL) { + exit(OVERFLOW); + } + + // ԭ + if(StrLength(S) == 1) { + (*L)->tag = Atom; + (*L)->Node.atom = S[1]; + } else { + (*L)->tag = List; + + p = *L; + + // ȥ + SubString(sub, S, 2, StrLength(S) - 2); + + // ظnӱ + do { + // subзͷhsubɺsubҲᷢ仯 + sever(hsub, sub); + + // ݹ鴴 + CreateGList(&(p->Node.ptr.hp), hsub); + + q = p; + + // βΪգҪβ + if(!StrEmpty(sub)) { + p = (GList) malloc(sizeof(GLNode)); + if(p == NULL) { + exit(OVERFLOW); + } + + p->tag = List; + + q->Node.ptr.tp = p; + } + } while(!StrEmpty(sub)); + + q->Node.ptr.tp = NULL; + } + } + + return OK; +} + +/* + * + * + * ͷŹռڴ档 + */ +Status DestroyGList(GList* L) { + GList head, tail; + + if(L == NULL || *L == NULL) { + return ERROR; + } + + // ɾԭӽ + if((*L)->tag == Atom) { + free(*L); + *L = NULL; + + // ɾӱ + } else { + head = (*L)->Node.ptr.hp; + tail = (*L)->Node.ptr.tp; + free(*L); + *L = NULL; + DestroyGList(&head); + DestroyGList(&tail); + } + + return OK; +} + +/* + * 㷨5.6 + * + * + * + * ɹLƵõT + */ +Status CopyGList(GList* T, GList L) { + if(T == NULL) { + return ERROR; + } + + if(L == NULL) { + *T = NULL; + } else { + // ½ + *T = (GList) malloc(sizeof(GLNode)); + if(*T == NULL) { + exit(OVERFLOW); + } + + (*T)->tag = L->tag; + + // Ƶԭ + if(L->tag == Atom) { + (*T)->Node.atom = L->Node.atom; + + // Ʊͷͱβ + } else { + CopyGList(&((*T)->Node.ptr.hp), L->Node.ptr.hp); + CopyGList(&((*T)->Node.ptr.tp), L->Node.ptr.tp); + } + } + + return OK; +} + +/* + * + * + * عijȡ + */ +int GListLength(GList L) { + int count; + + for(count = 0; L != NULL; count++, L = L->Node.ptr.tp) { + } + + return count; +} + +/* + * 㷨5.5 + * + * + * + * ع + */ +int GListDepth(GList L) { + int max, deep; + GList p; + + // ձΪ1 + if(L == NULL) { + return 1; + } + + // ԭΪ0 + if(L->tag == Atom) { + return 0; + } + + // ݹӱ + for(max = 0, p = L; p != NULL; p = p->Node.ptr.tp) { + deep = GListDepth(p->Node.ptr.hp); + if(deep > max) { + max = deep; + } + } + + // ǿձǸԪȼһ + return max + 1; +} + +/* + * п + * + * жϹǷΪա + */ +Status GListEmpty(GList L) { + return L == NULL ? TRUE : FALSE; +} + +/* + * ͷ + */ +GList GetHead(GList L) { + GList p; + + // ձޱͷﲻܷNULLȻֲʧ˻Ƿ˿ձ + if(L == NULL) { + exit(ERROR); + } + + CopyGList(&p, L->Node.ptr.hp); + + return p; +} + +/* + * β + */ +GList GetTail(GList L) { + GList p; + + // ձޱβﲻܷNULLȻֲʧ˻Ƿ˿ձ + if(L == NULL) { + exit(ERROR); + } + + CopyGList(&p, L->Node.ptr.tp); + + return p; +} + +/* + * + * + * ԪeΪLĵһԪء + */ +Status InsertFirst(GList* L, GList e) { + GList g; + + if(L == NULL) { + return ERROR; + } + + g = (GList) malloc(sizeof(GLNode)); + if(g == NULL) { + exit(OVERFLOW); + } + + g->tag = List; + g->Node.ptr.hp = e; + g->Node.ptr.tp = *L; + *L = g; + + return OK; +} + +/* + * ɾ + * + * LĵһԪɾeء + */ +Status DeleteFirst(GList* L, GList* e) { + GList p; + + // ձ޷ɾ + if(L == NULL || *L == NULL) { + return ERROR; + } + + p = *L; + *L = (*L)->Node.ptr.tp; + + CopyGList(e, p->Node.ptr.hp); + + free(p); + + return OK; +} + +/* + * + * + * visitʹL + */ +void Traverse(GList L, void(Visit)(AtomType)) { + + if(L == NULL) { + return; + } + + if(L->tag == Atom) { + Visit(L->Node.atom); + } else { + Traverse(L->Node.ptr.hp, Visit); + Traverse(L->Node.ptr.tp, Visit); + } + +} + +/* + * ͼλ + * + * L + */ +void PrintGraph(GList L) { + Print(L, Head); + printf("\n"); +} + +/* + * ͼλڲʵ֣markͼλǡ + */ +static void Print(GList L, Mark mark) { + // LΪ + if(L == NULL) { + if(mark == Head) { + printf("("); + } + + printf(")"); + + // LΪʱ + } else { + // ԭӽ㣬ԭ + if(L->tag == Atom) { + printf("%c", L->Node.atom); + + // ӱ㣬ҪԱͷβֱ + } else { + if(mark == Head) { + printf("("); + } else { + printf(","); + } + + Print(L->Node.ptr.hp, Head); + Print(L->Node.ptr.tp, Tail); + } + } +} + +/* + * 㷨5.8 + * + * ǿմstrָ֣hsubΪһ','֮ǰӴstrΪһ','֮Ӵ + * + *ע + * 1.ַstrȷ޿հ׷ţstrѾȥš + * 2.ɺstrҲᷢ仯 + */ +static void sever(SString hstr, SString str) { + int i, k, n; + SString ch; + + n = StrLength(str); + + i = 0; // ַʱα + k = 0; // δ + + do { + ++i; + + // ȡstrһַ + SubString(ch, str, i, 1); + + if(ch[1] == '(') { + ++k; + } + + if(ch[1] == ')') { + --k; + } + } while(i < n && (ch[1] != ',' || k != 0)); + + // ڶ + if(i < n) { + SubString(hstr, str, 1, i - 1); + SubString(str, str, i + 1, n - i); + + // ֻһ + } else { + StrCopy(hstr, str); + ClearString(str); + } +} diff --git a/VisualC++/ExerciseBook/05.34.1/GList-HT.h b/VisualC++/ExerciseBook/05.34.1/GList-HT.h new file mode 100644 index 0000000..508b96f --- /dev/null +++ b/VisualC++/ExerciseBook/05.34.1/GList-HT.h @@ -0,0 +1,164 @@ +/*============================ + * ͷβ洢ʾ + * + * 㷨: 5.55.65.75.8 + =============================*/ + +#ifndef GLIST_HT_H +#define GLIST_HT_H + +#include +#include // ṩ mallocreallocfreeexit ԭ +#include "Status.h" //**01 **// +#include "SString.h" //**04 **// + +/* ԭԪ */ +typedef char AtomType; + +/* + * + * + * Atom-0ԭӽ + * List-1 + */ +typedef enum { Atom, List } ElemTag; + +/* ͷβ洢ʾͶ */ +typedef struct GLNode { + ElemTag tag; // ǣԭӽͱ + + // ԭӽͱϲ + union { + AtomType atom; // atomԭӽֵAtomTypeû + struct { + struct GLNode* hp; // ָͷ + struct GLNode* tp; // ָβ + } ptr; // ָ + } Node; +} GLNode; + +/* */ +typedef GLNode* GList; + +/* + * ͼλ + * + * HeadָԱͷ + * TailָԱβ + */ +typedef enum { Head, Tail } Mark; + + +/* + * ʼ + * + * ʼյĹΪ0Ϊ1 + * + *ע + * Ҫÿһȥſ + */ +Status InitGList(GList* L); + +/* + * 㷨5.7 + * + * + * + * ַSL + */ +Status CreateGList(GList* L, SString S); + +/* + * + * + * ͷŹռڴ档 + */ +Status DestroyGList(GList* L); + +/* + * 㷨5.6 + * + * + * + * ɹLƵõT + */ +Status CopyGList(GList* T, GList L); + +/* + * + * + * عijȡ + */ +int GListLength(GList L); + +/* + * 㷨5.5 + * + * + * + * ع + */ +int GListDepth(GList L); + +/* + * п + * + * жϹǷΪա + */ +Status GListEmpty(GList L); + +/* + * ͷ + */ +GList GetHead(GList L); + +/* + * β + */ +GList GetTail(GList L); + +/* + * + * + * ԪeΪLĵһԪء + */ +Status InsertFirst(GList* L, GList e); + +/* + * ɾ + * + * LĵһԪɾeء + */ +Status DeleteFirst(GList* L, GList* e); + +/* + * + * + * visitʹL + */ +void Traverse(GList L, void (Visit)(AtomType)); + +/* + * ͼλ + * + * L + */ +void PrintGraph(GList L); + +/* + * ͼλڲʵ֣markͼλǡ + */ +static void Print(GList L, Mark mark); + +/* + * 㷨5.8 + * + * ǿմstrָ֣hsubΪһ','֮ǰӴstrΪһ','֮Ӵ + * + *ע + * 1.ַstrȷ޿հ׷ţstrѾȥš + * 2.ɺstrҲᷢ仯 + */ +static void sever(SString hstr, SString str); + +#endif diff --git a/VisualC++/ExerciseBook/05.34.1/SString.c b/VisualC++/ExerciseBook/05.34.1/SString.c new file mode 100644 index 0000000..7a96fcf --- /dev/null +++ b/VisualC++/ExerciseBook/05.34.1/SString.c @@ -0,0 +1,195 @@ +/*============================= + * Ķ˳洢ʾ˳򴮣 + * + * 㷨: 4.14.24.34.5 + ==============================*/ + +#include "SString.h" //**04 **// + +/* + * ʼ + * + * һֵΪcharsĴT + * + *ע + * òСӼ + */ +Status StrAssign(SString T, const char* chars) { + int i, len; + + len = (int) strlen(chars); + + // chars + if(len > MAXSTRLEN) { + return ERROR; + } + + T[0] = len; + for(i = 1; i <= len; i++) { + T[i] = chars[i - 1]; + } + + return OK; +} + +/* + * + * + * Sա + */ +Status ClearString(SString S) { + // ֻҪΪ0Ϳ + S[0] = 0; + return OK; +} + +/* + * п + * + * жϴSǷЧݡ + * + * ֵ + * TRUE : SΪ + * FALSE: SΪ + */ +Status StrEmpty(SString S) { + return S[0] == 0 ? TRUE : FALSE; +} + +/* + * + * + * شSԪصĸ + * + *ע + * òСӼ + */ +int StrLength(SString S) { + return S[0]; +} + +/* + * 㷨4.3 + * + * Ӵ + * + * SubS[pos, pos+len-1] + * ֵָʾǷȡɹ + * + *ע + * òСӼ + */ +Status SubString(SString Sub, SString S, int pos, int len) { + int i; + + if(pos < 1 || pos > S[0] || len < 0 || pos + len - 1 > S[0]) { + return ERROR; + } + + // Ԫ + for(i = 1; i <= len; i++) { + Sub[i] = S[pos + i - 1]; + } + + // ȷ³ + Sub[0] = len; + + return OK; +} + +/* + * ɾ + * + * ɾS[pos, pos+len-1] + */ +Status StrDelete(SString S, int pos, int len) { + int i; + + if(pos < 1 || pos + len - 1 > S[0] || len < 0) { + return ERROR; + } + + // ɾijΪ0ǰ + if(len == 0) { + return OK; + } + + // ѺԪŲǰ棬ǵɾԪ + for(i = pos + len; i <= S[0]; i++) { + S[i - len] = S[i]; + } + + // ȼ + S[0] -= len; + + return OK; +} + +/* + * Ƚ + * + * ȽϴSʹTرȽϽ + * + *ע + * òСӼ + */ +int StrCompare(SString S, SString T) { + int i = 1; + + while(i <= S[0] && i <= T[0]) { + // ַͬʱȽС + if(S[i] != T[i]) { + return S[i] - T[i]; + } + + i++; + } + + return S[0] - T[0]; +} + +/* + * + * + * SƵT + */ +Status StrCopy(SString T, SString S) { + int i; + + // ͬϢһ + for(i = 0; i <= S[0]; i++) { + T[i] = S[i]; + } + + return OK; +} + +/* + * ַSеĿհףɴӡַո + * + *ע + * úڱġ + */ +Status ClearBlank(SString S) { + int i, j; + + // ǿմ + if(S[0] == 0) { + return ERROR; + } + + for(i = 1, j = 0; i <= S[0]; i++) { + // հףԹ + if(S[i] == ' ' || !isprint(S[i])) { + continue; + } + + j++; + + S[j] = S[i]; + } + + S[0] = j; + + return OK; +} diff --git a/VisualC++/ExerciseBook/05.34.1/SString.h b/VisualC++/ExerciseBook/05.34.1/SString.h new file mode 100644 index 0000000..0632f18 --- /dev/null +++ b/VisualC++/ExerciseBook/05.34.1/SString.h @@ -0,0 +1,117 @@ +/*============================= + * Ķ˳洢ʾ˳򴮣 + * + * 㷨: 4.14.24.34.5 + ==============================*/ + +#ifndef SSTRING_H +#define SSTRING_H + +#include +#include // ṩ strlen ԭ +#include // ṩ isprint ԭ +#include "Status.h" //**01 **// + +/* 궨 */ +#define MAXSTRLEN 255 // ˳򴮵󴮳 + +/* + * ˳洢Ͷ + * + * עЧԪشSString1ŵԪʼ洢 + * SString0ŵԪ洢䳤 + */ +typedef unsigned char SString[MAXSTRLEN + 1]; // 0ŵԪŴij + + +/* + * ʾ + * + * ѭ̲ĵдϰߣposָʾַλ()1ʼ + */ + + +/* + * ʼ + * + * һֵΪcharsĴT + * + *ע + * òСӼ + */ +Status StrAssign(SString T, const char* chars); + +/* + * + * + * Sա + */ +Status ClearString(SString S); + +/* + * п + * + * жϴSǷЧݡ + * + * ֵ + * TRUE : SΪ + * FALSE: SΪ + */ +Status StrEmpty(SString S); + +/* + * + * + * شSԪصĸ + * + *ע + * òСӼ + */ +int StrLength(SString S); + +/* + * 㷨4.3 + * + * Ӵ + * + * SubS[pos, pos+len-1] + * ֵָʾǷȡɹ + * + *ע + * òСӼ + */ +Status SubString(SString Sub, SString S, int pos, int len); + +/* + * ɾ + * + * ɾS[pos, pos+len-1] + */ +Status StrDelete(SString S, int pos, int len); + +/* + * Ƚ + * + * ȽϴSʹTرȽϽ + * + *ע + * òСӼ + */ +int StrCompare(SString S, SString T); + +/* + * + * + * SƵT + */ +Status StrCopy(SString T, SString S); + +/* + * ַSеĿհףɴӡַո + * + *ע + * úڱġ + */ +Status ClearBlank(SString S); + +#endif diff --git a/VisualC++/ExerciseBook/05.34.2/05.34.2.c b/VisualC++/ExerciseBook/05.34.2/05.34.2.c new file mode 100644 index 0000000..c72e80d --- /dev/null +++ b/VisualC++/ExerciseBook/05.34.2/05.34.2.c @@ -0,0 +1,61 @@ +#include +#include "Status.h" //**01 **// +#include "SString.h" //**04 **// +#include "GList-E.h" //**05 ͹**// + +/* + * ùչ洢ʾ + */ +Status Algo_5_34_2(GList* L); + + +int main(int argc, char* argv[]) { + GList L; + char* s = "(a,((b,c),()),(((d),e),f))"; + SString S; + + printf(" L ...\n"); + StrAssign(S, s); + CreateGList(&L, S); + printf("L = "); + PrintGraph(L); + + printf("ù...\n"); + Algo_5_34_2(&L); + printf("L = "); + PrintGraph(L); + + return 0; +} + + +/* + * ùչ洢ʾ + */ +Status Algo_5_34_2(GList* L) { + GList head, tail; + + if(L == NULL || *L == NULL) { + return ERROR; + } + + // Ӻǰﵽ + head = *L; + tail = (*L)->tp; + + if(head->tag == List && head->Node.hp != NULL) { + Algo_5_34_2(&(head->Node.hp)); + } + + // Աβ + if(tail != NULL) { + Algo_5_34_2(&((*L)->tp)); + + // ͷβ + *L = (*L)->tp; + tail->tp = head; + head->tp = NULL; + } + + return OK; +} diff --git a/VisualC++/ExerciseBook/05.34.2/05.34.2.vcxproj b/VisualC++/ExerciseBook/05.34.2/05.34.2.vcxproj new file mode 100644 index 0000000..f7738af --- /dev/null +++ b/VisualC++/ExerciseBook/05.34.2/05.34.2.vcxproj @@ -0,0 +1,78 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {D367E1DB-CCB7-4911-8805-1C25A41543FD} + My05342 + + + + Application + true + MultiByte + + + Application + false + true + MultiByte + + + + + + + + + + + + + $(SolutionDir)\..\Status;$(IncludePath) + + + + Level3 + Disabled + + + true + $(SolutionDir)\..\Status\Status.lib;%(AdditionalDependencies) + Console + + + + + Level3 + MaxSpeed + true + true + + + true + true + true + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/05.34.2/05.34.2.vcxproj.filters b/VisualC++/ExerciseBook/05.34.2/05.34.2.vcxproj.filters new file mode 100644 index 0000000..faa4912 --- /dev/null +++ b/VisualC++/ExerciseBook/05.34.2/05.34.2.vcxproj.filters @@ -0,0 +1,36 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + 源文件 + + + 源文件 + + + 源文件 + + + + + 头文件 + + + 头文件 + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/05.34.2/05.34.2.vcxproj.user b/VisualC++/ExerciseBook/05.34.2/05.34.2.vcxproj.user new file mode 100644 index 0000000..ace9a86 --- /dev/null +++ b/VisualC++/ExerciseBook/05.34.2/05.34.2.vcxproj.user @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/05.34.2/GList-E.c b/VisualC++/ExerciseBook/05.34.2/GList-E.c new file mode 100644 index 0000000..3fc0ad9 --- /dev/null +++ b/VisualC++/ExerciseBook/05.34.2/GList-E.c @@ -0,0 +1,449 @@ +/*=========================== + * չ洢ʾ + ============================*/ + +#include "GList-E.h" //**05 ͹**// + +/* + * ʼ + * + * ʼյĹΪ0Ϊ1 + * + *ע + * Ҫÿһſ + */ +Status InitGList(GList* L) { + if(L == NULL) { + return ERROR; + } + + *L = (GList) malloc(sizeof(GLNode)); + if(!*L) { + exit(OVERFLOW); + } + + (*L)->tag = List; + (*L)->Node.hp = NULL; + (*L)->tp = NULL; + + return OK; +} + +/* + * + * + * ַSL + */ +Status CreateGList(GList* L, SString S) { + SString emp, hsub, sub, tmp; + + if(L == NULL) { + return ERROR; + } + + // ַSеĿհףɴӡַո + ClearBlank(S); + + if(StrEmpty(S)) { + return ERROR; + } + + // Ϊ˲ƻS + StrCopy(sub, S); + + /* + * ִеʱ + * ٴִеʱѾȥ + */ + sever(hsub, sub); + + *L = (GList) malloc(sizeof(GLNode)); + if(*L == NULL) { + exit(OVERFLOW); + } + + StrAssign(emp, "()"); + + if(!StrCompare(hsub, emp)) { + (*L)->tag = List; + (*L)->Node.hp = NULL; + } else { + if(StrLength(hsub) == 1) { + (*L)->tag = Atom; + (*L)->Node.atom = hsub[1]; + } else { + (*L)->tag = List; + + SubString(tmp, hsub, 2, StrLength(hsub) - 2); + + CreateGList(&((*L)->Node.hp), tmp); + } + } + + // ڶβ˳ݹ + if(StrEmpty(sub)) { + (*L)->tp = NULL; + } else { + // ݹβ + CreateGList(&((*L)->tp), sub); + } + + return OK; +} + +/* + * + * + * ͷŹռڴ档 + */ +Status DestroyGList(GList* L) { + GList head, tail; + + if(L == NULL || *L == NULL) { + return ERROR; + } + + // ӱ + if((*L)->tag == List) { + head = (*L)->Node.hp; // ͷ + tail = (*L)->tp; // β + + free(*L); + *L = NULL; + + // ݹ鴦ͷ + if(head != NULL) { + DestroyGList(&head); + } + + // ݹ鴦β + if(tail != NULL) { + DestroyGList(&tail); + } + + // ԭӽ + } else { + tail = (*L)->tp; // β + + free(*L); + *L = NULL; + + if(tail != NULL) { + DestroyGList(&tail); + } + } + + return OK; +} + +/* + * + * + * ɹLƵõT + */ +Status CopyGList(GList* T, GList L) { + + if(L == NULL) { + return ERROR; + } + + *T = (GList) malloc(sizeof(GLNode)); + if(*T == NULL) { + exit(OVERFLOW); + } + + // ԭ + if(L->tag == Atom) { + (*T)->tag = Atom; + (*T)->Node.atom = L->Node.atom; + + // ӱ + } else { + (*T)->tag = List; + + // Ʊͷ + if(L->Node.hp != NULL) { + CopyGList(&((*T)->Node.hp), L->Node.hp); + } else { + (*T)->Node.hp = NULL; + } + } + + // Ʊβ + if(L->tp != NULL) { + CopyGList(&((*T)->tp), L->tp); + } else { + (*T)->tp = NULL; + } + + return OK; +} + +/* + * + * + * عijȡ + */ +int GListLength(GList L) { + int count = 0; + GList p; + + // + if(L == NULL) { + return -1; + } + + p = L->Node.hp; + + while(p != NULL) { + ++count; + p = p->tp; + } + + return count; +} + +/* + * + * + * ع + */ +int GListDepth(GList L) { + int max, deep; + GList p; + + max = 0; + + // + if(L == NULL) { + return -1; + } + + // ձΪ1 + if(L->tag == List && !L->Node.hp) { + return 1; + } + + // ԭΪ0 + if(L->tag == Atom) { + return 0; + } + + // ݹӱ + for(p = L->Node.hp; p != NULL; p = p->tp) { + // pΪͷָӱ + deep = GListDepth(p); + if(deep > max) { + max = deep; + } + } + + return max + 1; +} + +/* + * п + * + * жϹǷΪա + */ +Status GListEmpty(GList L) { + // + if(L == NULL) { + return ERROR; + } + + if(L->tag == List && L->Node.hp == NULL && L->tp == NULL) { + return TRUE; + } else { + return ERROR; + } +} + +/* + * ͷ + */ +GList GetHead(GList L) { + GList p, q; + + // ڻΪձ޷ȡͷ + if(L == NULL || L->Node.hp == NULL) { + return NULL; + } + + q = L->Node.hp->tp; // ʱLıβϢ + L->Node.hp->tp = NULL; // ȥLıβ + + CopyGList(&p, L->Node.hp); // ƱͷϢαβ + + L->Node.hp->tp = q; // ָLıβϢ + + return p; +} + +/* + * β + */ +GList GetTail(GList L) { + GList p, q; + + // ڻΪձ޷ȡβ + if(L == NULL || L->Node.hp == NULL) { + return NULL; + } + + q = L->Node.hp; // ʱLıͷϢ + L->Node.hp = q->tp; // ժLıͷ + + CopyGList(&p, L); // ƱβϢαͷ + + q->tp = L->Node.hp; // ָLıͷϢ + L->Node.hp = q; + + return p; +} + +/* + * + * + * ԪeΪLĵһԪء + */ +Status InsertFirst(GList* L, GList e) { + + // + if(L == NULL || *L == NULL) { + return ERROR; + } + + if(e == NULL) { + return ERROR; + } + + e->tp = (*L)->Node.hp; + (*L)->Node.hp = e; + + return OK; +} + +/* + * ɾ + * + * LĵһԪɾeء + */ +Status DeleteFirst(GList* L, GList* e) { + GList p; + + // ڻΪձ޷ɾͷ + if(*L == NULL || (*L)->Node.hp == NULL) { + return ERROR; + } + + p = (*L)->Node.hp; + (*L)->Node.hp = p->tp; + p->tp = NULL; + + *e = p; + + return OK; +} + +/* + * + * + * visitʹL + */ +void Traverse(GList L, void(Visit)(AtomType)) { + if(L == NULL) { + return; + } + + if(L->tag == List) { + Traverse(L->Node.hp, Visit); + } else { + Visit(L->Node.atom); + } + + Traverse(L->tp, Visit); +} + +/* + * ͼλ + * + * L + */ +void PrintGraph(GList L) { + Print(L); + printf("\n"); +} + +/* + * ͼλڲʵ֡ + */ +static void Print(GList L) { + if(L == NULL) { + return; + } + + // + if(L->tag == List) { + printf("("); + + if(L->Node.hp) { + Print(L->Node.hp); + } + + if(L->tp) { + printf("),"); + Print(L->tp); + } else { + printf(")"); + } + + // ԭӽ + } else { + printf("%c", L->Node.atom); + if(L->tp) { + printf(","); + Print(L->tp); + } + } +} + +/* + * ǿմstrָ֣hsubΪһ','֮ǰӴstrΪһ','֮Ӵ + * + *ע + * 1.ַstrȷ޿հ׷ţ + * strſȥҲδȥ + * 2.ɺstrҲᷢ仯 + */ +static void sever(SString hstr, SString str) { + int i, k, n; + SString ch; + + n = StrLength(str); + + i = 0; // ַʱα + k = 0; // δ + + do { + ++i; + + // ȡstrһַ + SubString(ch, str, i, 1); + + if(ch[1] == '(') { + ++k; + } + if(ch[1] == ')') { + --k; + } + } while(i < n && (ch[1] != ',' || k != 0)); + + if(i < n) { + SubString(hstr, str, 1, i - 1); + SubString(str, str, i + 1, n - i); + } else { + StrCopy(hstr, str); + ClearString(str); + } +} diff --git a/VisualC++/ExerciseBook/05.34.2/GList-E.h b/VisualC++/ExerciseBook/05.34.2/GList-E.h new file mode 100644 index 0000000..fa9af82 --- /dev/null +++ b/VisualC++/ExerciseBook/05.34.2/GList-E.h @@ -0,0 +1,146 @@ +/*=========================== + * չ洢ʾ + ============================*/ + +#ifndef GLIST_E_H +#define GLIST_E_H + +#include +#include // ṩ mallocreallocfreeexit ԭ +#include "Status.h" //**01 **// +#include "SString.h" //**04 **// + +/* ԭԪ */ +typedef char AtomType; //ԭ + +/* + * + * + * Atom-0ԭӽ + * List-1 + */ +typedef enum { Atom, List } ElemTag; + +/* չ洢ʾͶ */ +typedef struct GLNode { + ElemTag tag; // ǣԭӽͱ + + // ԭӽͱϲ + union + { + AtomType atom; // atomԭӽֵAtomTypeû + struct GLNode* hp; // ָͷ + } Node; + struct GLNode* tp; // ָβ +} GLNode; + +/* */ +typedef GLNode* GList; + + +/* + * ʼ + * + * ʼյĹΪ0Ϊ1 + * + *ע + * Ҫÿһſ + */ +Status InitGList(GList* L); + +/* + * + * + * ַSL + */ +Status CreateGList(GList* L, SString S); + +/* + * + * + * ͷŹռڴ档 + */ +Status DestroyGList(GList* L); + +/* + * + * + * ɹLƵõT + */ +Status CopyGList(GList* T, GList L); + +/* + * + * + * عijȡ + */ +int GListLength(GList L); + +/* + * + * + * ع + */ +int GListDepth(GList L); + +/* + * п + * + * жϹǷΪա + */ +Status GListEmpty(GList L); + +/* + * ͷ + */ +GList GetHead(GList L); + +/* + * β + */ +GList GetTail(GList L); + +/* + * + * + * ԪeΪLĵһԪء + */ +Status InsertFirst(GList* L, GList e); + +/* + * ɾ + * + * LĵһԪɾeء + */ +Status DeleteFirst(GList* L, GList* e); + +/* + * + * + * visitʹL + */ +void Traverse(GList L, void(Visit)(AtomType)); + +/* + * ͼλ + * + * L + */ +void PrintGraph(GList L); + +/* + * ͼλڲʵ֡ + */ +static void Print(GList L); + +/* + * ǿմstrָ֣hsubΪһ','֮ǰӴstrΪһ','֮Ӵ + * + *ע + * 1.ַstrȷ޿հ׷ţ + * strſȥҲδȥ + * 2.ɺstrҲᷢ仯 + */ +static void sever(SString hstr, SString str); + +#endif diff --git a/VisualC++/ExerciseBook/05.34.2/SString.c b/VisualC++/ExerciseBook/05.34.2/SString.c new file mode 100644 index 0000000..7a96fcf --- /dev/null +++ b/VisualC++/ExerciseBook/05.34.2/SString.c @@ -0,0 +1,195 @@ +/*============================= + * Ķ˳洢ʾ˳򴮣 + * + * 㷨: 4.14.24.34.5 + ==============================*/ + +#include "SString.h" //**04 **// + +/* + * ʼ + * + * һֵΪcharsĴT + * + *ע + * òСӼ + */ +Status StrAssign(SString T, const char* chars) { + int i, len; + + len = (int) strlen(chars); + + // chars + if(len > MAXSTRLEN) { + return ERROR; + } + + T[0] = len; + for(i = 1; i <= len; i++) { + T[i] = chars[i - 1]; + } + + return OK; +} + +/* + * + * + * Sա + */ +Status ClearString(SString S) { + // ֻҪΪ0Ϳ + S[0] = 0; + return OK; +} + +/* + * п + * + * жϴSǷЧݡ + * + * ֵ + * TRUE : SΪ + * FALSE: SΪ + */ +Status StrEmpty(SString S) { + return S[0] == 0 ? TRUE : FALSE; +} + +/* + * + * + * شSԪصĸ + * + *ע + * òСӼ + */ +int StrLength(SString S) { + return S[0]; +} + +/* + * 㷨4.3 + * + * Ӵ + * + * SubS[pos, pos+len-1] + * ֵָʾǷȡɹ + * + *ע + * òСӼ + */ +Status SubString(SString Sub, SString S, int pos, int len) { + int i; + + if(pos < 1 || pos > S[0] || len < 0 || pos + len - 1 > S[0]) { + return ERROR; + } + + // Ԫ + for(i = 1; i <= len; i++) { + Sub[i] = S[pos + i - 1]; + } + + // ȷ³ + Sub[0] = len; + + return OK; +} + +/* + * ɾ + * + * ɾS[pos, pos+len-1] + */ +Status StrDelete(SString S, int pos, int len) { + int i; + + if(pos < 1 || pos + len - 1 > S[0] || len < 0) { + return ERROR; + } + + // ɾijΪ0ǰ + if(len == 0) { + return OK; + } + + // ѺԪŲǰ棬ǵɾԪ + for(i = pos + len; i <= S[0]; i++) { + S[i - len] = S[i]; + } + + // ȼ + S[0] -= len; + + return OK; +} + +/* + * Ƚ + * + * ȽϴSʹTرȽϽ + * + *ע + * òСӼ + */ +int StrCompare(SString S, SString T) { + int i = 1; + + while(i <= S[0] && i <= T[0]) { + // ַͬʱȽС + if(S[i] != T[i]) { + return S[i] - T[i]; + } + + i++; + } + + return S[0] - T[0]; +} + +/* + * + * + * SƵT + */ +Status StrCopy(SString T, SString S) { + int i; + + // ͬϢһ + for(i = 0; i <= S[0]; i++) { + T[i] = S[i]; + } + + return OK; +} + +/* + * ַSеĿհףɴӡַո + * + *ע + * úڱġ + */ +Status ClearBlank(SString S) { + int i, j; + + // ǿմ + if(S[0] == 0) { + return ERROR; + } + + for(i = 1, j = 0; i <= S[0]; i++) { + // հףԹ + if(S[i] == ' ' || !isprint(S[i])) { + continue; + } + + j++; + + S[j] = S[i]; + } + + S[0] = j; + + return OK; +} diff --git a/VisualC++/ExerciseBook/05.34.2/SString.h b/VisualC++/ExerciseBook/05.34.2/SString.h new file mode 100644 index 0000000..0632f18 --- /dev/null +++ b/VisualC++/ExerciseBook/05.34.2/SString.h @@ -0,0 +1,117 @@ +/*============================= + * Ķ˳洢ʾ˳򴮣 + * + * 㷨: 4.14.24.34.5 + ==============================*/ + +#ifndef SSTRING_H +#define SSTRING_H + +#include +#include // ṩ strlen ԭ +#include // ṩ isprint ԭ +#include "Status.h" //**01 **// + +/* 궨 */ +#define MAXSTRLEN 255 // ˳򴮵󴮳 + +/* + * ˳洢Ͷ + * + * עЧԪشSString1ŵԪʼ洢 + * SString0ŵԪ洢䳤 + */ +typedef unsigned char SString[MAXSTRLEN + 1]; // 0ŵԪŴij + + +/* + * ʾ + * + * ѭ̲ĵдϰߣposָʾַλ()1ʼ + */ + + +/* + * ʼ + * + * һֵΪcharsĴT + * + *ע + * òСӼ + */ +Status StrAssign(SString T, const char* chars); + +/* + * + * + * Sա + */ +Status ClearString(SString S); + +/* + * п + * + * жϴSǷЧݡ + * + * ֵ + * TRUE : SΪ + * FALSE: SΪ + */ +Status StrEmpty(SString S); + +/* + * + * + * شSԪصĸ + * + *ע + * òСӼ + */ +int StrLength(SString S); + +/* + * 㷨4.3 + * + * Ӵ + * + * SubS[pos, pos+len-1] + * ֵָʾǷȡɹ + * + *ע + * òСӼ + */ +Status SubString(SString Sub, SString S, int pos, int len); + +/* + * ɾ + * + * ɾS[pos, pos+len-1] + */ +Status StrDelete(SString S, int pos, int len); + +/* + * Ƚ + * + * ȽϴSʹTرȽϽ + * + *ע + * òСӼ + */ +int StrCompare(SString S, SString T); + +/* + * + * + * SƵT + */ +Status StrCopy(SString T, SString S); + +/* + * ַSеĿհףɴӡַո + * + *ע + * úڱġ + */ +Status ClearBlank(SString S); + +#endif diff --git a/VisualC++/ExerciseBook/05.35-05.36/05.35-05.36.c b/VisualC++/ExerciseBook/05.35-05.36/05.35-05.36.c new file mode 100644 index 0000000..615ee5e --- /dev/null +++ b/VisualC++/ExerciseBook/05.35-05.36/05.35-05.36.c @@ -0,0 +1,45 @@ +#include +#include "Status.h" //**01 **// +#include "SString.h" //**04 **// +#include "GList.h" //**05 ͹**// + +/* + * Lォ"( )"ΪΪյ״̬ + */ +Status Algo_5_35(GList* L, SString S); + +/* + * Lォ"( )"ΪΪյ״̬ + */ +void Algo_5_36(GList L); + + +int main(int argc, char* argv[]) { + GList L; + char* s = "(( ),(e),(a,(b,c,d)))"; + SString S; + + printf(" L ...\n"); + StrAssign(S, s); + Algo_5_35(&L, S); + + printf("L = "); + Algo_5_36(L); + + return 0; +} + + +/* + * Lォ"( )"ΪΪյ״̬ + */ +Status Algo_5_35(GList* L, SString S) { + return CreateGList(L, S); +} + +/* + * Lォ"( )"ΪΪյ״̬ + */ +void Algo_5_36(GList L) { + PrintGraph(L); +} diff --git a/VisualC++/ExerciseBook/05.35-05.36/05.35-05.36.vcxproj b/VisualC++/ExerciseBook/05.35-05.36/05.35-05.36.vcxproj new file mode 100644 index 0000000..a06397d --- /dev/null +++ b/VisualC++/ExerciseBook/05.35-05.36/05.35-05.36.vcxproj @@ -0,0 +1,78 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {5F387672-C799-4368-9203-BA5CBAB5387D} + My05350536 + + + + Application + true + MultiByte + + + Application + false + true + MultiByte + + + + + + + + + + + + + $(SolutionDir)\..\Status;$(IncludePath) + + + + Level3 + Disabled + + + true + $(SolutionDir)\..\Status\Status.lib;%(AdditionalDependencies) + Console + + + + + Level3 + MaxSpeed + true + true + + + true + true + true + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/05.35-05.36/05.35-05.36.vcxproj.filters b/VisualC++/ExerciseBook/05.35-05.36/05.35-05.36.vcxproj.filters new file mode 100644 index 0000000..155ecf5 --- /dev/null +++ b/VisualC++/ExerciseBook/05.35-05.36/05.35-05.36.vcxproj.filters @@ -0,0 +1,36 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + 源文件 + + + 源文件 + + + 源文件 + + + + + 头文件 + + + 头文件 + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/05.35-05.36/05.35-05.36.vcxproj.user b/VisualC++/ExerciseBook/05.35-05.36/05.35-05.36.vcxproj.user new file mode 100644 index 0000000..ace9a86 --- /dev/null +++ b/VisualC++/ExerciseBook/05.35-05.36/05.35-05.36.vcxproj.user @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/05.35-05.36/GList.c b/VisualC++/ExerciseBook/05.35-05.36/GList.c new file mode 100644 index 0000000..3956155 --- /dev/null +++ b/VisualC++/ExerciseBook/05.35-05.36/GList.c @@ -0,0 +1,179 @@ +/*============================ + * ͷβ洢ʾ + =============================*/ + +#include "GList.h" + +/* + * + * + * ַSL + * + *ע + * ォ"( )"ΪΪյ״̬ + */ +Status CreateGList(GList* L, SString S) { + SString emp; // չַ + SString hsub, sub; + GList p, q; + + if(L == NULL) { + return ERROR; + } + + // ַSеĿհףɴӡַո + ClearBlank(S); + + if(StrEmpty(S)) { + return ERROR; + } + + StrAssign(emp, "( )"); + + /* + * 봮Ϊ()ҪյĹ + * + *ע + * ̲Ĵġ + * StrCompareķֵָʾַĴСָʾַǷȡ + * S()ȣֵӦ0 + */ + if(!StrCompare(S, emp)) { + *L = NULL; + } else { + *L = (GList) malloc(sizeof(GLNode)); + if(*L == NULL) { + exit(OVERFLOW); + } + + // ԭ + if(StrLength(S) == 1) { + (*L)->tag = Atom; + (*L)->Node.atom = S[1]; + } else { + (*L)->tag = List; + + p = *L; + + // ȥ + SubString(sub, S, 2, StrLength(S) - 2); + + // ظnӱ + do { + // subзͷhsubɺsubҲᷢ仯 + sever(hsub, sub); + + // ݹ鴴 + CreateGList(&(p->Node.ptr.hp), hsub); + + q = p; + + // βΪգҪβ + if(!StrEmpty(sub)) { + p = (GList) malloc(sizeof(GLNode)); + if(p == NULL) { + exit(OVERFLOW); + } + + p->tag = List; + + q->Node.ptr.tp = p; + } + } while(!StrEmpty(sub)); + + q->Node.ptr.tp = NULL; + } + } + + return OK; +} + +/* + * ͼλ + * + * L + * + *ע + * ォ"( )"ΪΪյ״̬ + */ +void PrintGraph(GList L) { + Print(L, Head); + printf("\n"); +} + +/* + * ͼλڲʵ֣markͼλǡ + */ +static void Print(GList L, Mark mark) { + // LΪ + if(L == NULL) { + if(mark == Head) { + printf("( "); + } + + printf(")"); + + // LΪʱ + } else { + // ԭӽ㣬ԭ + if(L->tag == Atom) { + printf("%c", L->Node.atom); + + // ӱ㣬ҪԱͷβֱ + } else { + if(mark == Head) { + printf("("); + } else { + printf(","); + } + + Print(L->Node.ptr.hp, Head); + Print(L->Node.ptr.tp, Tail); + } + } +} + +/* + * 㷨5.8 + * + * ǿմstrָ֣hsubΪһ','֮ǰӴstrΪһ','֮Ӵ + * + *ע + * 1.ַstrȷ޿հ׷ţstrѾȥš + * 2.ɺstrҲᷢ仯 + */ +static void sever(SString hstr, SString str) { + int i, k, n; + SString ch; + + n = StrLength(str); + + i = 0; // ַʱα + k = 0; // δ + + do { + ++i; + + // ȡstrһַ + SubString(ch, str, i, 1); + + if(ch[1] == '(') { + ++k; + } + + if(ch[1] == ')') { + --k; + } + } while(i < n && (ch[1] != ',' || k != 0)); + + // ڶ + if(i < n) { + SubString(hstr, str, 1, i - 1); + SubString(str, str, i + 1, n - i); + + // ֻһ + } else { + StrCopy(hstr, str); + ClearString(str); + } +} diff --git a/VisualC++/ExerciseBook/05.35-05.36/GList.h b/VisualC++/ExerciseBook/05.35-05.36/GList.h new file mode 100644 index 0000000..c9837e7 --- /dev/null +++ b/VisualC++/ExerciseBook/05.35-05.36/GList.h @@ -0,0 +1,82 @@ +/*============================ + * ͷβ洢ʾ + =============================*/ + +#ifndef GLIST_H +#define GLIST_H + +#include +#include // ṩ mallocreallocfreeexit ԭ +#include "Status.h" //**01 **// +#include "SString.h" //**04 **// + +/* ԭԪ */ +typedef char AtomType; + +/* + * + * + * Atom-0ԭӽ + * List-1 + */ +typedef enum { Atom, List } ElemTag; + +/* ͷβ洢ʾͶ */ +typedef struct GLNode { + ElemTag tag; // ǣԭӽͱ + + // ԭӽͱϲ + union { + AtomType atom; // atomԭӽֵAtomTypeû + struct { + struct GLNode* hp; // ָͷ + struct GLNode* tp; // ָβ + } ptr; // ָ + } Node; +} GLNode; + +/* */ +typedef GLNode* GList; + +/* + * ͼλ + * + * HeadָԱͷ + * TailָԱβ + */ +typedef enum { Head, Tail } Mark; + + +/* + * 㷨5.7 + * + * + * + * ַSL + */ +Status CreateGList(GList* L, SString S); + +/* + * ͼλ + * + * L + */ +void PrintGraph(GList L); + +/* + * ͼλڲʵ֣markͼλǡ + */ +static void Print(GList L, Mark mark); + +/* + * 㷨5.8 + * + * ǿմstrָ֣hsubΪһ','֮ǰӴstrΪһ','֮Ӵ + * + *ע + * 1.ַstrȷ޿հ׷ţstrѾȥš + * 2.ɺstrҲᷢ仯 + */ +static void sever(SString hstr, SString str); + +#endif diff --git a/VisualC++/ExerciseBook/05.35-05.36/SString.c b/VisualC++/ExerciseBook/05.35-05.36/SString.c new file mode 100644 index 0000000..b8bb831 --- /dev/null +++ b/VisualC++/ExerciseBook/05.35-05.36/SString.c @@ -0,0 +1,195 @@ +/*============================= + * Ķ˳洢ʾ˳򴮣 + * + * 㷨: 4.14.24.34.5 + ==============================*/ + +#include "SString.h" //**04 **// + +/* + * ʼ + * + * һֵΪcharsĴT + * + *ע + * òСӼ + */ +Status StrAssign(SString T, const char* chars) { + int i, len; + + len = (int) strlen(chars); + + // chars + if(len > MAXSTRLEN) { + return ERROR; + } + + T[0] = len; + for(i = 1; i <= len; i++) { + T[i] = chars[i - 1]; + } + + return OK; +} + +/* + * + * + * Sա + */ +Status ClearString(SString S) { + // ֻҪΪ0Ϳ + S[0] = 0; + return OK; +} + +/* + * п + * + * жϴSǷЧݡ + * + * ֵ + * TRUE : SΪ + * FALSE: SΪ + */ +Status StrEmpty(SString S) { + return S[0] == 0 ? TRUE : FALSE; +} + +/* + * + * + * شSԪصĸ + * + *ע + * òСӼ + */ +int StrLength(SString S) { + return S[0]; +} + +/* + * 㷨4.3 + * + * Ӵ + * + * SubS[pos, pos+len-1] + * ֵָʾǷȡɹ + * + *ע + * òСӼ + */ +Status SubString(SString Sub, SString S, int pos, int len) { + int i; + + if(pos < 1 || pos > S[0] || len < 0 || pos + len - 1 > S[0]) { + return ERROR; + } + + // Ԫ + for(i = 1; i <= len; i++) { + Sub[i] = S[pos + i - 1]; + } + + // ȷ³ + Sub[0] = len; + + return OK; +} + +/* + * ɾ + * + * ɾS[pos, pos+len-1] + */ +Status StrDelete(SString S, int pos, int len) { + int i; + + if(pos < 1 || pos + len - 1 > S[0] || len < 0) { + return ERROR; + } + + // ɾijΪ0ǰ + if(len == 0) { + return OK; + } + + // ѺԪŲǰ棬ǵɾԪ + for(i = pos + len; i <= S[0]; i++) { + S[i - len] = S[i]; + } + + // ȼ + S[0] -= len; + + return OK; +} + +/* + * Ƚ + * + * ȽϴSʹTرȽϽ + * + *ע + * òСӼ + */ +int StrCompare(SString S, SString T) { + int i = 1; + + while(i <= S[0] && i <= T[0]) { + // ַͬʱȽС + if(S[i] != T[i]) { + return S[i] - T[i]; + } + + i++; + } + + return S[0] - T[0]; +} + +/* + * + * + * SƵT + */ +Status StrCopy(SString T, SString S) { + int i; + + // ͬϢһ + for(i = 0; i <= S[0]; i++) { + T[i] = S[i]; + } + + return OK; +} + +/* + * ַSеIJɴӡַո + * + *ע + * úڱġ + */ +Status ClearBlank(SString S) { + int i, j; + + // ǿմ + if(S[0] == 0) { + return ERROR; + } + + for(i = 1, j = 0; i <= S[0]; i++) { + // հףԹ + if(!isprint(S[i])) { + continue; + } + + j++; + + S[j] = S[i]; + } + + S[0] = j; + + return OK; +} diff --git a/VisualC++/ExerciseBook/05.35-05.36/SString.h b/VisualC++/ExerciseBook/05.35-05.36/SString.h new file mode 100644 index 0000000..3635a16 --- /dev/null +++ b/VisualC++/ExerciseBook/05.35-05.36/SString.h @@ -0,0 +1,117 @@ +/*============================= + * Ķ˳洢ʾ˳򴮣 + * + * 㷨: 4.14.24.34.5 + ==============================*/ + +#ifndef SSTRING_H +#define SSTRING_H + +#include +#include // ṩ strlen ԭ +#include // ṩ isprint ԭ +#include "Status.h" //**01 **// + +/* 궨 */ +#define MAXSTRLEN 255 // ˳򴮵󴮳 + +/* + * ˳洢Ͷ + * + * עЧԪشSString1ŵԪʼ洢 + * SString0ŵԪ洢䳤 + */ +typedef unsigned char SString[MAXSTRLEN + 1]; // 0ŵԪŴij + + +/* + * ʾ + * + * ѭ̲ĵдϰߣposָʾַλ()1ʼ + */ + + +/* + * ʼ + * + * һֵΪcharsĴT + * + *ע + * òСӼ + */ +Status StrAssign(SString T, const char* chars); + +/* + * + * + * Sա + */ +Status ClearString(SString S); + +/* + * п + * + * жϴSǷЧݡ + * + * ֵ + * TRUE : SΪ + * FALSE: SΪ + */ +Status StrEmpty(SString S); + +/* + * + * + * شSԪصĸ + * + *ע + * òСӼ + */ +int StrLength(SString S); + +/* + * 㷨4.3 + * + * Ӵ + * + * SubS[pos, pos+len-1] + * ֵָʾǷȡɹ + * + *ע + * òСӼ + */ +Status SubString(SString Sub, SString S, int pos, int len); + +/* + * ɾ + * + * ɾS[pos, pos+len-1] + */ +Status StrDelete(SString S, int pos, int len); + +/* + * Ƚ + * + * ȽϴSʹTرȽϽ + * + *ע + * òСӼ + */ +int StrCompare(SString S, SString T); + +/* + * + * + * SƵT + */ +Status StrCopy(SString T, SString S); + +/* + * ַSеIJɴӡַո + * + *ע + * úڱġ + */ +Status ClearBlank(SString S); + +#endif diff --git a/VisualC++/ExerciseBook/05.37.1/05.37.1.c b/VisualC++/ExerciseBook/05.37.1/05.37.1.c new file mode 100644 index 0000000..11b37d6 --- /dev/null +++ b/VisualC++/ExerciseBook/05.37.1/05.37.1.c @@ -0,0 +1,63 @@ +#include +#include "SString.h" //**04 **// +#include "GList-HT.h" //**05 ͹**// + +/* + * ɾֵΪxԭͷβ洢ʾ + */ +void Algo_5_37_1(GList* L, AtomType x); + + +int main(int argc, char* argv[]) { + GList L; + char* s = "((b),(e),(a,(b,c,d)),(b,((b),b)),x,b,(y))"; + SString S; + + printf(" L ...\n"); + StrAssign(S, s); + CreateGList(&L, S); + printf("L = "); + PrintGraph(L); + + printf("ɾ L еԪ 'b' ...\n"); + Algo_5_37_1(&L, 'b'); + printf("L = "); + PrintGraph(L); + + return 0; +} + + +/* + * ɾֵΪxԭͷβ洢ʾ + */ +void Algo_5_37_1(GList* L, AtomType x) { + GList h, p; + + if(L == NULL || *L == NULL || (*L)->tag == Atom) { + return; + } + + h = (*L)->Node.ptr.hp; + + if(h != NULL) { + if(h->tag == List) { + Algo_5_37_1(&((*L)->Node.ptr.hp), x); + Algo_5_37_1(&((*L)->Node.ptr.tp), x); + } else { + if(h->Node.atom == x) { + p = *L; + *L = (*L)->Node.ptr.tp; + p->Node.ptr.tp = NULL; + DestroyGList(&p); + Algo_5_37_1(L, x); + } else { + Algo_5_37_1(&((*L)->Node.ptr.tp), x); + } + } + } else { + if((*L)->Node.ptr.tp != NULL) { + Algo_5_37_1(&((*L)->Node.ptr.tp), x); + } + } +} diff --git a/VisualC++/ExerciseBook/05.37.1/05.37.1.vcxproj b/VisualC++/ExerciseBook/05.37.1/05.37.1.vcxproj new file mode 100644 index 0000000..d769f95 --- /dev/null +++ b/VisualC++/ExerciseBook/05.37.1/05.37.1.vcxproj @@ -0,0 +1,78 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {C034ACF3-B096-4A56-975A-A8497FC86E14} + My05371 + + + + Application + true + MultiByte + + + Application + false + true + MultiByte + + + + + + + + + + + + + $(SolutionDir)\..\Status;$(IncludePath) + + + + Level3 + Disabled + + + true + $(SolutionDir)\..\Status\Status.lib;%(AdditionalDependencies) + Console + + + + + Level3 + MaxSpeed + true + true + + + true + true + true + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/05.37.1/05.37.1.vcxproj.filters b/VisualC++/ExerciseBook/05.37.1/05.37.1.vcxproj.filters new file mode 100644 index 0000000..87c449a --- /dev/null +++ b/VisualC++/ExerciseBook/05.37.1/05.37.1.vcxproj.filters @@ -0,0 +1,36 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + 源文件 + + + 源文件 + + + 源文件 + + + + + 头文件 + + + 头文件 + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/05.37.1/05.37.1.vcxproj.user b/VisualC++/ExerciseBook/05.37.1/05.37.1.vcxproj.user new file mode 100644 index 0000000..ace9a86 --- /dev/null +++ b/VisualC++/ExerciseBook/05.37.1/05.37.1.vcxproj.user @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/05.37.1/GList-HT.c b/VisualC++/ExerciseBook/05.37.1/GList-HT.c new file mode 100644 index 0000000..bad30df --- /dev/null +++ b/VisualC++/ExerciseBook/05.37.1/GList-HT.c @@ -0,0 +1,418 @@ +/*============================ + * ͷβ洢ʾ + * + * 㷨: 5.55.65.75.8 + =============================*/ + +#include "GList-HT.h" //**05 ͹**// + +/* + * ʼ + * + * ʼյĹΪ0Ϊ1 + * + *ע + * Ҫÿһȥſ + */ +Status InitGList(GList* L) { + if(L == NULL) { + return ERROR; + } + + *L = NULL; + + return OK; +} + +/* + * 㷨5.7 + * + * + * + * ַSL + */ +Status CreateGList(GList* L, SString S) { + SString emp; // չַ + SString hsub, sub; + GList p, q; + + if(L == NULL) { + return ERROR; + } + + // ַSеĿհףɴӡַո + ClearBlank(S); + + if(StrEmpty(S)) { + return ERROR; + } + + StrAssign(emp, "()"); + + /* + * 봮Ϊ()ҪյĹ + * + *ע + * ̲Ĵġ + * StrCompareķֵָʾַĴСָʾַǷȡ + * S()ȣֵӦ0 + */ + if(!StrCompare(S, emp)) { + *L = NULL; + } else { + *L = (GList) malloc(sizeof(GLNode)); + if(*L == NULL) { + exit(OVERFLOW); + } + + // ԭ + if(StrLength(S) == 1) { + (*L)->tag = Atom; + (*L)->Node.atom = S[1]; + } else { + (*L)->tag = List; + + p = *L; + + // ȥ + SubString(sub, S, 2, StrLength(S) - 2); + + // ظnӱ + do { + // subзͷhsubɺsubҲᷢ仯 + sever(hsub, sub); + + // ݹ鴴 + CreateGList(&(p->Node.ptr.hp), hsub); + + q = p; + + // βΪգҪβ + if(!StrEmpty(sub)) { + p = (GList) malloc(sizeof(GLNode)); + if(p == NULL) { + exit(OVERFLOW); + } + + p->tag = List; + + q->Node.ptr.tp = p; + } + } while(!StrEmpty(sub)); + + q->Node.ptr.tp = NULL; + } + } + + return OK; +} + +/* + * + * + * ͷŹռڴ档 + */ +Status DestroyGList(GList* L) { + GList head, tail; + + if(L == NULL || *L == NULL) { + return ERROR; + } + + // ɾԭӽ + if((*L)->tag == Atom) { + free(*L); + *L = NULL; + + // ɾӱ + } else { + head = (*L)->Node.ptr.hp; + tail = (*L)->Node.ptr.tp; + free(*L); + *L = NULL; + DestroyGList(&head); + DestroyGList(&tail); + } + + return OK; +} + +/* + * 㷨5.6 + * + * + * + * ɹLƵõT + */ +Status CopyGList(GList* T, GList L) { + if(T == NULL) { + return ERROR; + } + + if(L == NULL) { + *T = NULL; + } else { + // ½ + *T = (GList) malloc(sizeof(GLNode)); + if(*T == NULL) { + exit(OVERFLOW); + } + + (*T)->tag = L->tag; + + // Ƶԭ + if(L->tag == Atom) { + (*T)->Node.atom = L->Node.atom; + + // Ʊͷͱβ + } else { + CopyGList(&((*T)->Node.ptr.hp), L->Node.ptr.hp); + CopyGList(&((*T)->Node.ptr.tp), L->Node.ptr.tp); + } + } + + return OK; +} + +/* + * + * + * عijȡ + */ +int GListLength(GList L) { + int count; + + for(count = 0; L != NULL; count++, L = L->Node.ptr.tp) { + } + + return count; +} + +/* + * 㷨5.5 + * + * + * + * ع + */ +int GListDepth(GList L) { + int max, deep; + GList p; + + // ձΪ1 + if(L == NULL) { + return 1; + } + + // ԭΪ0 + if(L->tag == Atom) { + return 0; + } + + // ݹӱ + for(max = 0, p = L; p != NULL; p = p->Node.ptr.tp) { + deep = GListDepth(p->Node.ptr.hp); + if(deep > max) { + max = deep; + } + } + + // ǿձǸԪȼһ + return max + 1; +} + +/* + * п + * + * жϹǷΪա + */ +Status GListEmpty(GList L) { + return L == NULL ? TRUE : FALSE; +} + +/* + * ͷ + */ +GList GetHead(GList L) { + GList p; + + // ձޱͷﲻܷNULLȻֲʧ˻Ƿ˿ձ + if(L == NULL) { + exit(ERROR); + } + + CopyGList(&p, L->Node.ptr.hp); + + return p; +} + +/* + * β + */ +GList GetTail(GList L) { + GList p; + + // ձޱβﲻܷNULLȻֲʧ˻Ƿ˿ձ + if(L == NULL) { + exit(ERROR); + } + + CopyGList(&p, L->Node.ptr.tp); + + return p; +} + +/* + * + * + * ԪeΪLĵһԪء + */ +Status InsertFirst(GList* L, GList e) { + GList g; + + if(L == NULL) { + return ERROR; + } + + g = (GList) malloc(sizeof(GLNode)); + if(g == NULL) { + exit(OVERFLOW); + } + + g->tag = List; + g->Node.ptr.hp = e; + g->Node.ptr.tp = *L; + *L = g; + + return OK; +} + +/* + * ɾ + * + * LĵһԪɾeء + */ +Status DeleteFirst(GList* L, GList* e) { + GList p; + + // ձ޷ɾ + if(L == NULL || *L == NULL) { + return ERROR; + } + + p = *L; + *L = (*L)->Node.ptr.tp; + + CopyGList(e, p->Node.ptr.hp); + + free(p); + + return OK; +} + +/* + * + * + * visitʹL + */ +void Traverse(GList L, void(Visit)(AtomType)) { + + if(L == NULL) { + return; + } + + if(L->tag == Atom) { + Visit(L->Node.atom); + } else { + Traverse(L->Node.ptr.hp, Visit); + Traverse(L->Node.ptr.tp, Visit); + } + +} + +/* + * ͼλ + * + * L + */ +void PrintGraph(GList L) { + Print(L, Head); + printf("\n"); +} + +/* + * ͼλڲʵ֣markͼλǡ + */ +static void Print(GList L, Mark mark) { + // LΪ + if(L == NULL) { + if(mark == Head) { + printf("("); + } + + printf(")"); + + // LΪʱ + } else { + // ԭӽ㣬ԭ + if(L->tag == Atom) { + printf("%c", L->Node.atom); + + // ӱ㣬ҪԱͷβֱ + } else { + if(mark == Head) { + printf("("); + } else { + printf(","); + } + + Print(L->Node.ptr.hp, Head); + Print(L->Node.ptr.tp, Tail); + } + } +} + +/* + * 㷨5.8 + * + * ǿմstrָ֣hsubΪһ','֮ǰӴstrΪһ','֮Ӵ + * + *ע + * 1.ַstrȷ޿հ׷ţstrѾȥš + * 2.ɺstrҲᷢ仯 + */ +static void sever(SString hstr, SString str) { + int i, k, n; + SString ch; + + n = StrLength(str); + + i = 0; // ַʱα + k = 0; // δ + + do { + ++i; + + // ȡstrһַ + SubString(ch, str, i, 1); + + if(ch[1] == '(') { + ++k; + } + + if(ch[1] == ')') { + --k; + } + } while(i < n && (ch[1] != ',' || k != 0)); + + // ڶ + if(i < n) { + SubString(hstr, str, 1, i - 1); + SubString(str, str, i + 1, n - i); + + // ֻһ + } else { + StrCopy(hstr, str); + ClearString(str); + } +} diff --git a/VisualC++/ExerciseBook/05.37.1/GList-HT.h b/VisualC++/ExerciseBook/05.37.1/GList-HT.h new file mode 100644 index 0000000..508b96f --- /dev/null +++ b/VisualC++/ExerciseBook/05.37.1/GList-HT.h @@ -0,0 +1,164 @@ +/*============================ + * ͷβ洢ʾ + * + * 㷨: 5.55.65.75.8 + =============================*/ + +#ifndef GLIST_HT_H +#define GLIST_HT_H + +#include +#include // ṩ mallocreallocfreeexit ԭ +#include "Status.h" //**01 **// +#include "SString.h" //**04 **// + +/* ԭԪ */ +typedef char AtomType; + +/* + * + * + * Atom-0ԭӽ + * List-1 + */ +typedef enum { Atom, List } ElemTag; + +/* ͷβ洢ʾͶ */ +typedef struct GLNode { + ElemTag tag; // ǣԭӽͱ + + // ԭӽͱϲ + union { + AtomType atom; // atomԭӽֵAtomTypeû + struct { + struct GLNode* hp; // ָͷ + struct GLNode* tp; // ָβ + } ptr; // ָ + } Node; +} GLNode; + +/* */ +typedef GLNode* GList; + +/* + * ͼλ + * + * HeadָԱͷ + * TailָԱβ + */ +typedef enum { Head, Tail } Mark; + + +/* + * ʼ + * + * ʼյĹΪ0Ϊ1 + * + *ע + * Ҫÿһȥſ + */ +Status InitGList(GList* L); + +/* + * 㷨5.7 + * + * + * + * ַSL + */ +Status CreateGList(GList* L, SString S); + +/* + * + * + * ͷŹռڴ档 + */ +Status DestroyGList(GList* L); + +/* + * 㷨5.6 + * + * + * + * ɹLƵõT + */ +Status CopyGList(GList* T, GList L); + +/* + * + * + * عijȡ + */ +int GListLength(GList L); + +/* + * 㷨5.5 + * + * + * + * ع + */ +int GListDepth(GList L); + +/* + * п + * + * жϹǷΪա + */ +Status GListEmpty(GList L); + +/* + * ͷ + */ +GList GetHead(GList L); + +/* + * β + */ +GList GetTail(GList L); + +/* + * + * + * ԪeΪLĵһԪء + */ +Status InsertFirst(GList* L, GList e); + +/* + * ɾ + * + * LĵһԪɾeء + */ +Status DeleteFirst(GList* L, GList* e); + +/* + * + * + * visitʹL + */ +void Traverse(GList L, void (Visit)(AtomType)); + +/* + * ͼλ + * + * L + */ +void PrintGraph(GList L); + +/* + * ͼλڲʵ֣markͼλǡ + */ +static void Print(GList L, Mark mark); + +/* + * 㷨5.8 + * + * ǿմstrָ֣hsubΪһ','֮ǰӴstrΪһ','֮Ӵ + * + *ע + * 1.ַstrȷ޿հ׷ţstrѾȥš + * 2.ɺstrҲᷢ仯 + */ +static void sever(SString hstr, SString str); + +#endif diff --git a/VisualC++/ExerciseBook/05.37.1/SString.c b/VisualC++/ExerciseBook/05.37.1/SString.c new file mode 100644 index 0000000..7a96fcf --- /dev/null +++ b/VisualC++/ExerciseBook/05.37.1/SString.c @@ -0,0 +1,195 @@ +/*============================= + * Ķ˳洢ʾ˳򴮣 + * + * 㷨: 4.14.24.34.5 + ==============================*/ + +#include "SString.h" //**04 **// + +/* + * ʼ + * + * һֵΪcharsĴT + * + *ע + * òСӼ + */ +Status StrAssign(SString T, const char* chars) { + int i, len; + + len = (int) strlen(chars); + + // chars + if(len > MAXSTRLEN) { + return ERROR; + } + + T[0] = len; + for(i = 1; i <= len; i++) { + T[i] = chars[i - 1]; + } + + return OK; +} + +/* + * + * + * Sա + */ +Status ClearString(SString S) { + // ֻҪΪ0Ϳ + S[0] = 0; + return OK; +} + +/* + * п + * + * жϴSǷЧݡ + * + * ֵ + * TRUE : SΪ + * FALSE: SΪ + */ +Status StrEmpty(SString S) { + return S[0] == 0 ? TRUE : FALSE; +} + +/* + * + * + * شSԪصĸ + * + *ע + * òСӼ + */ +int StrLength(SString S) { + return S[0]; +} + +/* + * 㷨4.3 + * + * Ӵ + * + * SubS[pos, pos+len-1] + * ֵָʾǷȡɹ + * + *ע + * òСӼ + */ +Status SubString(SString Sub, SString S, int pos, int len) { + int i; + + if(pos < 1 || pos > S[0] || len < 0 || pos + len - 1 > S[0]) { + return ERROR; + } + + // Ԫ + for(i = 1; i <= len; i++) { + Sub[i] = S[pos + i - 1]; + } + + // ȷ³ + Sub[0] = len; + + return OK; +} + +/* + * ɾ + * + * ɾS[pos, pos+len-1] + */ +Status StrDelete(SString S, int pos, int len) { + int i; + + if(pos < 1 || pos + len - 1 > S[0] || len < 0) { + return ERROR; + } + + // ɾijΪ0ǰ + if(len == 0) { + return OK; + } + + // ѺԪŲǰ棬ǵɾԪ + for(i = pos + len; i <= S[0]; i++) { + S[i - len] = S[i]; + } + + // ȼ + S[0] -= len; + + return OK; +} + +/* + * Ƚ + * + * ȽϴSʹTرȽϽ + * + *ע + * òСӼ + */ +int StrCompare(SString S, SString T) { + int i = 1; + + while(i <= S[0] && i <= T[0]) { + // ַͬʱȽС + if(S[i] != T[i]) { + return S[i] - T[i]; + } + + i++; + } + + return S[0] - T[0]; +} + +/* + * + * + * SƵT + */ +Status StrCopy(SString T, SString S) { + int i; + + // ͬϢһ + for(i = 0; i <= S[0]; i++) { + T[i] = S[i]; + } + + return OK; +} + +/* + * ַSеĿհףɴӡַո + * + *ע + * úڱġ + */ +Status ClearBlank(SString S) { + int i, j; + + // ǿմ + if(S[0] == 0) { + return ERROR; + } + + for(i = 1, j = 0; i <= S[0]; i++) { + // հףԹ + if(S[i] == ' ' || !isprint(S[i])) { + continue; + } + + j++; + + S[j] = S[i]; + } + + S[0] = j; + + return OK; +} diff --git a/VisualC++/ExerciseBook/05.37.1/SString.h b/VisualC++/ExerciseBook/05.37.1/SString.h new file mode 100644 index 0000000..0632f18 --- /dev/null +++ b/VisualC++/ExerciseBook/05.37.1/SString.h @@ -0,0 +1,117 @@ +/*============================= + * Ķ˳洢ʾ˳򴮣 + * + * 㷨: 4.14.24.34.5 + ==============================*/ + +#ifndef SSTRING_H +#define SSTRING_H + +#include +#include // ṩ strlen ԭ +#include // ṩ isprint ԭ +#include "Status.h" //**01 **// + +/* 궨 */ +#define MAXSTRLEN 255 // ˳򴮵󴮳 + +/* + * ˳洢Ͷ + * + * עЧԪشSString1ŵԪʼ洢 + * SString0ŵԪ洢䳤 + */ +typedef unsigned char SString[MAXSTRLEN + 1]; // 0ŵԪŴij + + +/* + * ʾ + * + * ѭ̲ĵдϰߣposָʾַλ()1ʼ + */ + + +/* + * ʼ + * + * һֵΪcharsĴT + * + *ע + * òСӼ + */ +Status StrAssign(SString T, const char* chars); + +/* + * + * + * Sա + */ +Status ClearString(SString S); + +/* + * п + * + * жϴSǷЧݡ + * + * ֵ + * TRUE : SΪ + * FALSE: SΪ + */ +Status StrEmpty(SString S); + +/* + * + * + * شSԪصĸ + * + *ע + * òСӼ + */ +int StrLength(SString S); + +/* + * 㷨4.3 + * + * Ӵ + * + * SubS[pos, pos+len-1] + * ֵָʾǷȡɹ + * + *ע + * òСӼ + */ +Status SubString(SString Sub, SString S, int pos, int len); + +/* + * ɾ + * + * ɾS[pos, pos+len-1] + */ +Status StrDelete(SString S, int pos, int len); + +/* + * Ƚ + * + * ȽϴSʹTرȽϽ + * + *ע + * òСӼ + */ +int StrCompare(SString S, SString T); + +/* + * + * + * SƵT + */ +Status StrCopy(SString T, SString S); + +/* + * ַSеĿհףɴӡַո + * + *ע + * úڱġ + */ +Status ClearBlank(SString S); + +#endif diff --git a/VisualC++/ExerciseBook/05.37.2/05.37.2.c b/VisualC++/ExerciseBook/05.37.2/05.37.2.c new file mode 100644 index 0000000..9e5afb1 --- /dev/null +++ b/VisualC++/ExerciseBook/05.37.2/05.37.2.c @@ -0,0 +1,56 @@ +#include +#include // ṩmallocreallocfreeexitԭ +#include "SString.h" //**04 **// +#include "GList-E.h" //**05 ͹**// + +/* + * ɾֵΪxԭչ洢ʾ + */ +void Algo_5_37_2(GList* L, AtomType x); + + +int main(int argc, char* argv[]) { + GList L; + char* s = "((b),(e),(a,(b,c,d)),(b,((b),b)),x,b,(y))"; + SString S; + + printf(" L ...\n"); + StrAssign(S, s); + CreateGList(&L, S); + printf("L = "); + PrintGraph(L); + + printf("ɾ L еԪ 'b' ...\n"); + Algo_5_37_2(&L, 'b'); + printf("L = "); + PrintGraph(L); + + return 0; +} + + +/* + * ɾֵΪxԭչ洢ʾ + */ +void Algo_5_37_2(GList* L, AtomType x) { + GList p; + + if(L == NULL || *L == NULL) { + return; + } + + if((*L)->tag == List) { + Algo_5_37_2(&((*L)->Node.hp), x); + Algo_5_37_2(&((*L)->tp), x); + } else { + if((*L)->Node.atom == x) { + p = *L; + *L = (*L)->tp; + free(p); + + Algo_5_37_2(L, x); + } else { + Algo_5_37_2(&((*L)->tp), x); + } + } +} diff --git a/VisualC++/ExerciseBook/05.37.2/05.37.2.vcxproj b/VisualC++/ExerciseBook/05.37.2/05.37.2.vcxproj new file mode 100644 index 0000000..f1fdcae --- /dev/null +++ b/VisualC++/ExerciseBook/05.37.2/05.37.2.vcxproj @@ -0,0 +1,78 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {960F0527-2A12-49C5-B79C-21EBF9528B6C} + My05372 + + + + Application + true + MultiByte + + + Application + false + true + MultiByte + + + + + + + + + + + + + $(SolutionDir)\..\Status;$(IncludePath) + + + + Level3 + Disabled + + + true + $(SolutionDir)\..\Status\Status.lib;%(AdditionalDependencies) + Console + + + + + Level3 + MaxSpeed + true + true + + + true + true + true + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/05.37.2/05.37.2.vcxproj.filters b/VisualC++/ExerciseBook/05.37.2/05.37.2.vcxproj.filters new file mode 100644 index 0000000..5decfe3 --- /dev/null +++ b/VisualC++/ExerciseBook/05.37.2/05.37.2.vcxproj.filters @@ -0,0 +1,36 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + 源文件 + + + 源文件 + + + 源文件 + + + + + 头文件 + + + 头文件 + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/05.37.2/05.37.2.vcxproj.user b/VisualC++/ExerciseBook/05.37.2/05.37.2.vcxproj.user new file mode 100644 index 0000000..ace9a86 --- /dev/null +++ b/VisualC++/ExerciseBook/05.37.2/05.37.2.vcxproj.user @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/05.37.2/GList-E.c b/VisualC++/ExerciseBook/05.37.2/GList-E.c new file mode 100644 index 0000000..3fc0ad9 --- /dev/null +++ b/VisualC++/ExerciseBook/05.37.2/GList-E.c @@ -0,0 +1,449 @@ +/*=========================== + * չ洢ʾ + ============================*/ + +#include "GList-E.h" //**05 ͹**// + +/* + * ʼ + * + * ʼյĹΪ0Ϊ1 + * + *ע + * Ҫÿһſ + */ +Status InitGList(GList* L) { + if(L == NULL) { + return ERROR; + } + + *L = (GList) malloc(sizeof(GLNode)); + if(!*L) { + exit(OVERFLOW); + } + + (*L)->tag = List; + (*L)->Node.hp = NULL; + (*L)->tp = NULL; + + return OK; +} + +/* + * + * + * ַSL + */ +Status CreateGList(GList* L, SString S) { + SString emp, hsub, sub, tmp; + + if(L == NULL) { + return ERROR; + } + + // ַSеĿհףɴӡַո + ClearBlank(S); + + if(StrEmpty(S)) { + return ERROR; + } + + // Ϊ˲ƻS + StrCopy(sub, S); + + /* + * ִеʱ + * ٴִеʱѾȥ + */ + sever(hsub, sub); + + *L = (GList) malloc(sizeof(GLNode)); + if(*L == NULL) { + exit(OVERFLOW); + } + + StrAssign(emp, "()"); + + if(!StrCompare(hsub, emp)) { + (*L)->tag = List; + (*L)->Node.hp = NULL; + } else { + if(StrLength(hsub) == 1) { + (*L)->tag = Atom; + (*L)->Node.atom = hsub[1]; + } else { + (*L)->tag = List; + + SubString(tmp, hsub, 2, StrLength(hsub) - 2); + + CreateGList(&((*L)->Node.hp), tmp); + } + } + + // ڶβ˳ݹ + if(StrEmpty(sub)) { + (*L)->tp = NULL; + } else { + // ݹβ + CreateGList(&((*L)->tp), sub); + } + + return OK; +} + +/* + * + * + * ͷŹռڴ档 + */ +Status DestroyGList(GList* L) { + GList head, tail; + + if(L == NULL || *L == NULL) { + return ERROR; + } + + // ӱ + if((*L)->tag == List) { + head = (*L)->Node.hp; // ͷ + tail = (*L)->tp; // β + + free(*L); + *L = NULL; + + // ݹ鴦ͷ + if(head != NULL) { + DestroyGList(&head); + } + + // ݹ鴦β + if(tail != NULL) { + DestroyGList(&tail); + } + + // ԭӽ + } else { + tail = (*L)->tp; // β + + free(*L); + *L = NULL; + + if(tail != NULL) { + DestroyGList(&tail); + } + } + + return OK; +} + +/* + * + * + * ɹLƵõT + */ +Status CopyGList(GList* T, GList L) { + + if(L == NULL) { + return ERROR; + } + + *T = (GList) malloc(sizeof(GLNode)); + if(*T == NULL) { + exit(OVERFLOW); + } + + // ԭ + if(L->tag == Atom) { + (*T)->tag = Atom; + (*T)->Node.atom = L->Node.atom; + + // ӱ + } else { + (*T)->tag = List; + + // Ʊͷ + if(L->Node.hp != NULL) { + CopyGList(&((*T)->Node.hp), L->Node.hp); + } else { + (*T)->Node.hp = NULL; + } + } + + // Ʊβ + if(L->tp != NULL) { + CopyGList(&((*T)->tp), L->tp); + } else { + (*T)->tp = NULL; + } + + return OK; +} + +/* + * + * + * عijȡ + */ +int GListLength(GList L) { + int count = 0; + GList p; + + // + if(L == NULL) { + return -1; + } + + p = L->Node.hp; + + while(p != NULL) { + ++count; + p = p->tp; + } + + return count; +} + +/* + * + * + * ع + */ +int GListDepth(GList L) { + int max, deep; + GList p; + + max = 0; + + // + if(L == NULL) { + return -1; + } + + // ձΪ1 + if(L->tag == List && !L->Node.hp) { + return 1; + } + + // ԭΪ0 + if(L->tag == Atom) { + return 0; + } + + // ݹӱ + for(p = L->Node.hp; p != NULL; p = p->tp) { + // pΪͷָӱ + deep = GListDepth(p); + if(deep > max) { + max = deep; + } + } + + return max + 1; +} + +/* + * п + * + * жϹǷΪա + */ +Status GListEmpty(GList L) { + // + if(L == NULL) { + return ERROR; + } + + if(L->tag == List && L->Node.hp == NULL && L->tp == NULL) { + return TRUE; + } else { + return ERROR; + } +} + +/* + * ͷ + */ +GList GetHead(GList L) { + GList p, q; + + // ڻΪձ޷ȡͷ + if(L == NULL || L->Node.hp == NULL) { + return NULL; + } + + q = L->Node.hp->tp; // ʱLıβϢ + L->Node.hp->tp = NULL; // ȥLıβ + + CopyGList(&p, L->Node.hp); // ƱͷϢαβ + + L->Node.hp->tp = q; // ָLıβϢ + + return p; +} + +/* + * β + */ +GList GetTail(GList L) { + GList p, q; + + // ڻΪձ޷ȡβ + if(L == NULL || L->Node.hp == NULL) { + return NULL; + } + + q = L->Node.hp; // ʱLıͷϢ + L->Node.hp = q->tp; // ժLıͷ + + CopyGList(&p, L); // ƱβϢαͷ + + q->tp = L->Node.hp; // ָLıͷϢ + L->Node.hp = q; + + return p; +} + +/* + * + * + * ԪeΪLĵһԪء + */ +Status InsertFirst(GList* L, GList e) { + + // + if(L == NULL || *L == NULL) { + return ERROR; + } + + if(e == NULL) { + return ERROR; + } + + e->tp = (*L)->Node.hp; + (*L)->Node.hp = e; + + return OK; +} + +/* + * ɾ + * + * LĵһԪɾeء + */ +Status DeleteFirst(GList* L, GList* e) { + GList p; + + // ڻΪձ޷ɾͷ + if(*L == NULL || (*L)->Node.hp == NULL) { + return ERROR; + } + + p = (*L)->Node.hp; + (*L)->Node.hp = p->tp; + p->tp = NULL; + + *e = p; + + return OK; +} + +/* + * + * + * visitʹL + */ +void Traverse(GList L, void(Visit)(AtomType)) { + if(L == NULL) { + return; + } + + if(L->tag == List) { + Traverse(L->Node.hp, Visit); + } else { + Visit(L->Node.atom); + } + + Traverse(L->tp, Visit); +} + +/* + * ͼλ + * + * L + */ +void PrintGraph(GList L) { + Print(L); + printf("\n"); +} + +/* + * ͼλڲʵ֡ + */ +static void Print(GList L) { + if(L == NULL) { + return; + } + + // + if(L->tag == List) { + printf("("); + + if(L->Node.hp) { + Print(L->Node.hp); + } + + if(L->tp) { + printf("),"); + Print(L->tp); + } else { + printf(")"); + } + + // ԭӽ + } else { + printf("%c", L->Node.atom); + if(L->tp) { + printf(","); + Print(L->tp); + } + } +} + +/* + * ǿմstrָ֣hsubΪһ','֮ǰӴstrΪһ','֮Ӵ + * + *ע + * 1.ַstrȷ޿հ׷ţ + * strſȥҲδȥ + * 2.ɺstrҲᷢ仯 + */ +static void sever(SString hstr, SString str) { + int i, k, n; + SString ch; + + n = StrLength(str); + + i = 0; // ַʱα + k = 0; // δ + + do { + ++i; + + // ȡstrһַ + SubString(ch, str, i, 1); + + if(ch[1] == '(') { + ++k; + } + if(ch[1] == ')') { + --k; + } + } while(i < n && (ch[1] != ',' || k != 0)); + + if(i < n) { + SubString(hstr, str, 1, i - 1); + SubString(str, str, i + 1, n - i); + } else { + StrCopy(hstr, str); + ClearString(str); + } +} diff --git a/VisualC++/ExerciseBook/05.37.2/GList-E.h b/VisualC++/ExerciseBook/05.37.2/GList-E.h new file mode 100644 index 0000000..fa9af82 --- /dev/null +++ b/VisualC++/ExerciseBook/05.37.2/GList-E.h @@ -0,0 +1,146 @@ +/*=========================== + * չ洢ʾ + ============================*/ + +#ifndef GLIST_E_H +#define GLIST_E_H + +#include +#include // ṩ mallocreallocfreeexit ԭ +#include "Status.h" //**01 **// +#include "SString.h" //**04 **// + +/* ԭԪ */ +typedef char AtomType; //ԭ + +/* + * + * + * Atom-0ԭӽ + * List-1 + */ +typedef enum { Atom, List } ElemTag; + +/* չ洢ʾͶ */ +typedef struct GLNode { + ElemTag tag; // ǣԭӽͱ + + // ԭӽͱϲ + union + { + AtomType atom; // atomԭӽֵAtomTypeû + struct GLNode* hp; // ָͷ + } Node; + struct GLNode* tp; // ָβ +} GLNode; + +/* */ +typedef GLNode* GList; + + +/* + * ʼ + * + * ʼյĹΪ0Ϊ1 + * + *ע + * Ҫÿһſ + */ +Status InitGList(GList* L); + +/* + * + * + * ַSL + */ +Status CreateGList(GList* L, SString S); + +/* + * + * + * ͷŹռڴ档 + */ +Status DestroyGList(GList* L); + +/* + * + * + * ɹLƵõT + */ +Status CopyGList(GList* T, GList L); + +/* + * + * + * عijȡ + */ +int GListLength(GList L); + +/* + * + * + * ع + */ +int GListDepth(GList L); + +/* + * п + * + * жϹǷΪա + */ +Status GListEmpty(GList L); + +/* + * ͷ + */ +GList GetHead(GList L); + +/* + * β + */ +GList GetTail(GList L); + +/* + * + * + * ԪeΪLĵһԪء + */ +Status InsertFirst(GList* L, GList e); + +/* + * ɾ + * + * LĵһԪɾeء + */ +Status DeleteFirst(GList* L, GList* e); + +/* + * + * + * visitʹL + */ +void Traverse(GList L, void(Visit)(AtomType)); + +/* + * ͼλ + * + * L + */ +void PrintGraph(GList L); + +/* + * ͼλڲʵ֡ + */ +static void Print(GList L); + +/* + * ǿմstrָ֣hsubΪһ','֮ǰӴstrΪһ','֮Ӵ + * + *ע + * 1.ַstrȷ޿հ׷ţ + * strſȥҲδȥ + * 2.ɺstrҲᷢ仯 + */ +static void sever(SString hstr, SString str); + +#endif diff --git a/VisualC++/ExerciseBook/05.37.2/SString.c b/VisualC++/ExerciseBook/05.37.2/SString.c new file mode 100644 index 0000000..7a96fcf --- /dev/null +++ b/VisualC++/ExerciseBook/05.37.2/SString.c @@ -0,0 +1,195 @@ +/*============================= + * Ķ˳洢ʾ˳򴮣 + * + * 㷨: 4.14.24.34.5 + ==============================*/ + +#include "SString.h" //**04 **// + +/* + * ʼ + * + * һֵΪcharsĴT + * + *ע + * òСӼ + */ +Status StrAssign(SString T, const char* chars) { + int i, len; + + len = (int) strlen(chars); + + // chars + if(len > MAXSTRLEN) { + return ERROR; + } + + T[0] = len; + for(i = 1; i <= len; i++) { + T[i] = chars[i - 1]; + } + + return OK; +} + +/* + * + * + * Sա + */ +Status ClearString(SString S) { + // ֻҪΪ0Ϳ + S[0] = 0; + return OK; +} + +/* + * п + * + * жϴSǷЧݡ + * + * ֵ + * TRUE : SΪ + * FALSE: SΪ + */ +Status StrEmpty(SString S) { + return S[0] == 0 ? TRUE : FALSE; +} + +/* + * + * + * شSԪصĸ + * + *ע + * òСӼ + */ +int StrLength(SString S) { + return S[0]; +} + +/* + * 㷨4.3 + * + * Ӵ + * + * SubS[pos, pos+len-1] + * ֵָʾǷȡɹ + * + *ע + * òСӼ + */ +Status SubString(SString Sub, SString S, int pos, int len) { + int i; + + if(pos < 1 || pos > S[0] || len < 0 || pos + len - 1 > S[0]) { + return ERROR; + } + + // Ԫ + for(i = 1; i <= len; i++) { + Sub[i] = S[pos + i - 1]; + } + + // ȷ³ + Sub[0] = len; + + return OK; +} + +/* + * ɾ + * + * ɾS[pos, pos+len-1] + */ +Status StrDelete(SString S, int pos, int len) { + int i; + + if(pos < 1 || pos + len - 1 > S[0] || len < 0) { + return ERROR; + } + + // ɾijΪ0ǰ + if(len == 0) { + return OK; + } + + // ѺԪŲǰ棬ǵɾԪ + for(i = pos + len; i <= S[0]; i++) { + S[i - len] = S[i]; + } + + // ȼ + S[0] -= len; + + return OK; +} + +/* + * Ƚ + * + * ȽϴSʹTرȽϽ + * + *ע + * òСӼ + */ +int StrCompare(SString S, SString T) { + int i = 1; + + while(i <= S[0] && i <= T[0]) { + // ַͬʱȽС + if(S[i] != T[i]) { + return S[i] - T[i]; + } + + i++; + } + + return S[0] - T[0]; +} + +/* + * + * + * SƵT + */ +Status StrCopy(SString T, SString S) { + int i; + + // ͬϢһ + for(i = 0; i <= S[0]; i++) { + T[i] = S[i]; + } + + return OK; +} + +/* + * ַSеĿհףɴӡַո + * + *ע + * úڱġ + */ +Status ClearBlank(SString S) { + int i, j; + + // ǿմ + if(S[0] == 0) { + return ERROR; + } + + for(i = 1, j = 0; i <= S[0]; i++) { + // հףԹ + if(S[i] == ' ' || !isprint(S[i])) { + continue; + } + + j++; + + S[j] = S[i]; + } + + S[0] = j; + + return OK; +} diff --git a/VisualC++/ExerciseBook/05.37.2/SString.h b/VisualC++/ExerciseBook/05.37.2/SString.h new file mode 100644 index 0000000..0632f18 --- /dev/null +++ b/VisualC++/ExerciseBook/05.37.2/SString.h @@ -0,0 +1,117 @@ +/*============================= + * Ķ˳洢ʾ˳򴮣 + * + * 㷨: 4.14.24.34.5 + ==============================*/ + +#ifndef SSTRING_H +#define SSTRING_H + +#include +#include // ṩ strlen ԭ +#include // ṩ isprint ԭ +#include "Status.h" //**01 **// + +/* 궨 */ +#define MAXSTRLEN 255 // ˳򴮵󴮳 + +/* + * ˳洢Ͷ + * + * עЧԪشSString1ŵԪʼ洢 + * SString0ŵԪ洢䳤 + */ +typedef unsigned char SString[MAXSTRLEN + 1]; // 0ŵԪŴij + + +/* + * ʾ + * + * ѭ̲ĵдϰߣposָʾַλ()1ʼ + */ + + +/* + * ʼ + * + * һֵΪcharsĴT + * + *ע + * òСӼ + */ +Status StrAssign(SString T, const char* chars); + +/* + * + * + * Sա + */ +Status ClearString(SString S); + +/* + * п + * + * жϴSǷЧݡ + * + * ֵ + * TRUE : SΪ + * FALSE: SΪ + */ +Status StrEmpty(SString S); + +/* + * + * + * شSԪصĸ + * + *ע + * òСӼ + */ +int StrLength(SString S); + +/* + * 㷨4.3 + * + * Ӵ + * + * SubS[pos, pos+len-1] + * ֵָʾǷȡɹ + * + *ע + * òСӼ + */ +Status SubString(SString Sub, SString S, int pos, int len); + +/* + * ɾ + * + * ɾS[pos, pos+len-1] + */ +Status StrDelete(SString S, int pos, int len); + +/* + * Ƚ + * + * ȽϴSʹTرȽϽ + * + *ע + * òСӼ + */ +int StrCompare(SString S, SString T); + +/* + * + * + * SƵT + */ +Status StrCopy(SString T, SString S); + +/* + * ַSеĿհףɴӡַո + * + *ע + * úڱġ + */ +Status ClearBlank(SString S); + +#endif diff --git a/VisualC++/ExerciseBook/05.38.1/05.38.1.c b/VisualC++/ExerciseBook/05.38.1/05.38.1.c new file mode 100644 index 0000000..c41ea76 --- /dev/null +++ b/VisualC++/ExerciseBook/05.38.1/05.38.1.c @@ -0,0 +1,47 @@ +#include +#include "SString.h" //**04 **// +#include "GList-HT.h" //**05 ͹**// + +/* + * еlԭ(ͷβ洢ʾ) + */ +void Algo_5_38_1(GList L, int d, int l); + + +int main(int argc, char* argv[]) { + GList L; + char* s = "((a),(b),(c,(d,e,f)),(g,((h),i)))"; + SString S; + + printf(" L ...\n"); + StrAssign(S, s); + CreateGList(&L, S); + printf("L = "); + PrintGraph(L); + + printf(" 2 ԭΪ"); + Algo_5_38_1(L, 0, 2); + printf("\n"); + + return 0; +} + + +/* + * еlԭ(ͷβ洢ʾ) + */ +void Algo_5_38_1(GList L, int d, int l) { + int i = d; // dijֵֵΪ0 + + if(L && l >= i) { + if(L->tag == Atom) { + // + if(l == i) { + printf("%c ", L->Node.atom); + } + } else { + Algo_5_38_1(L->Node.ptr.hp, i + 1, l); // ͷָָĻһ + Algo_5_38_1(L->Node.ptr.tp, i, l); + } + } +} diff --git a/VisualC++/ExerciseBook/05.38.1/05.38.1.vcxproj b/VisualC++/ExerciseBook/05.38.1/05.38.1.vcxproj new file mode 100644 index 0000000..db01959 --- /dev/null +++ b/VisualC++/ExerciseBook/05.38.1/05.38.1.vcxproj @@ -0,0 +1,78 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {679BE61B-60DE-4BC3-B8B0-B414175A376C} + My05381 + + + + Application + true + MultiByte + + + Application + false + true + MultiByte + + + + + + + + + + + + + $(SolutionDir)\..\Status;$(IncludePath) + + + + Level3 + Disabled + + + true + $(SolutionDir)\..\Status\Status.lib;%(AdditionalDependencies) + Console + + + + + Level3 + MaxSpeed + true + true + + + true + true + true + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/05.38.1/05.38.1.vcxproj.filters b/VisualC++/ExerciseBook/05.38.1/05.38.1.vcxproj.filters new file mode 100644 index 0000000..ca246ce --- /dev/null +++ b/VisualC++/ExerciseBook/05.38.1/05.38.1.vcxproj.filters @@ -0,0 +1,36 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + 源文件 + + + 源文件 + + + 源文件 + + + + + 头文件 + + + 头文件 + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/05.38.1/05.38.1.vcxproj.user b/VisualC++/ExerciseBook/05.38.1/05.38.1.vcxproj.user new file mode 100644 index 0000000..ace9a86 --- /dev/null +++ b/VisualC++/ExerciseBook/05.38.1/05.38.1.vcxproj.user @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/05.38.1/GList-HT.c b/VisualC++/ExerciseBook/05.38.1/GList-HT.c new file mode 100644 index 0000000..bad30df --- /dev/null +++ b/VisualC++/ExerciseBook/05.38.1/GList-HT.c @@ -0,0 +1,418 @@ +/*============================ + * ͷβ洢ʾ + * + * 㷨: 5.55.65.75.8 + =============================*/ + +#include "GList-HT.h" //**05 ͹**// + +/* + * ʼ + * + * ʼյĹΪ0Ϊ1 + * + *ע + * Ҫÿһȥſ + */ +Status InitGList(GList* L) { + if(L == NULL) { + return ERROR; + } + + *L = NULL; + + return OK; +} + +/* + * 㷨5.7 + * + * + * + * ַSL + */ +Status CreateGList(GList* L, SString S) { + SString emp; // չַ + SString hsub, sub; + GList p, q; + + if(L == NULL) { + return ERROR; + } + + // ַSеĿհףɴӡַո + ClearBlank(S); + + if(StrEmpty(S)) { + return ERROR; + } + + StrAssign(emp, "()"); + + /* + * 봮Ϊ()ҪյĹ + * + *ע + * ̲Ĵġ + * StrCompareķֵָʾַĴСָʾַǷȡ + * S()ȣֵӦ0 + */ + if(!StrCompare(S, emp)) { + *L = NULL; + } else { + *L = (GList) malloc(sizeof(GLNode)); + if(*L == NULL) { + exit(OVERFLOW); + } + + // ԭ + if(StrLength(S) == 1) { + (*L)->tag = Atom; + (*L)->Node.atom = S[1]; + } else { + (*L)->tag = List; + + p = *L; + + // ȥ + SubString(sub, S, 2, StrLength(S) - 2); + + // ظnӱ + do { + // subзͷhsubɺsubҲᷢ仯 + sever(hsub, sub); + + // ݹ鴴 + CreateGList(&(p->Node.ptr.hp), hsub); + + q = p; + + // βΪգҪβ + if(!StrEmpty(sub)) { + p = (GList) malloc(sizeof(GLNode)); + if(p == NULL) { + exit(OVERFLOW); + } + + p->tag = List; + + q->Node.ptr.tp = p; + } + } while(!StrEmpty(sub)); + + q->Node.ptr.tp = NULL; + } + } + + return OK; +} + +/* + * + * + * ͷŹռڴ档 + */ +Status DestroyGList(GList* L) { + GList head, tail; + + if(L == NULL || *L == NULL) { + return ERROR; + } + + // ɾԭӽ + if((*L)->tag == Atom) { + free(*L); + *L = NULL; + + // ɾӱ + } else { + head = (*L)->Node.ptr.hp; + tail = (*L)->Node.ptr.tp; + free(*L); + *L = NULL; + DestroyGList(&head); + DestroyGList(&tail); + } + + return OK; +} + +/* + * 㷨5.6 + * + * + * + * ɹLƵõT + */ +Status CopyGList(GList* T, GList L) { + if(T == NULL) { + return ERROR; + } + + if(L == NULL) { + *T = NULL; + } else { + // ½ + *T = (GList) malloc(sizeof(GLNode)); + if(*T == NULL) { + exit(OVERFLOW); + } + + (*T)->tag = L->tag; + + // Ƶԭ + if(L->tag == Atom) { + (*T)->Node.atom = L->Node.atom; + + // Ʊͷͱβ + } else { + CopyGList(&((*T)->Node.ptr.hp), L->Node.ptr.hp); + CopyGList(&((*T)->Node.ptr.tp), L->Node.ptr.tp); + } + } + + return OK; +} + +/* + * + * + * عijȡ + */ +int GListLength(GList L) { + int count; + + for(count = 0; L != NULL; count++, L = L->Node.ptr.tp) { + } + + return count; +} + +/* + * 㷨5.5 + * + * + * + * ع + */ +int GListDepth(GList L) { + int max, deep; + GList p; + + // ձΪ1 + if(L == NULL) { + return 1; + } + + // ԭΪ0 + if(L->tag == Atom) { + return 0; + } + + // ݹӱ + for(max = 0, p = L; p != NULL; p = p->Node.ptr.tp) { + deep = GListDepth(p->Node.ptr.hp); + if(deep > max) { + max = deep; + } + } + + // ǿձǸԪȼһ + return max + 1; +} + +/* + * п + * + * жϹǷΪա + */ +Status GListEmpty(GList L) { + return L == NULL ? TRUE : FALSE; +} + +/* + * ͷ + */ +GList GetHead(GList L) { + GList p; + + // ձޱͷﲻܷNULLȻֲʧ˻Ƿ˿ձ + if(L == NULL) { + exit(ERROR); + } + + CopyGList(&p, L->Node.ptr.hp); + + return p; +} + +/* + * β + */ +GList GetTail(GList L) { + GList p; + + // ձޱβﲻܷNULLȻֲʧ˻Ƿ˿ձ + if(L == NULL) { + exit(ERROR); + } + + CopyGList(&p, L->Node.ptr.tp); + + return p; +} + +/* + * + * + * ԪeΪLĵһԪء + */ +Status InsertFirst(GList* L, GList e) { + GList g; + + if(L == NULL) { + return ERROR; + } + + g = (GList) malloc(sizeof(GLNode)); + if(g == NULL) { + exit(OVERFLOW); + } + + g->tag = List; + g->Node.ptr.hp = e; + g->Node.ptr.tp = *L; + *L = g; + + return OK; +} + +/* + * ɾ + * + * LĵһԪɾeء + */ +Status DeleteFirst(GList* L, GList* e) { + GList p; + + // ձ޷ɾ + if(L == NULL || *L == NULL) { + return ERROR; + } + + p = *L; + *L = (*L)->Node.ptr.tp; + + CopyGList(e, p->Node.ptr.hp); + + free(p); + + return OK; +} + +/* + * + * + * visitʹL + */ +void Traverse(GList L, void(Visit)(AtomType)) { + + if(L == NULL) { + return; + } + + if(L->tag == Atom) { + Visit(L->Node.atom); + } else { + Traverse(L->Node.ptr.hp, Visit); + Traverse(L->Node.ptr.tp, Visit); + } + +} + +/* + * ͼλ + * + * L + */ +void PrintGraph(GList L) { + Print(L, Head); + printf("\n"); +} + +/* + * ͼλڲʵ֣markͼλǡ + */ +static void Print(GList L, Mark mark) { + // LΪ + if(L == NULL) { + if(mark == Head) { + printf("("); + } + + printf(")"); + + // LΪʱ + } else { + // ԭӽ㣬ԭ + if(L->tag == Atom) { + printf("%c", L->Node.atom); + + // ӱ㣬ҪԱͷβֱ + } else { + if(mark == Head) { + printf("("); + } else { + printf(","); + } + + Print(L->Node.ptr.hp, Head); + Print(L->Node.ptr.tp, Tail); + } + } +} + +/* + * 㷨5.8 + * + * ǿմstrָ֣hsubΪһ','֮ǰӴstrΪһ','֮Ӵ + * + *ע + * 1.ַstrȷ޿հ׷ţstrѾȥš + * 2.ɺstrҲᷢ仯 + */ +static void sever(SString hstr, SString str) { + int i, k, n; + SString ch; + + n = StrLength(str); + + i = 0; // ַʱα + k = 0; // δ + + do { + ++i; + + // ȡstrһַ + SubString(ch, str, i, 1); + + if(ch[1] == '(') { + ++k; + } + + if(ch[1] == ')') { + --k; + } + } while(i < n && (ch[1] != ',' || k != 0)); + + // ڶ + if(i < n) { + SubString(hstr, str, 1, i - 1); + SubString(str, str, i + 1, n - i); + + // ֻһ + } else { + StrCopy(hstr, str); + ClearString(str); + } +} diff --git a/VisualC++/ExerciseBook/05.38.1/GList-HT.h b/VisualC++/ExerciseBook/05.38.1/GList-HT.h new file mode 100644 index 0000000..508b96f --- /dev/null +++ b/VisualC++/ExerciseBook/05.38.1/GList-HT.h @@ -0,0 +1,164 @@ +/*============================ + * ͷβ洢ʾ + * + * 㷨: 5.55.65.75.8 + =============================*/ + +#ifndef GLIST_HT_H +#define GLIST_HT_H + +#include +#include // ṩ mallocreallocfreeexit ԭ +#include "Status.h" //**01 **// +#include "SString.h" //**04 **// + +/* ԭԪ */ +typedef char AtomType; + +/* + * + * + * Atom-0ԭӽ + * List-1 + */ +typedef enum { Atom, List } ElemTag; + +/* ͷβ洢ʾͶ */ +typedef struct GLNode { + ElemTag tag; // ǣԭӽͱ + + // ԭӽͱϲ + union { + AtomType atom; // atomԭӽֵAtomTypeû + struct { + struct GLNode* hp; // ָͷ + struct GLNode* tp; // ָβ + } ptr; // ָ + } Node; +} GLNode; + +/* */ +typedef GLNode* GList; + +/* + * ͼλ + * + * HeadָԱͷ + * TailָԱβ + */ +typedef enum { Head, Tail } Mark; + + +/* + * ʼ + * + * ʼյĹΪ0Ϊ1 + * + *ע + * Ҫÿһȥſ + */ +Status InitGList(GList* L); + +/* + * 㷨5.7 + * + * + * + * ַSL + */ +Status CreateGList(GList* L, SString S); + +/* + * + * + * ͷŹռڴ档 + */ +Status DestroyGList(GList* L); + +/* + * 㷨5.6 + * + * + * + * ɹLƵõT + */ +Status CopyGList(GList* T, GList L); + +/* + * + * + * عijȡ + */ +int GListLength(GList L); + +/* + * 㷨5.5 + * + * + * + * ع + */ +int GListDepth(GList L); + +/* + * п + * + * жϹǷΪա + */ +Status GListEmpty(GList L); + +/* + * ͷ + */ +GList GetHead(GList L); + +/* + * β + */ +GList GetTail(GList L); + +/* + * + * + * ԪeΪLĵһԪء + */ +Status InsertFirst(GList* L, GList e); + +/* + * ɾ + * + * LĵһԪɾeء + */ +Status DeleteFirst(GList* L, GList* e); + +/* + * + * + * visitʹL + */ +void Traverse(GList L, void (Visit)(AtomType)); + +/* + * ͼλ + * + * L + */ +void PrintGraph(GList L); + +/* + * ͼλڲʵ֣markͼλǡ + */ +static void Print(GList L, Mark mark); + +/* + * 㷨5.8 + * + * ǿմstrָ֣hsubΪһ','֮ǰӴstrΪһ','֮Ӵ + * + *ע + * 1.ַstrȷ޿հ׷ţstrѾȥš + * 2.ɺstrҲᷢ仯 + */ +static void sever(SString hstr, SString str); + +#endif diff --git a/VisualC++/ExerciseBook/05.38.1/SString.c b/VisualC++/ExerciseBook/05.38.1/SString.c new file mode 100644 index 0000000..7a96fcf --- /dev/null +++ b/VisualC++/ExerciseBook/05.38.1/SString.c @@ -0,0 +1,195 @@ +/*============================= + * Ķ˳洢ʾ˳򴮣 + * + * 㷨: 4.14.24.34.5 + ==============================*/ + +#include "SString.h" //**04 **// + +/* + * ʼ + * + * һֵΪcharsĴT + * + *ע + * òСӼ + */ +Status StrAssign(SString T, const char* chars) { + int i, len; + + len = (int) strlen(chars); + + // chars + if(len > MAXSTRLEN) { + return ERROR; + } + + T[0] = len; + for(i = 1; i <= len; i++) { + T[i] = chars[i - 1]; + } + + return OK; +} + +/* + * + * + * Sա + */ +Status ClearString(SString S) { + // ֻҪΪ0Ϳ + S[0] = 0; + return OK; +} + +/* + * п + * + * жϴSǷЧݡ + * + * ֵ + * TRUE : SΪ + * FALSE: SΪ + */ +Status StrEmpty(SString S) { + return S[0] == 0 ? TRUE : FALSE; +} + +/* + * + * + * شSԪصĸ + * + *ע + * òСӼ + */ +int StrLength(SString S) { + return S[0]; +} + +/* + * 㷨4.3 + * + * Ӵ + * + * SubS[pos, pos+len-1] + * ֵָʾǷȡɹ + * + *ע + * òСӼ + */ +Status SubString(SString Sub, SString S, int pos, int len) { + int i; + + if(pos < 1 || pos > S[0] || len < 0 || pos + len - 1 > S[0]) { + return ERROR; + } + + // Ԫ + for(i = 1; i <= len; i++) { + Sub[i] = S[pos + i - 1]; + } + + // ȷ³ + Sub[0] = len; + + return OK; +} + +/* + * ɾ + * + * ɾS[pos, pos+len-1] + */ +Status StrDelete(SString S, int pos, int len) { + int i; + + if(pos < 1 || pos + len - 1 > S[0] || len < 0) { + return ERROR; + } + + // ɾijΪ0ǰ + if(len == 0) { + return OK; + } + + // ѺԪŲǰ棬ǵɾԪ + for(i = pos + len; i <= S[0]; i++) { + S[i - len] = S[i]; + } + + // ȼ + S[0] -= len; + + return OK; +} + +/* + * Ƚ + * + * ȽϴSʹTرȽϽ + * + *ע + * òСӼ + */ +int StrCompare(SString S, SString T) { + int i = 1; + + while(i <= S[0] && i <= T[0]) { + // ַͬʱȽС + if(S[i] != T[i]) { + return S[i] - T[i]; + } + + i++; + } + + return S[0] - T[0]; +} + +/* + * + * + * SƵT + */ +Status StrCopy(SString T, SString S) { + int i; + + // ͬϢһ + for(i = 0; i <= S[0]; i++) { + T[i] = S[i]; + } + + return OK; +} + +/* + * ַSеĿհףɴӡַո + * + *ע + * úڱġ + */ +Status ClearBlank(SString S) { + int i, j; + + // ǿմ + if(S[0] == 0) { + return ERROR; + } + + for(i = 1, j = 0; i <= S[0]; i++) { + // հףԹ + if(S[i] == ' ' || !isprint(S[i])) { + continue; + } + + j++; + + S[j] = S[i]; + } + + S[0] = j; + + return OK; +} diff --git a/VisualC++/ExerciseBook/05.38.1/SString.h b/VisualC++/ExerciseBook/05.38.1/SString.h new file mode 100644 index 0000000..0632f18 --- /dev/null +++ b/VisualC++/ExerciseBook/05.38.1/SString.h @@ -0,0 +1,117 @@ +/*============================= + * Ķ˳洢ʾ˳򴮣 + * + * 㷨: 4.14.24.34.5 + ==============================*/ + +#ifndef SSTRING_H +#define SSTRING_H + +#include +#include // ṩ strlen ԭ +#include // ṩ isprint ԭ +#include "Status.h" //**01 **// + +/* 궨 */ +#define MAXSTRLEN 255 // ˳򴮵󴮳 + +/* + * ˳洢Ͷ + * + * עЧԪشSString1ŵԪʼ洢 + * SString0ŵԪ洢䳤 + */ +typedef unsigned char SString[MAXSTRLEN + 1]; // 0ŵԪŴij + + +/* + * ʾ + * + * ѭ̲ĵдϰߣposָʾַλ()1ʼ + */ + + +/* + * ʼ + * + * һֵΪcharsĴT + * + *ע + * òСӼ + */ +Status StrAssign(SString T, const char* chars); + +/* + * + * + * Sա + */ +Status ClearString(SString S); + +/* + * п + * + * жϴSǷЧݡ + * + * ֵ + * TRUE : SΪ + * FALSE: SΪ + */ +Status StrEmpty(SString S); + +/* + * + * + * شSԪصĸ + * + *ע + * òСӼ + */ +int StrLength(SString S); + +/* + * 㷨4.3 + * + * Ӵ + * + * SubS[pos, pos+len-1] + * ֵָʾǷȡɹ + * + *ע + * òСӼ + */ +Status SubString(SString Sub, SString S, int pos, int len); + +/* + * ɾ + * + * ɾS[pos, pos+len-1] + */ +Status StrDelete(SString S, int pos, int len); + +/* + * Ƚ + * + * ȽϴSʹTرȽϽ + * + *ע + * òСӼ + */ +int StrCompare(SString S, SString T); + +/* + * + * + * SƵT + */ +Status StrCopy(SString T, SString S); + +/* + * ַSеĿհףɴӡַո + * + *ע + * úڱġ + */ +Status ClearBlank(SString S); + +#endif diff --git a/VisualC++/ExerciseBook/05.38.2/05.38.2.c b/VisualC++/ExerciseBook/05.38.2/05.38.2.c new file mode 100644 index 0000000..ed3096f --- /dev/null +++ b/VisualC++/ExerciseBook/05.38.2/05.38.2.c @@ -0,0 +1,48 @@ +#include +#include "SString.h" //**04 **// +#include "GList-E.h" //**05 ͹**// + +/* + * еlԭ(չ洢ʾ) + */ +void Algo_5_38_2(GList L, int d, int l); + + +int main(int argc, char* argv[]) { + GList L; + char* s = "((a),(b),(c,(d,e,f)),(g,((h),i)))"; + SString S; + + printf(" L ...\n"); + StrAssign(S, s); + CreateGList(&L, S); + printf("L = "); + PrintGraph(L); + + printf(" 2 ԭΪ"); + Algo_5_38_2(L, 0, 2); + printf("\n"); + + return 0; +} + + +/* + * еlԭ(չ洢ʾ) + */ +void Algo_5_38_2(GList L, int d, int l) { + int i = d; // dijֵֵΪ0 + + if(L && l >= i) { + if(L->tag == Atom) { + // + if(l == i) { + printf("%c ", L->Node.atom); + } + } else { + Algo_5_38_2(L->Node.hp, i + 1, l); // ͷָָĻһ + } + + Algo_5_38_2(L->tp, i, l); + } +} diff --git a/VisualC++/ExerciseBook/05.38.2/05.38.2.vcxproj b/VisualC++/ExerciseBook/05.38.2/05.38.2.vcxproj new file mode 100644 index 0000000..7c21ba8 --- /dev/null +++ b/VisualC++/ExerciseBook/05.38.2/05.38.2.vcxproj @@ -0,0 +1,78 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {564E9CB9-3C86-4823-98A5-777D1B0A3104} + My05382 + + + + Application + true + MultiByte + + + Application + false + true + MultiByte + + + + + + + + + + + + + $(SolutionDir)\..\Status;$(IncludePath) + + + + Level3 + Disabled + + + true + $(SolutionDir)\..\Status\Status.lib;%(AdditionalDependencies) + Console + + + + + Level3 + MaxSpeed + true + true + + + true + true + true + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/05.38.2/05.38.2.vcxproj.filters b/VisualC++/ExerciseBook/05.38.2/05.38.2.vcxproj.filters new file mode 100644 index 0000000..d067555 --- /dev/null +++ b/VisualC++/ExerciseBook/05.38.2/05.38.2.vcxproj.filters @@ -0,0 +1,36 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + 源文件 + + + 源文件 + + + 源文件 + + + + + 头文件 + + + 头文件 + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/05.38.2/05.38.2.vcxproj.user b/VisualC++/ExerciseBook/05.38.2/05.38.2.vcxproj.user new file mode 100644 index 0000000..ace9a86 --- /dev/null +++ b/VisualC++/ExerciseBook/05.38.2/05.38.2.vcxproj.user @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/05.38.2/GList-E.c b/VisualC++/ExerciseBook/05.38.2/GList-E.c new file mode 100644 index 0000000..3fc0ad9 --- /dev/null +++ b/VisualC++/ExerciseBook/05.38.2/GList-E.c @@ -0,0 +1,449 @@ +/*=========================== + * չ洢ʾ + ============================*/ + +#include "GList-E.h" //**05 ͹**// + +/* + * ʼ + * + * ʼյĹΪ0Ϊ1 + * + *ע + * Ҫÿһſ + */ +Status InitGList(GList* L) { + if(L == NULL) { + return ERROR; + } + + *L = (GList) malloc(sizeof(GLNode)); + if(!*L) { + exit(OVERFLOW); + } + + (*L)->tag = List; + (*L)->Node.hp = NULL; + (*L)->tp = NULL; + + return OK; +} + +/* + * + * + * ַSL + */ +Status CreateGList(GList* L, SString S) { + SString emp, hsub, sub, tmp; + + if(L == NULL) { + return ERROR; + } + + // ַSеĿհףɴӡַո + ClearBlank(S); + + if(StrEmpty(S)) { + return ERROR; + } + + // Ϊ˲ƻS + StrCopy(sub, S); + + /* + * ִеʱ + * ٴִеʱѾȥ + */ + sever(hsub, sub); + + *L = (GList) malloc(sizeof(GLNode)); + if(*L == NULL) { + exit(OVERFLOW); + } + + StrAssign(emp, "()"); + + if(!StrCompare(hsub, emp)) { + (*L)->tag = List; + (*L)->Node.hp = NULL; + } else { + if(StrLength(hsub) == 1) { + (*L)->tag = Atom; + (*L)->Node.atom = hsub[1]; + } else { + (*L)->tag = List; + + SubString(tmp, hsub, 2, StrLength(hsub) - 2); + + CreateGList(&((*L)->Node.hp), tmp); + } + } + + // ڶβ˳ݹ + if(StrEmpty(sub)) { + (*L)->tp = NULL; + } else { + // ݹβ + CreateGList(&((*L)->tp), sub); + } + + return OK; +} + +/* + * + * + * ͷŹռڴ档 + */ +Status DestroyGList(GList* L) { + GList head, tail; + + if(L == NULL || *L == NULL) { + return ERROR; + } + + // ӱ + if((*L)->tag == List) { + head = (*L)->Node.hp; // ͷ + tail = (*L)->tp; // β + + free(*L); + *L = NULL; + + // ݹ鴦ͷ + if(head != NULL) { + DestroyGList(&head); + } + + // ݹ鴦β + if(tail != NULL) { + DestroyGList(&tail); + } + + // ԭӽ + } else { + tail = (*L)->tp; // β + + free(*L); + *L = NULL; + + if(tail != NULL) { + DestroyGList(&tail); + } + } + + return OK; +} + +/* + * + * + * ɹLƵõT + */ +Status CopyGList(GList* T, GList L) { + + if(L == NULL) { + return ERROR; + } + + *T = (GList) malloc(sizeof(GLNode)); + if(*T == NULL) { + exit(OVERFLOW); + } + + // ԭ + if(L->tag == Atom) { + (*T)->tag = Atom; + (*T)->Node.atom = L->Node.atom; + + // ӱ + } else { + (*T)->tag = List; + + // Ʊͷ + if(L->Node.hp != NULL) { + CopyGList(&((*T)->Node.hp), L->Node.hp); + } else { + (*T)->Node.hp = NULL; + } + } + + // Ʊβ + if(L->tp != NULL) { + CopyGList(&((*T)->tp), L->tp); + } else { + (*T)->tp = NULL; + } + + return OK; +} + +/* + * + * + * عijȡ + */ +int GListLength(GList L) { + int count = 0; + GList p; + + // + if(L == NULL) { + return -1; + } + + p = L->Node.hp; + + while(p != NULL) { + ++count; + p = p->tp; + } + + return count; +} + +/* + * + * + * ع + */ +int GListDepth(GList L) { + int max, deep; + GList p; + + max = 0; + + // + if(L == NULL) { + return -1; + } + + // ձΪ1 + if(L->tag == List && !L->Node.hp) { + return 1; + } + + // ԭΪ0 + if(L->tag == Atom) { + return 0; + } + + // ݹӱ + for(p = L->Node.hp; p != NULL; p = p->tp) { + // pΪͷָӱ + deep = GListDepth(p); + if(deep > max) { + max = deep; + } + } + + return max + 1; +} + +/* + * п + * + * жϹǷΪա + */ +Status GListEmpty(GList L) { + // + if(L == NULL) { + return ERROR; + } + + if(L->tag == List && L->Node.hp == NULL && L->tp == NULL) { + return TRUE; + } else { + return ERROR; + } +} + +/* + * ͷ + */ +GList GetHead(GList L) { + GList p, q; + + // ڻΪձ޷ȡͷ + if(L == NULL || L->Node.hp == NULL) { + return NULL; + } + + q = L->Node.hp->tp; // ʱLıβϢ + L->Node.hp->tp = NULL; // ȥLıβ + + CopyGList(&p, L->Node.hp); // ƱͷϢαβ + + L->Node.hp->tp = q; // ָLıβϢ + + return p; +} + +/* + * β + */ +GList GetTail(GList L) { + GList p, q; + + // ڻΪձ޷ȡβ + if(L == NULL || L->Node.hp == NULL) { + return NULL; + } + + q = L->Node.hp; // ʱLıͷϢ + L->Node.hp = q->tp; // ժLıͷ + + CopyGList(&p, L); // ƱβϢαͷ + + q->tp = L->Node.hp; // ָLıͷϢ + L->Node.hp = q; + + return p; +} + +/* + * + * + * ԪeΪLĵһԪء + */ +Status InsertFirst(GList* L, GList e) { + + // + if(L == NULL || *L == NULL) { + return ERROR; + } + + if(e == NULL) { + return ERROR; + } + + e->tp = (*L)->Node.hp; + (*L)->Node.hp = e; + + return OK; +} + +/* + * ɾ + * + * LĵһԪɾeء + */ +Status DeleteFirst(GList* L, GList* e) { + GList p; + + // ڻΪձ޷ɾͷ + if(*L == NULL || (*L)->Node.hp == NULL) { + return ERROR; + } + + p = (*L)->Node.hp; + (*L)->Node.hp = p->tp; + p->tp = NULL; + + *e = p; + + return OK; +} + +/* + * + * + * visitʹL + */ +void Traverse(GList L, void(Visit)(AtomType)) { + if(L == NULL) { + return; + } + + if(L->tag == List) { + Traverse(L->Node.hp, Visit); + } else { + Visit(L->Node.atom); + } + + Traverse(L->tp, Visit); +} + +/* + * ͼλ + * + * L + */ +void PrintGraph(GList L) { + Print(L); + printf("\n"); +} + +/* + * ͼλڲʵ֡ + */ +static void Print(GList L) { + if(L == NULL) { + return; + } + + // + if(L->tag == List) { + printf("("); + + if(L->Node.hp) { + Print(L->Node.hp); + } + + if(L->tp) { + printf("),"); + Print(L->tp); + } else { + printf(")"); + } + + // ԭӽ + } else { + printf("%c", L->Node.atom); + if(L->tp) { + printf(","); + Print(L->tp); + } + } +} + +/* + * ǿմstrָ֣hsubΪһ','֮ǰӴstrΪһ','֮Ӵ + * + *ע + * 1.ַstrȷ޿հ׷ţ + * strſȥҲδȥ + * 2.ɺstrҲᷢ仯 + */ +static void sever(SString hstr, SString str) { + int i, k, n; + SString ch; + + n = StrLength(str); + + i = 0; // ַʱα + k = 0; // δ + + do { + ++i; + + // ȡstrһַ + SubString(ch, str, i, 1); + + if(ch[1] == '(') { + ++k; + } + if(ch[1] == ')') { + --k; + } + } while(i < n && (ch[1] != ',' || k != 0)); + + if(i < n) { + SubString(hstr, str, 1, i - 1); + SubString(str, str, i + 1, n - i); + } else { + StrCopy(hstr, str); + ClearString(str); + } +} diff --git a/VisualC++/ExerciseBook/05.38.2/GList-E.h b/VisualC++/ExerciseBook/05.38.2/GList-E.h new file mode 100644 index 0000000..fa9af82 --- /dev/null +++ b/VisualC++/ExerciseBook/05.38.2/GList-E.h @@ -0,0 +1,146 @@ +/*=========================== + * չ洢ʾ + ============================*/ + +#ifndef GLIST_E_H +#define GLIST_E_H + +#include +#include // ṩ mallocreallocfreeexit ԭ +#include "Status.h" //**01 **// +#include "SString.h" //**04 **// + +/* ԭԪ */ +typedef char AtomType; //ԭ + +/* + * + * + * Atom-0ԭӽ + * List-1 + */ +typedef enum { Atom, List } ElemTag; + +/* չ洢ʾͶ */ +typedef struct GLNode { + ElemTag tag; // ǣԭӽͱ + + // ԭӽͱϲ + union + { + AtomType atom; // atomԭӽֵAtomTypeû + struct GLNode* hp; // ָͷ + } Node; + struct GLNode* tp; // ָβ +} GLNode; + +/* */ +typedef GLNode* GList; + + +/* + * ʼ + * + * ʼյĹΪ0Ϊ1 + * + *ע + * Ҫÿһſ + */ +Status InitGList(GList* L); + +/* + * + * + * ַSL + */ +Status CreateGList(GList* L, SString S); + +/* + * + * + * ͷŹռڴ档 + */ +Status DestroyGList(GList* L); + +/* + * + * + * ɹLƵõT + */ +Status CopyGList(GList* T, GList L); + +/* + * + * + * عijȡ + */ +int GListLength(GList L); + +/* + * + * + * ع + */ +int GListDepth(GList L); + +/* + * п + * + * жϹǷΪա + */ +Status GListEmpty(GList L); + +/* + * ͷ + */ +GList GetHead(GList L); + +/* + * β + */ +GList GetTail(GList L); + +/* + * + * + * ԪeΪLĵһԪء + */ +Status InsertFirst(GList* L, GList e); + +/* + * ɾ + * + * LĵһԪɾeء + */ +Status DeleteFirst(GList* L, GList* e); + +/* + * + * + * visitʹL + */ +void Traverse(GList L, void(Visit)(AtomType)); + +/* + * ͼλ + * + * L + */ +void PrintGraph(GList L); + +/* + * ͼλڲʵ֡ + */ +static void Print(GList L); + +/* + * ǿմstrָ֣hsubΪһ','֮ǰӴstrΪһ','֮Ӵ + * + *ע + * 1.ַstrȷ޿հ׷ţ + * strſȥҲδȥ + * 2.ɺstrҲᷢ仯 + */ +static void sever(SString hstr, SString str); + +#endif diff --git a/VisualC++/ExerciseBook/05.38.2/SString.c b/VisualC++/ExerciseBook/05.38.2/SString.c new file mode 100644 index 0000000..7a96fcf --- /dev/null +++ b/VisualC++/ExerciseBook/05.38.2/SString.c @@ -0,0 +1,195 @@ +/*============================= + * Ķ˳洢ʾ˳򴮣 + * + * 㷨: 4.14.24.34.5 + ==============================*/ + +#include "SString.h" //**04 **// + +/* + * ʼ + * + * һֵΪcharsĴT + * + *ע + * òСӼ + */ +Status StrAssign(SString T, const char* chars) { + int i, len; + + len = (int) strlen(chars); + + // chars + if(len > MAXSTRLEN) { + return ERROR; + } + + T[0] = len; + for(i = 1; i <= len; i++) { + T[i] = chars[i - 1]; + } + + return OK; +} + +/* + * + * + * Sա + */ +Status ClearString(SString S) { + // ֻҪΪ0Ϳ + S[0] = 0; + return OK; +} + +/* + * п + * + * жϴSǷЧݡ + * + * ֵ + * TRUE : SΪ + * FALSE: SΪ + */ +Status StrEmpty(SString S) { + return S[0] == 0 ? TRUE : FALSE; +} + +/* + * + * + * شSԪصĸ + * + *ע + * òСӼ + */ +int StrLength(SString S) { + return S[0]; +} + +/* + * 㷨4.3 + * + * Ӵ + * + * SubS[pos, pos+len-1] + * ֵָʾǷȡɹ + * + *ע + * òСӼ + */ +Status SubString(SString Sub, SString S, int pos, int len) { + int i; + + if(pos < 1 || pos > S[0] || len < 0 || pos + len - 1 > S[0]) { + return ERROR; + } + + // Ԫ + for(i = 1; i <= len; i++) { + Sub[i] = S[pos + i - 1]; + } + + // ȷ³ + Sub[0] = len; + + return OK; +} + +/* + * ɾ + * + * ɾS[pos, pos+len-1] + */ +Status StrDelete(SString S, int pos, int len) { + int i; + + if(pos < 1 || pos + len - 1 > S[0] || len < 0) { + return ERROR; + } + + // ɾijΪ0ǰ + if(len == 0) { + return OK; + } + + // ѺԪŲǰ棬ǵɾԪ + for(i = pos + len; i <= S[0]; i++) { + S[i - len] = S[i]; + } + + // ȼ + S[0] -= len; + + return OK; +} + +/* + * Ƚ + * + * ȽϴSʹTرȽϽ + * + *ע + * òСӼ + */ +int StrCompare(SString S, SString T) { + int i = 1; + + while(i <= S[0] && i <= T[0]) { + // ַͬʱȽС + if(S[i] != T[i]) { + return S[i] - T[i]; + } + + i++; + } + + return S[0] - T[0]; +} + +/* + * + * + * SƵT + */ +Status StrCopy(SString T, SString S) { + int i; + + // ͬϢһ + for(i = 0; i <= S[0]; i++) { + T[i] = S[i]; + } + + return OK; +} + +/* + * ַSеĿհףɴӡַո + * + *ע + * úڱġ + */ +Status ClearBlank(SString S) { + int i, j; + + // ǿմ + if(S[0] == 0) { + return ERROR; + } + + for(i = 1, j = 0; i <= S[0]; i++) { + // հףԹ + if(S[i] == ' ' || !isprint(S[i])) { + continue; + } + + j++; + + S[j] = S[i]; + } + + S[0] = j; + + return OK; +} diff --git a/VisualC++/ExerciseBook/05.38.2/SString.h b/VisualC++/ExerciseBook/05.38.2/SString.h new file mode 100644 index 0000000..0632f18 --- /dev/null +++ b/VisualC++/ExerciseBook/05.38.2/SString.h @@ -0,0 +1,117 @@ +/*============================= + * Ķ˳洢ʾ˳򴮣 + * + * 㷨: 4.14.24.34.5 + ==============================*/ + +#ifndef SSTRING_H +#define SSTRING_H + +#include +#include // ṩ strlen ԭ +#include // ṩ isprint ԭ +#include "Status.h" //**01 **// + +/* 궨 */ +#define MAXSTRLEN 255 // ˳򴮵󴮳 + +/* + * ˳洢Ͷ + * + * עЧԪشSString1ŵԪʼ洢 + * SString0ŵԪ洢䳤 + */ +typedef unsigned char SString[MAXSTRLEN + 1]; // 0ŵԪŴij + + +/* + * ʾ + * + * ѭ̲ĵдϰߣposָʾַλ()1ʼ + */ + + +/* + * ʼ + * + * һֵΪcharsĴT + * + *ע + * òСӼ + */ +Status StrAssign(SString T, const char* chars); + +/* + * + * + * Sա + */ +Status ClearString(SString S); + +/* + * п + * + * жϴSǷЧݡ + * + * ֵ + * TRUE : SΪ + * FALSE: SΪ + */ +Status StrEmpty(SString S); + +/* + * + * + * شSԪصĸ + * + *ע + * òСӼ + */ +int StrLength(SString S); + +/* + * 㷨4.3 + * + * Ӵ + * + * SubS[pos, pos+len-1] + * ֵָʾǷȡɹ + * + *ע + * òСӼ + */ +Status SubString(SString Sub, SString S, int pos, int len); + +/* + * ɾ + * + * ɾS[pos, pos+len-1] + */ +Status StrDelete(SString S, int pos, int len); + +/* + * Ƚ + * + * ȽϴSʹTرȽϽ + * + *ע + * òСӼ + */ +int StrCompare(SString S, SString T); + +/* + * + * + * SƵT + */ +Status StrCopy(SString T, SString S); + +/* + * ַSеĿհףɴӡַո + * + *ע + * úڱġ + */ +Status ClearBlank(SString S); + +#endif diff --git a/VisualC++/ExerciseBook/ExerciseBook.sdf b/VisualC++/ExerciseBook/ExerciseBook.sdf index 67505ba..4eadf33 100644 Binary files a/VisualC++/ExerciseBook/ExerciseBook.sdf and b/VisualC++/ExerciseBook/ExerciseBook.sdf differ diff --git a/VisualC++/ExerciseBook/ExerciseBook.sln b/VisualC++/ExerciseBook/ExerciseBook.sln index 9d20288..df7ec92 100644 --- a/VisualC++/ExerciseBook/ExerciseBook.sln +++ b/VisualC++/ExerciseBook/ExerciseBook.sln @@ -133,6 +133,58 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "04.30", "04.30\04.30.vcxpro EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "04.31", "04.31\04.31.vcxproj", "{2FB26990-0C5E-47FB-9D0F-E3A202D2A47F}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "05.17", "05.17\05.17.vcxproj", "{AD70051F-9782-4A15-A23D-76E1E8A6CC68}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "05.18", "05.18\05.18.vcxproj", "{DEAB729F-1809-4FAC-93DC-9E42774A3BFA}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "05.19", "05.19\05.19.vcxproj", "{0E1F3F75-49AB-4167-83E2-C118DB269292}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "05.20", "05.20\05.20.vcxproj", "{685BE3FF-10F8-417E-9601-7CDE7AEFAC0B}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "05.21", "05.21\05.21.vcxproj", "{2E30EE16-A652-4316-8FBC-6245559F35E3}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "05.22", "05.22\05.22.vcxproj", "{AF31443B-830F-4A4C-A72D-40FC9ACE5654}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "05.23", "05.23\05.23.vcxproj", "{D342BB95-DAA3-4C66-889A-9DC49DA213B0}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "05.24", "05.24\05.24.vcxproj", "{7B1D365B-1574-45A1-AECD-1E16A521398B}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "05.25", "05.25\05.25.vcxproj", "{0E85120D-878D-4F74-9D6E-2BC465659A38}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "05.26", "05.26\05.26.vcxproj", "{A124BA87-11B9-4329-8572-F4D3EAE759E8}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "05.27", "05.27\05.27.vcxproj", "{EF60CDEA-A37D-4A91-ABB9-95D41D970927}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "05.28-05.29", "05.28-05.29\05.28-05.29.vcxproj", "{1E4BBDA3-6E21-433D-95B3-CCBB7A450A34}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "05.30.1", "05.30.1\05.30.1.vcxproj", "{404AA05D-2412-4645-9E2C-280BFC6284FD}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "05.30.2", "05.30.2\05.30.2.vcxproj", "{986E6EF4-6118-4504-9667-3B86BC71D7CC}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "05.31", "05.31\05.31.vcxproj", "{F63981E9-26D4-4EF9-82F5-1482260619CF}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "05.32.1", "05.32.1\05.32.1.vcxproj", "{CF15AF01-BA4A-45D2-89DC-98FF7B722AB0}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "05.32.2", "05.32.2\05.32.2.vcxproj", "{2C7DDD17-6590-4684-826B-AEC0A0E4221A}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "05.33.1", "05.33.1\05.33.1.vcxproj", "{4862063F-4D32-4C02-AF63-35381605EDFE}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "05.33.2", "05.33.2\05.33.2.vcxproj", "{D7EEED63-8BE4-4754-9657-D2276236E34A}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "05.34.1", "05.34.1\05.34.1.vcxproj", "{0E9C5F8C-656A-4535-A61F-53E62C8F005A}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "05.34.2", "05.34.2\05.34.2.vcxproj", "{D367E1DB-CCB7-4911-8805-1C25A41543FD}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "05.35-05.36", "05.35-05.36\05.35-05.36.vcxproj", "{5F387672-C799-4368-9203-BA5CBAB5387D}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "05.37.1", "05.37.1\05.37.1.vcxproj", "{C034ACF3-B096-4A56-975A-A8497FC86E14}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "05.37.2", "05.37.2\05.37.2.vcxproj", "{960F0527-2A12-49C5-B79C-21EBF9528B6C}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "05.38.1", "05.38.1\05.38.1.vcxproj", "{679BE61B-60DE-4BC3-B8B0-B414175A376C}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "05.38.2", "05.38.2\05.38.2.vcxproj", "{564E9CB9-3C86-4823-98A5-777D1B0A3104}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 @@ -403,6 +455,110 @@ Global {2FB26990-0C5E-47FB-9D0F-E3A202D2A47F}.Debug|Win32.Build.0 = Debug|Win32 {2FB26990-0C5E-47FB-9D0F-E3A202D2A47F}.Release|Win32.ActiveCfg = Release|Win32 {2FB26990-0C5E-47FB-9D0F-E3A202D2A47F}.Release|Win32.Build.0 = Release|Win32 + {AD70051F-9782-4A15-A23D-76E1E8A6CC68}.Debug|Win32.ActiveCfg = Debug|Win32 + {AD70051F-9782-4A15-A23D-76E1E8A6CC68}.Debug|Win32.Build.0 = Debug|Win32 + {AD70051F-9782-4A15-A23D-76E1E8A6CC68}.Release|Win32.ActiveCfg = Release|Win32 + {AD70051F-9782-4A15-A23D-76E1E8A6CC68}.Release|Win32.Build.0 = Release|Win32 + {DEAB729F-1809-4FAC-93DC-9E42774A3BFA}.Debug|Win32.ActiveCfg = Debug|Win32 + {DEAB729F-1809-4FAC-93DC-9E42774A3BFA}.Debug|Win32.Build.0 = Debug|Win32 + {DEAB729F-1809-4FAC-93DC-9E42774A3BFA}.Release|Win32.ActiveCfg = Release|Win32 + {DEAB729F-1809-4FAC-93DC-9E42774A3BFA}.Release|Win32.Build.0 = Release|Win32 + {0E1F3F75-49AB-4167-83E2-C118DB269292}.Debug|Win32.ActiveCfg = Debug|Win32 + {0E1F3F75-49AB-4167-83E2-C118DB269292}.Debug|Win32.Build.0 = Debug|Win32 + {0E1F3F75-49AB-4167-83E2-C118DB269292}.Release|Win32.ActiveCfg = Release|Win32 + {0E1F3F75-49AB-4167-83E2-C118DB269292}.Release|Win32.Build.0 = Release|Win32 + {685BE3FF-10F8-417E-9601-7CDE7AEFAC0B}.Debug|Win32.ActiveCfg = Debug|Win32 + {685BE3FF-10F8-417E-9601-7CDE7AEFAC0B}.Debug|Win32.Build.0 = Debug|Win32 + {685BE3FF-10F8-417E-9601-7CDE7AEFAC0B}.Release|Win32.ActiveCfg = Release|Win32 + {685BE3FF-10F8-417E-9601-7CDE7AEFAC0B}.Release|Win32.Build.0 = Release|Win32 + {2E30EE16-A652-4316-8FBC-6245559F35E3}.Debug|Win32.ActiveCfg = Debug|Win32 + {2E30EE16-A652-4316-8FBC-6245559F35E3}.Debug|Win32.Build.0 = Debug|Win32 + {2E30EE16-A652-4316-8FBC-6245559F35E3}.Release|Win32.ActiveCfg = Release|Win32 + {2E30EE16-A652-4316-8FBC-6245559F35E3}.Release|Win32.Build.0 = Release|Win32 + {AF31443B-830F-4A4C-A72D-40FC9ACE5654}.Debug|Win32.ActiveCfg = Debug|Win32 + {AF31443B-830F-4A4C-A72D-40FC9ACE5654}.Debug|Win32.Build.0 = Debug|Win32 + {AF31443B-830F-4A4C-A72D-40FC9ACE5654}.Release|Win32.ActiveCfg = Release|Win32 + {AF31443B-830F-4A4C-A72D-40FC9ACE5654}.Release|Win32.Build.0 = Release|Win32 + {D342BB95-DAA3-4C66-889A-9DC49DA213B0}.Debug|Win32.ActiveCfg = Debug|Win32 + {D342BB95-DAA3-4C66-889A-9DC49DA213B0}.Debug|Win32.Build.0 = Debug|Win32 + {D342BB95-DAA3-4C66-889A-9DC49DA213B0}.Release|Win32.ActiveCfg = Release|Win32 + {D342BB95-DAA3-4C66-889A-9DC49DA213B0}.Release|Win32.Build.0 = Release|Win32 + {7B1D365B-1574-45A1-AECD-1E16A521398B}.Debug|Win32.ActiveCfg = Debug|Win32 + {7B1D365B-1574-45A1-AECD-1E16A521398B}.Debug|Win32.Build.0 = Debug|Win32 + {7B1D365B-1574-45A1-AECD-1E16A521398B}.Release|Win32.ActiveCfg = Release|Win32 + {7B1D365B-1574-45A1-AECD-1E16A521398B}.Release|Win32.Build.0 = Release|Win32 + {0E85120D-878D-4F74-9D6E-2BC465659A38}.Debug|Win32.ActiveCfg = Debug|Win32 + {0E85120D-878D-4F74-9D6E-2BC465659A38}.Debug|Win32.Build.0 = Debug|Win32 + {0E85120D-878D-4F74-9D6E-2BC465659A38}.Release|Win32.ActiveCfg = Release|Win32 + {0E85120D-878D-4F74-9D6E-2BC465659A38}.Release|Win32.Build.0 = Release|Win32 + {A124BA87-11B9-4329-8572-F4D3EAE759E8}.Debug|Win32.ActiveCfg = Debug|Win32 + {A124BA87-11B9-4329-8572-F4D3EAE759E8}.Debug|Win32.Build.0 = Debug|Win32 + {A124BA87-11B9-4329-8572-F4D3EAE759E8}.Release|Win32.ActiveCfg = Release|Win32 + {A124BA87-11B9-4329-8572-F4D3EAE759E8}.Release|Win32.Build.0 = Release|Win32 + {EF60CDEA-A37D-4A91-ABB9-95D41D970927}.Debug|Win32.ActiveCfg = Debug|Win32 + {EF60CDEA-A37D-4A91-ABB9-95D41D970927}.Debug|Win32.Build.0 = Debug|Win32 + {EF60CDEA-A37D-4A91-ABB9-95D41D970927}.Release|Win32.ActiveCfg = Release|Win32 + {EF60CDEA-A37D-4A91-ABB9-95D41D970927}.Release|Win32.Build.0 = Release|Win32 + {1E4BBDA3-6E21-433D-95B3-CCBB7A450A34}.Debug|Win32.ActiveCfg = Debug|Win32 + {1E4BBDA3-6E21-433D-95B3-CCBB7A450A34}.Debug|Win32.Build.0 = Debug|Win32 + {1E4BBDA3-6E21-433D-95B3-CCBB7A450A34}.Release|Win32.ActiveCfg = Release|Win32 + {1E4BBDA3-6E21-433D-95B3-CCBB7A450A34}.Release|Win32.Build.0 = Release|Win32 + {404AA05D-2412-4645-9E2C-280BFC6284FD}.Debug|Win32.ActiveCfg = Debug|Win32 + {404AA05D-2412-4645-9E2C-280BFC6284FD}.Debug|Win32.Build.0 = Debug|Win32 + {404AA05D-2412-4645-9E2C-280BFC6284FD}.Release|Win32.ActiveCfg = Release|Win32 + {404AA05D-2412-4645-9E2C-280BFC6284FD}.Release|Win32.Build.0 = Release|Win32 + {986E6EF4-6118-4504-9667-3B86BC71D7CC}.Debug|Win32.ActiveCfg = Debug|Win32 + {986E6EF4-6118-4504-9667-3B86BC71D7CC}.Debug|Win32.Build.0 = Debug|Win32 + {986E6EF4-6118-4504-9667-3B86BC71D7CC}.Release|Win32.ActiveCfg = Release|Win32 + {986E6EF4-6118-4504-9667-3B86BC71D7CC}.Release|Win32.Build.0 = Release|Win32 + {F63981E9-26D4-4EF9-82F5-1482260619CF}.Debug|Win32.ActiveCfg = Debug|Win32 + {F63981E9-26D4-4EF9-82F5-1482260619CF}.Debug|Win32.Build.0 = Debug|Win32 + {F63981E9-26D4-4EF9-82F5-1482260619CF}.Release|Win32.ActiveCfg = Release|Win32 + {F63981E9-26D4-4EF9-82F5-1482260619CF}.Release|Win32.Build.0 = Release|Win32 + {CF15AF01-BA4A-45D2-89DC-98FF7B722AB0}.Debug|Win32.ActiveCfg = Debug|Win32 + {CF15AF01-BA4A-45D2-89DC-98FF7B722AB0}.Debug|Win32.Build.0 = Debug|Win32 + {CF15AF01-BA4A-45D2-89DC-98FF7B722AB0}.Release|Win32.ActiveCfg = Release|Win32 + {CF15AF01-BA4A-45D2-89DC-98FF7B722AB0}.Release|Win32.Build.0 = Release|Win32 + {2C7DDD17-6590-4684-826B-AEC0A0E4221A}.Debug|Win32.ActiveCfg = Debug|Win32 + {2C7DDD17-6590-4684-826B-AEC0A0E4221A}.Debug|Win32.Build.0 = Debug|Win32 + {2C7DDD17-6590-4684-826B-AEC0A0E4221A}.Release|Win32.ActiveCfg = Release|Win32 + {2C7DDD17-6590-4684-826B-AEC0A0E4221A}.Release|Win32.Build.0 = Release|Win32 + {4862063F-4D32-4C02-AF63-35381605EDFE}.Debug|Win32.ActiveCfg = Debug|Win32 + {4862063F-4D32-4C02-AF63-35381605EDFE}.Debug|Win32.Build.0 = Debug|Win32 + {4862063F-4D32-4C02-AF63-35381605EDFE}.Release|Win32.ActiveCfg = Release|Win32 + {4862063F-4D32-4C02-AF63-35381605EDFE}.Release|Win32.Build.0 = Release|Win32 + {D7EEED63-8BE4-4754-9657-D2276236E34A}.Debug|Win32.ActiveCfg = Debug|Win32 + {D7EEED63-8BE4-4754-9657-D2276236E34A}.Debug|Win32.Build.0 = Debug|Win32 + {D7EEED63-8BE4-4754-9657-D2276236E34A}.Release|Win32.ActiveCfg = Release|Win32 + {D7EEED63-8BE4-4754-9657-D2276236E34A}.Release|Win32.Build.0 = Release|Win32 + {0E9C5F8C-656A-4535-A61F-53E62C8F005A}.Debug|Win32.ActiveCfg = Debug|Win32 + {0E9C5F8C-656A-4535-A61F-53E62C8F005A}.Debug|Win32.Build.0 = Debug|Win32 + {0E9C5F8C-656A-4535-A61F-53E62C8F005A}.Release|Win32.ActiveCfg = Release|Win32 + {0E9C5F8C-656A-4535-A61F-53E62C8F005A}.Release|Win32.Build.0 = Release|Win32 + {D367E1DB-CCB7-4911-8805-1C25A41543FD}.Debug|Win32.ActiveCfg = Debug|Win32 + {D367E1DB-CCB7-4911-8805-1C25A41543FD}.Debug|Win32.Build.0 = Debug|Win32 + {D367E1DB-CCB7-4911-8805-1C25A41543FD}.Release|Win32.ActiveCfg = Release|Win32 + {D367E1DB-CCB7-4911-8805-1C25A41543FD}.Release|Win32.Build.0 = Release|Win32 + {5F387672-C799-4368-9203-BA5CBAB5387D}.Debug|Win32.ActiveCfg = Debug|Win32 + {5F387672-C799-4368-9203-BA5CBAB5387D}.Debug|Win32.Build.0 = Debug|Win32 + {5F387672-C799-4368-9203-BA5CBAB5387D}.Release|Win32.ActiveCfg = Release|Win32 + {5F387672-C799-4368-9203-BA5CBAB5387D}.Release|Win32.Build.0 = Release|Win32 + {C034ACF3-B096-4A56-975A-A8497FC86E14}.Debug|Win32.ActiveCfg = Debug|Win32 + {C034ACF3-B096-4A56-975A-A8497FC86E14}.Debug|Win32.Build.0 = Debug|Win32 + {C034ACF3-B096-4A56-975A-A8497FC86E14}.Release|Win32.ActiveCfg = Release|Win32 + {C034ACF3-B096-4A56-975A-A8497FC86E14}.Release|Win32.Build.0 = Release|Win32 + {960F0527-2A12-49C5-B79C-21EBF9528B6C}.Debug|Win32.ActiveCfg = Debug|Win32 + {960F0527-2A12-49C5-B79C-21EBF9528B6C}.Debug|Win32.Build.0 = Debug|Win32 + {960F0527-2A12-49C5-B79C-21EBF9528B6C}.Release|Win32.ActiveCfg = Release|Win32 + {960F0527-2A12-49C5-B79C-21EBF9528B6C}.Release|Win32.Build.0 = Release|Win32 + {679BE61B-60DE-4BC3-B8B0-B414175A376C}.Debug|Win32.ActiveCfg = Debug|Win32 + {679BE61B-60DE-4BC3-B8B0-B414175A376C}.Debug|Win32.Build.0 = Debug|Win32 + {679BE61B-60DE-4BC3-B8B0-B414175A376C}.Release|Win32.ActiveCfg = Release|Win32 + {679BE61B-60DE-4BC3-B8B0-B414175A376C}.Release|Win32.Build.0 = Release|Win32 + {564E9CB9-3C86-4823-98A5-777D1B0A3104}.Debug|Win32.ActiveCfg = Debug|Win32 + {564E9CB9-3C86-4823-98A5-777D1B0A3104}.Debug|Win32.Build.0 = Debug|Win32 + {564E9CB9-3C86-4823-98A5-777D1B0A3104}.Release|Win32.ActiveCfg = Release|Win32 + {564E9CB9-3C86-4823-98A5-777D1B0A3104}.Release|Win32.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/VisualC++/ExerciseBook/ExerciseBook.suo b/VisualC++/ExerciseBook/ExerciseBook.suo index f24f957..ae6da02 100644 Binary files a/VisualC++/ExerciseBook/ExerciseBook.suo and b/VisualC++/ExerciseBook/ExerciseBook.suo differ diff --git a/习题解析/05 数组和广义表/_v_images/20181128024131486_26584.png b/习题解析/05 数组和广义表/_v_images/20181128024131486_26584.png new file mode 100644 index 0000000..515b845 Binary files /dev/null and b/习题解析/05 数组和广义表/_v_images/20181128024131486_26584.png differ diff --git a/习题解析/05 数组和广义表/_v_images/20181128024617431_31991.png b/习题解析/05 数组和广义表/_v_images/20181128024617431_31991.png new file mode 100644 index 0000000..f075734 Binary files /dev/null and b/习题解析/05 数组和广义表/_v_images/20181128024617431_31991.png differ diff --git a/习题解析/05 数组和广义表/_v_images/20181128024818024_1955.png b/习题解析/05 数组和广义表/_v_images/20181128024818024_1955.png new file mode 100644 index 0000000..1de169e Binary files /dev/null and b/习题解析/05 数组和广义表/_v_images/20181128024818024_1955.png differ diff --git a/习题解析/05 数组和广义表/_v_images/20181128024844354_32694.png b/习题解析/05 数组和广义表/_v_images/20181128024844354_32694.png new file mode 100644 index 0000000..6c37700 Binary files /dev/null and b/习题解析/05 数组和广义表/_v_images/20181128024844354_32694.png differ diff --git a/习题解析/05 数组和广义表/_v_images/20181128024901661_11428.png b/习题解析/05 数组和广义表/_v_images/20181128024901661_11428.png new file mode 100644 index 0000000..59f4cd9 Binary files /dev/null and b/习题解析/05 数组和广义表/_v_images/20181128024901661_11428.png differ diff --git a/习题解析/05 数组和广义表/_v_images/20181128024915115_3609.png b/习题解析/05 数组和广义表/_v_images/20181128024915115_3609.png new file mode 100644 index 0000000..56bc00c Binary files /dev/null and b/习题解析/05 数组和广义表/_v_images/20181128024915115_3609.png differ diff --git a/习题解析/05 数组和广义表/_v_images/20181128025105462_31218.png b/习题解析/05 数组和广义表/_v_images/20181128025105462_31218.png new file mode 100644 index 0000000..e933260 Binary files /dev/null and b/习题解析/05 数组和广义表/_v_images/20181128025105462_31218.png differ diff --git a/习题解析/05 数组和广义表/_v_images/20181128025241824_32225.png b/习题解析/05 数组和广义表/_v_images/20181128025241824_32225.png new file mode 100644 index 0000000..205d50e Binary files /dev/null and b/习题解析/05 数组和广义表/_v_images/20181128025241824_32225.png differ diff --git a/习题解析/05 数组和广义表/_v_images/20181128025435346_25694.png b/习题解析/05 数组和广义表/_v_images/20181128025435346_25694.png new file mode 100644 index 0000000..228c6fd Binary files /dev/null and b/习题解析/05 数组和广义表/_v_images/20181128025435346_25694.png differ diff --git a/习题解析/05 数组和广义表/_v_images/20181128025526044_25756.png b/习题解析/05 数组和广义表/_v_images/20181128025526044_25756.png new file mode 100644 index 0000000..1c24b9a Binary files /dev/null and b/习题解析/05 数组和广义表/_v_images/20181128025526044_25756.png differ diff --git a/习题解析/05 数组和广义表/_v_images/20181128025550464_16430.png b/习题解析/05 数组和广义表/_v_images/20181128025550464_16430.png new file mode 100644 index 0000000..522446a Binary files /dev/null and b/习题解析/05 数组和广义表/_v_images/20181128025550464_16430.png differ diff --git a/习题解析/05 数组和广义表/_v_images/20181128025752290_16510.png b/习题解析/05 数组和广义表/_v_images/20181128025752290_16510.png new file mode 100644 index 0000000..0ce5342 Binary files /dev/null and b/习题解析/05 数组和广义表/_v_images/20181128025752290_16510.png differ diff --git a/习题解析/05 数组和广义表/_v_images/20181128025833026_20359.png b/习题解析/05 数组和广义表/_v_images/20181128025833026_20359.png new file mode 100644 index 0000000..49653cd Binary files /dev/null and b/习题解析/05 数组和广义表/_v_images/20181128025833026_20359.png differ diff --git a/习题解析/05 数组和广义表/_v_images/20181128025848038_32716.png b/习题解析/05 数组和广义表/_v_images/20181128025848038_32716.png new file mode 100644 index 0000000..a6a8956 Binary files /dev/null and b/习题解析/05 数组和广义表/_v_images/20181128025848038_32716.png differ diff --git a/习题解析/05 数组和广义表/_v_images/20181128025918606_14220.png b/习题解析/05 数组和广义表/_v_images/20181128025918606_14220.png new file mode 100644 index 0000000..fcc68c5 Binary files /dev/null and b/习题解析/05 数组和广义表/_v_images/20181128025918606_14220.png differ diff --git a/习题解析/05 数组和广义表/_v_images/20181128025944030_21649.png b/习题解析/05 数组和广义表/_v_images/20181128025944030_21649.png new file mode 100644 index 0000000..7572d36 Binary files /dev/null and b/习题解析/05 数组和广义表/_v_images/20181128025944030_21649.png differ diff --git a/习题解析/05 数组和广义表/_v_images/20181128030006944_5864.png b/习题解析/05 数组和广义表/_v_images/20181128030006944_5864.png new file mode 100644 index 0000000..eee2646 Binary files /dev/null and b/习题解析/05 数组和广义表/_v_images/20181128030006944_5864.png differ diff --git a/习题解析/05 数组和广义表/_v_images/20181128030200899_4388.png b/习题解析/05 数组和广义表/_v_images/20181128030200899_4388.png new file mode 100644 index 0000000..cb072c8 Binary files /dev/null and b/习题解析/05 数组和广义表/_v_images/20181128030200899_4388.png differ diff --git a/习题解析/05 数组和广义表/_v_images/20181128032123139_30296.png b/习题解析/05 数组和广义表/_v_images/20181128032123139_30296.png new file mode 100644 index 0000000..b8a6496 Binary files /dev/null and b/习题解析/05 数组和广义表/_v_images/20181128032123139_30296.png differ diff --git a/习题解析/05 数组和广义表/_v_images/20181128032203810_17392.png b/习题解析/05 数组和广义表/_v_images/20181128032203810_17392.png new file mode 100644 index 0000000..25f3692 Binary files /dev/null and b/习题解析/05 数组和广义表/_v_images/20181128032203810_17392.png differ diff --git a/习题解析/05 数组和广义表/_v_images/20181128102525149_11720.png b/习题解析/05 数组和广义表/_v_images/20181128102525149_11720.png new file mode 100644 index 0000000..5e581f4 Binary files /dev/null and b/习题解析/05 数组和广义表/_v_images/20181128102525149_11720.png differ diff --git a/习题解析/05 数组和广义表/_v_images/20181128102751394_22422.png b/习题解析/05 数组和广义表/_v_images/20181128102751394_22422.png new file mode 100644 index 0000000..4207db9 Binary files /dev/null and b/习题解析/05 数组和广义表/_v_images/20181128102751394_22422.png differ diff --git a/习题解析/05 数组和广义表/_v_images/20181128102824060_18222.png b/习题解析/05 数组和广义表/_v_images/20181128102824060_18222.png new file mode 100644 index 0000000..4d21122 Binary files /dev/null and b/习题解析/05 数组和广义表/_v_images/20181128102824060_18222.png differ diff --git a/习题解析/05 数组和广义表/第05章 数组与广义表.md b/习题解析/05 数组和广义表/第05章 数组与广义表.md new file mode 100644 index 0000000..7c579a1 --- /dev/null +++ b/习题解析/05 数组和广义表/第05章 数组与广义表.md @@ -0,0 +1,311 @@ +# 第5章 数组与广义表 + +## 一、基础知识题 + +### 5.1 假设有二维数组A6×8,每个元素用相邻的6个字节存储,存储器按字节编址,已知A的起始存储位置(基地址)为1000,计算: +###### (1) 数组A的体积(即存储量); +###### (2) 数组A的最后一个元素a57的第一个字节的地址; +###### (3) 按行存储时,元素a14的第一个字节的地址; +###### (4) 按列存储时,元素a47的第一个字节的地址。 + +> (1)V = 6×8×6 = 288 Byte +> (2)Loc(5,7) = 1000+(6×8-1)×6 = 1282 +> (3)Loc(1,4)(行) = 1000+(1×8+4)×6 = 1072 +> (4)Loc(4,7)(列) = 1000+(6×7+4)×6 = 1276 + +### 5.2 假设按低下标优先存储整数数组A9×3×5×8时,第一个元素的字节地址是100,每个整数占四个字节。问下列元素的存储地址是什么? +###### (1) a0000 +###### (2) a1111 +###### (3) a3125 +###### (4) a8247 + +> (1)Loc(0,0,0,0) = 100 +> (2)Loc(1,1,1,1) = 100+(1×3×5×8+1×5×8+1×8+1)×4 = 776 +> (3)Loc(3,1,2,5) = 100+(3×3×5×8+1×5×8+2×8+5)×4 = 1784 +> (4)Loc(8,2,4,7) = 100+(8×3×5×8+2×5×8+4×8+7)×4 = 4416 + +### 5.3 按高下标优先存储方式(以最右的下标为主序),顺序列出数组A2×2×3×3中所有元素aijkl,为了简化表达,可以只列出(i,j,k,l)的序列。 + +> (0,0,0,0) (1,0,0,0) (0,1,0,0) (1,1,0,0) +> (0,0,1,0) (1,0,1,0) (0,1,1,0) (1,1,1,0) +> (0,0,2,0) (1,0,2,0) (0,1,2,0) (1,1,2,0) +> +> (0,0,0,1) (1,0,0,1) (0,1,0,1) (1,1,0,1) +> (0,0,1,1) (1,0,1,1) (0,1,1,1) (1,1,1,1) +> (0,0,2,1) (1,0,2,1) (0,1,2,1) (1,1,2,1) +> +> (0,0,0,2) (1,0,0,2) (0,1,0,2) (1,1,0,2) +> (0,0,1,2) (1,0,1,2) (0,1,1,2) (1,1,1,2) +> (0,0,2,2) (1,0,2,2) (0,1,2,2) (1,1,2,2) +> +> 思路: +> +> ![5.3](_v_images/20181128024131486_26584.png) + +### 5.4 将教科书5.3.1节中的式(5-3)改写为一个等式的形式。 + +> ![5.4](_v_images/20181128024617431_31991.png) ,其中a=Max{i,j},b=Min{i,j}。 + +### 5.5 设有上三角矩阵(aij)n×n,将其上三角元素逐行存于数组B[m]中(m充分大),使得B[k]=aij,且k=f1(i)+f2(j)+c。试推导出函数f1,f2和常数c(要求f1和f2中不含常数项)。 + +> 根据题意得: +> ![5.5.1](_v_images/20181128024818024_1955.png)(1≤i≤j≤n,k≥0) +> 故: +> ![5.5.2](_v_images/20181128024844354_32694.png),![5.5.3](_v_images/20181128024901661_11428.png),![5.5.4](_v_images/20181128024915115_3609.png) + +### 5.6 设有三对角矩阵(aij)n×n,将其三条对角线上的元素存于数组B[3][n]中,使得元素B[u][v]=aij,试推导出从(i,j)到(u,v)的下标变换公式。 + +> 行:u = i – j + 1。 +> 列:v = j - 1。 +> 图示: +![5.6](_v_images/20181128025105462_31218.png) + +### 5.7 设有三对角矩阵(aij)n×n,将其三条对角线上的元素逐行地存于数组B[3n-2]中,使得B[k]=aij,求: +##### (1) 用i,j表示k的下标变换公式; +##### (2) 用k表示i,j的下标变换公式。 + +> (1) +> +> 逐行累加考虑:(|i-j|≤1) +![5.7.1](_v_images/20181128025241824_32225.png) +> +> 用“补缺法”考虑:(|i-j|≤1) +> ![5.7.2](_v_images/20181128025435346_25694.png) +> +> (2) i = (k+1)/3 + 1, (0≤k≤3n-1); j = k+3-2i = k+1-2[(k+1)/3]. + + +### 5.8 假设一个准对角矩阵 + +![5.8.1](_v_images/20181128025526044_25756.png) + +##### 按以下方式存于一维数组B[4m]中: +![5.8.2](_v_images/20181128025550464_16430.png) + +##### 写出由一对下标(i,j)求k的转换公式。 + +> k = 2i - j%2 - 1. +> +> **思路:** +> +>![5.8.3](_v_images/20181128025752290_16510.png) + +### 5.9 已知A为稀疏矩阵,试从空间和时间角度比较采用两种不同的存储结构(二维数组和三元组表)完成求运算![5.9](_v_images/20181128030200899_4388.png)的优缺点。 + +> (1)空间与时间复杂度分析: +> +> 用二维数组存储时,空间与时间复杂度均为O(n×n);设非零元个数为t,则用三元组存储时,空间与时间复杂度为O(t)。 +> +> (2)优缺点分析: +> +> 当非零元个数t< (1) = p +> (2) = (k, p, h) +> (3) = (a, b) +> (4) = ((c, d)) +> (5) = GetHead【((c, d))】=(c, d) +> (6) = GetTail【(a, b)】=(b) +> (7) = GetHead【GetTail【(a, b)】】=GetHead【(b)】=b +> (8) = GetTail【GetHead【((c, d))】】=GetTail【(c, d)】=(d) + +### 5.11 利用广义表的GetHead和GetTail操作写出如上题的函数表达式,把原子banana分别从下列广义表中分离出来。 +###### (1) L1 = (apple, pear, banana, orange); +###### (2) L2 = ((apple, pear), (banana, orange)); +###### (3) L3 = (((apple), (pear), (banana), (orange))); +###### (4) L4 = (apple, (pear), ((banana)), (((orange)))); +###### (5) L5 = ((((apple))), ((pear)), (banana), orange); +###### (6) L6 = ((((apple), pear), banana), orange); +###### (7) L7 = (apple, (pear, (banana), orange)); + +> (1) GetHead【GetTail【GetTail【L1】】】 +> (2) GetHead【GetHead【GetTail【L2】】】 +> (3) GetHead【GetHead【GetTail【GetTail【GetHead【L3】】】】】 +> (4) GetHead【GetHead【GetHead【GetTail【GetTail【L4】】】】】 +> (5) GetHead【GetHead【GetTail【GetTail【L5】】】】 +> (6) GetHead【GetTail【GetHead【L6】】】 +> (7) GetHead【GetHead【GetTail【GetHead【GetTail【L7】】】】】 + +### 5.12 按教科书5.5节中图5.8所示结点结构,画出下列广义表的存储结构图,并求它的深度。 +##### (1) ((()),a,((b,c),(),d),(((e)))) +##### (2) ((((a),b)),(((),(d)),(e,f))) + +> (1) deep = 4. +> +> ![5.12.1](_v_images/20181128025833026_20359.png) +> +> (2) deep = 4. +> +> ![5.12.2](_v_images/20181128025848038_32716.png) + +### 5.13 已知以下各图为广义表的存储结构图,其结点结构和5.12题相同。写出各图表示的广义表。 + +(1) ![5.13.1](_v_images/20181128025918606_14220.png) + +> 广义表:((x,(y)),(((())),(),(z))) + +(2) ![5.13.2](_v_images/20181128025944030_21649.png) + +> 广义表:(((a,b,()),()),(a,(b)),()) + +### 5.14 已知等差数列的第一项为a1,公差为d,试写出该数列前n项的和S(n)(n≥1)的递归定义。 + +> ![5.14](_v_images/20181128030006944_5864.png) + +### 5.15 写出求给定集合的幂集的递归定义。 + +> (1) 幂集递归定义的文字表述:(假设集合A中并无重复元素) +>> ① 若A为Ø,则其幂集B为{Ø}。 +>> ② 若A不为Ø。取出A中第一个元素记作a,求取A\{a}的幂集C。对于C中的每个元素x{此处元素必为集合},求集合{a}与集合x的并集,并将求得的各个并集暂时存放到集合D(D初始化为空集)中。最后,求取C与D的并集即可得到A的幂集B。 +> +> 标记求取集合A的幂集的函数为P【A】,获取集合A的元素的函数为I【A】,加号“+”代表取并集,箭头“←”代表将右边的元素添加到左边的集合中,则求幂集的过程可简化为三步: +> ❶ C = P【A\{a}】; +> ❷ ∑(D←(I【C】+{a})); +> ❸ B = C + D。 +> +> 例:集合 A={a,b,c} 的幂集为:B={Ø,{a},{b},{c},{a,b},{a,c},{b,c},{a,b,c}} +> 求取过程:(递归) +> ⒈ P【Ø】 = {Ø}; +> ⒉ P【{c}】: +>> ❶ C = P【{c}\{c}】 = P【Ø】 = {Ø}; +>> +>> ❷ ∑(D←(I【C】+{c})) (C中有1个元素,故需累计添加1次元素到D) +>>> Ⅰ. D←(Ø+{c})= D←{c},此时:D={{c}} +>> +>> ❸ B = C + D = {Ø,{c}},即P【{c}】 = {Ø,{c}}。 +>> +> ⒊ P【{b,c}】: +>> ❶ C = P【{b,c}\{b}】 = P【{c}】 = {Ø,{c}}; +>> +>> ❷ ∑(D←(I【C】+{b})) (C中有2个元素,故需累计添加2次元素到D) +>>> Ⅰ. D←(Ø+{b})= D←{b},此时:D={{b}} +>>> Ⅱ. D←({c}+{b})= D←{b,c},此时:D={{b},{b,c}} +>> +>> ❸ B = C + D = {Ø,{b},{c},{b,c}},即P【{b,c}】 = {Ø,{b},{c},{b,c}}。 +>> +> ⒋ P【{a,b,c}】: +>> ❶ C = P【{a,b,c}\{a}】 = P【{b,c}】 = {Ø,{b},{c},{b,c}}; +>> +>> ❷ ∑(D←(I【C】+{a})) (C中有4个元素,故需累计添加4次元素到D) +>>> Ⅰ.D←(Ø+{a}) = D←{a},此时:D={{a}} +>>> Ⅱ.D←({b}+{a}) = D←{a,b},此时:D={{a},{a,b}} +>>> Ⅲ.D←({c}+{a}) = D←{a,c},此时:D={{a},{a,b},{a,c}} +>>> Ⅳ.D←({b,c}+{a}) = D←{a,b,c},此时:D={{a},{a,b},{a,c},{a,b,c}} +>> +>> ❸ B = C + D = {Ø,{a},{b},{c},{a,b},{a,c},{b,c},{a,b,c}} +>>> 即P【{a,b,c}】 = {Ø,{a},{b},{c},{a,b},{a,c},{b,c},{a,b,c}}。 +> +> (2) 幂集递归定义的函数表示:(假设集合A中并无重复元素) +> ![5.15](_v_images/20181128032123139_30296.png) +> 其中,P【】、I【】、“+”、“←”的含义同上。 + +### 5.16 试利用C语言中的增量运算“++”和减量运算“--”写出两个非负整数a和b相加的递归定义。 + +> ![5.16](_v_images/20181128032203810_17392.png) + +### 5.17 已知顺序表L含有n个整数,试分别以函数形式写出下列运算的递归算法: +###### (1) 求表中的最大整数; +###### (2) 求表中的最小整数; +###### (3) 求表中n个整数之和; +###### (4) 求表中n个整数之积; +###### (5) 求表中n个整数的平均值。 + +---------- + +## 二、算法设计题 + +### 5.18 设计一个算法,将数组An中的元素A[0]至A[n-1]循环右移k位,并要求只用一个元素大小的附加存储,元素移动或交换次数为O(n)。 + +---------- + +### 5.19 若矩阵Am×n中的某个元素aij是第i行中的最小值,同时又是第j列中的最大值,则称此元素为该矩阵中的一个马鞍点。假设二维数组存储矩阵Am×n,试编写求出矩阵中所有马鞍点的算法,并分析你的算法在最坏情况下的时间复杂度。 + +---------- + +### 5.20 类似于以一维数组表示一元多项式,以m维数组:(aj1j2…jm),0≤ji≤n,i=1,2,…,m,表示m元多项式,数组元素ae1e2…em表示多项式中x1e1x2e2…xmem的系数。例如,和二元多项式x2+3xy+4y2-x+2相应的二维数组为: + +![5.20](_v_images/20181128102525149_11720.png) + +### 试编写一个算法将m维数组表示的m元多项式以常规表示的形式(按降幂顺序)输出。可将其中一项ckx1e1x2e2…xmem印成ckx1Ee1x2Ee2…xmEem(其中m,ck和ej(j=1,2,…,m)印出它们具体的值),当ck或ej(j=1,2,…,m)为1时,ck的值或“E”和ej的值可省略不印。 + +---------- + +### 5.21 假设稀疏矩阵A和B均以三元组顺序表作为存储结构。试写出矩阵相加的算法,另设三元组表C存放结果矩阵。 + +---------- + +### 5.22 假设稀疏矩阵A和B均以三元组顺序表作为存储结构。试写出满足以下条件的矩阵相加的算法:假设三元组顺序表A的空间足够大,将矩阵B加到矩阵A上,不增加A,B之外的附加空间,你的算法能否达到O(m+n)的时间复杂度?其中m和n分别为A,B矩阵中非零元的数目。 + +---------- + +### 5.23 三元组顺序表的一种变型是,从三元组顺序表中去掉行下标域得到二元组顺序表,另设一个行起始向量,其每个分量是二元组顺序表的一个下标值,指示该行中第一个非零元素在二元组顺序表中的起始位置。试编写一个算法,由矩阵元素的下标值i,j求矩阵元素。试讨论这种方法和三元组顺序表相比有什么优缺点。 + +---------- + +### 5.24 三元组顺序表的另一种变型是,不存矩阵元素的行、列下标,而存非零元在矩阵中以行为主序时排列的顺序号,即在LOC(0, 0)=1,l=1时按教科书5.2节中公式(5-2)计算出的值。试写一算法,由矩阵元素的下标值i,j求元素的值。 + +---------- + +### 5.25 若将稀疏矩阵A的非零元素以行序为主序的顺序存于一维数组V中,并用二维数组B表示A中的相应元素是否为零元素(以0和1分别表示零元素和非零元素)。 +### 例如,![5.25.1](_v_images/20181128102751394_22422.png)可用V=(15, 22, -6, 9)和![5.25.2](_v_images/20181128102824060_18222.png)表示。 +### 试写一算法,实现在上述表示法中实现矩阵相加的运算。并分析你算法的时间复杂度。 + +---------- + +### 5.26 试编写一个以三元组形式输出用十字链表表示的稀疏矩阵中非零元素及其下标的算法。 + +---------- + +### 5.27 试按教科书5.3.2节中定义的十字链表存储表示编写将稀疏矩阵B加到稀疏矩阵A上的算法。 + +---------- + +### 5.28 采用教科书5.6节中给出的m元多项式的表示方法,写一个求m元多项式中第一变元的偏导数的算法。 +### 5.29 采用教科书5.6节中给出的m元多项式的表示方法,写一个m元多项式相加的算法。 + +---------- + +### 5.30 试按表头、表尾的分析方法重写求广义表的深度的递归算法。 + +---------- + +### 5.31 试按教科书5.5节图5.10所示结点结构编写复制广义表的递归算法。 + +---------- + +### 5.32 试编写判别两个广义表是否相等的递归算法。 + +---------- + +### 5.33 试编写递归算法,输出广义表中所有原子项及其所在层次。 + +---------- + +### 5.34 试编写递归算法,逆转广义表中的数据元素。例如:将广义表(a, ((b, c), ()), (((d), e), f))逆转为:((f, (e, (d))), ((), (c, b)), a)。 + +---------- + +### 5.35 假设广义表按如下形式的字符串表示:(a1, a2, …, an), n≥0,其中ai或为单字母表示的原子,或为广义表;n=0时为只含空格字符的空表( )。试按教科书5.5节图5.8所示链表结点结构编写,按照读入的一个广义表字符串建立其存储结构的递归算法。 + +### 5.36 试按教科书5.5节图5.8所示存储结构,编写按上题描述的格式输出广义表的递归算法。 + +---------- + +### 5.37 试编写递归算法,删除广义表中所有值等于x的原子项。 + +---------- + +### 5.38 试编写算法,依次从左至右输出广义表中第l层的原子项。例如:广义表(a, (b, (c)), (d))中的a为第一层的原子项;b和d为第二层的原子项;c为第三层的原子项。 + +----------