diff --git a/CLion/ExerciseBook/04.10/04.10.c b/CLion/ExerciseBook/04.10/04.10.c new file mode 100644 index 0000000..f432071 --- /dev/null +++ b/CLion/ExerciseBook/04.10/04.10.c @@ -0,0 +1,35 @@ +#include +#include "String.h" //**字符串**// + +/* + * 字符串逆置:将T逆置为R。 + */ +StringType Algo_4_10(StringType T) { + int i; + StringType R = "", Sub; + + // 从后向前截取字符 + for(i = StrLength(T); i >= 1; i--) { + Sub = SubString(T, i, 1); + R = Concat(R, Sub); + } + + return R; +} + + +int main(int argc, char* argv[]) { + char* s = "0123456789"; + StringType T, R; + + printf("逆置前,T = "); + StrAssign(&T, s); + StrPrint(T); + + printf("逆置后,R = "); + R = Algo_4_10(T); + StrPrint(R); + + return 0; +} + diff --git a/CLion/ExerciseBook/04.10/CMakeLists.txt b/CLion/ExerciseBook/04.10/CMakeLists.txt new file mode 100644 index 0000000..722b166 --- /dev/null +++ b/CLion/ExerciseBook/04.10/CMakeLists.txt @@ -0,0 +1,7 @@ +# 包含公共库 +include_directories(${CMAKE_SOURCE_DIR}/Status) + +# 生成可执行文件 +add_executable(04.10 String.h String.c 04.10.c) +# 链接公共库 +target_link_libraries(04.10 Scanf_lib) \ No newline at end of file diff --git a/CLion/ExerciseBook/04.10/String.c b/CLion/ExerciseBook/04.10/String.c new file mode 100644 index 0000000..a476438 --- /dev/null +++ b/CLion/ExerciseBook/04.10/String.c @@ -0,0 +1,151 @@ +/*=========================== + * 习题4.10~4.14中使用的字符串 + ============================*/ + +#include "String.h" + +// 初始化:构造一个值为s的串t +void StrAssign(StringType* t, const char* s) { + if(s == NULL) { + *t = ""; + } + + *t = (char*) malloc((strlen(s) + 1) * sizeof(char)); + + strcpy(*t, s); +} + +// 比较:返回s与t的大小,如果大小一致,返回0 +int StrCompare(StringType s, StringType t) { + return strcmp(s, t); +} + +// 计数:返回字符串s的长度 +int StrLength(StringType s) { + return (int) strlen(s); +} + +// 联接:返回由s与t联接后的串 +StringType Concat(StringType s, StringType t) { + StringType r; + + if(s == NULL) { + s = ""; + } + + if(t == NULL) { + t = ""; + } + + r = (char*) malloc((strlen(s) + strlen(t) + 1) * sizeof(char)); + r[0] = '\0'; + + strcat(r, s); + strcat(r, t); + + return r; +} + +// 求子串:从s的start位置起,截取len个字符后返回 +StringType SubString(StringType s, int start, int len) { + int n; + char* sub; + + n = (int) strlen(s); + + if(start < 1 || start > n || start + len - 1 > n || len < 0) { + return ""; + } + + sub = (char*) malloc((len + 1) * sizeof(char)); + strncpy(sub, s + start - 1, len); + sub[len] = '\0'; + + return sub; +} + +// 查找:从s的pos位置起查找t,如果找到,返回其位置 +int Index(StringType s, StringType t, int pos) { + int m, n, i; + StringType sub; + + // 失败情形提前处理 + if(pos < 1 || pos > StrLength(s) || StrLength(t) == 0) { + return 0; + } + + n = StrLength(s); + m = StrLength(t); + i = pos; + + // 保证长度不越界 + while(i <= n - m + 1) { + // 获取S[i, i+m-1] + sub = SubString(s, i, m); + + // 如果子串与模式串不匹配,则需要继续推进 + if(StrCompare(sub, t) != 0) { + ++i; + } else { + return i; + } + } + + return 0; +} + +// 插入:在s的pos处插入t +Status StrInsert(StringType* s, int pos, StringType t) { + StringType r; + StringType s1, s2; + + if(pos < 1 || pos > StrLength(*s) + 1) { + return ERROR; + } + + r = (StringType) malloc((strlen(*s) + strlen(t) + 1) * sizeof(char)); + r[0] = '\0'; + + // 如果待插入的串为空,则提前返回 + if(StrLength(t) == 0) { + return OK; + } + + s1 = SubString(*s, 1, pos - 1); + s2 = SubString(*s, pos, (int) strlen(*s) - pos + 1); + + strcat(r, s1); + strcat(r, t); + strcat(r, s2); + + *s = r; + + return OK; +} + +// 删除:从s的pos位置起,删除len个字符 +Status StrDelete(StringType* s, int pos, int len) { + StringType r; + + if(pos < 1 || pos + len - 1 > StrLength(*s) || len < 0) { + return ERROR; + } + + // 如果待删除的长度为0,则提前返回 + if(len == 0) { + return OK; + } + + r = (StringType) malloc((StrLength(*s) - len + 1) * sizeof(char)); + strncpy(r, *s, pos - 1); + strcpy(r + pos - 1, *s + pos + len - 1); + + *s = r; + + return OK; +} + +// 输出字符串 +void StrPrint(StringType s) { + printf("%s\n", s); +} diff --git a/CLion/ExerciseBook/04.10/String.h b/CLion/ExerciseBook/04.10/String.h new file mode 100644 index 0000000..f4711a9 --- /dev/null +++ b/CLion/ExerciseBook/04.10/String.h @@ -0,0 +1,43 @@ +/*=========================== + * 习题4.10~4.14中使用的字符串 + ============================*/ + +#ifndef STRING_H +#define STRING_H + +#include +#include // 提供 strlen 原型 +#include "Status.h" //**▲01 绪论**// + +/* 字符串类型 */ +typedef char* StringType; + + +// 初始化:构造一个值为s的串t +void StrAssign(StringType* t, const char* s); + +// 比较:返回s与t的大小,如果大小一致,返回0 +int StrCompare(StringType s, StringType t); + +// 计数:返回字符串s的长度 +int StrLength(StringType s); + +// 联接:返回由s与t联接后的串 +StringType Concat(StringType s, StringType t); + +// 求子串:从s的start位置起,截取len个字符后返回 +StringType SubString(StringType s, int start, int len); + +// 查找:从s的pos位置起查找t,如果找到,返回其位置 +int Index(StringType s, StringType t, int pos); + +// 插入:在s的pos处插入t +Status StrInsert(StringType* s, int pos, StringType t); + +// 删除:从s的pos位置起,删除len个字符 +Status StrDelete(StringType* s, int pos, int len); + +// 输出字符串 +void StrPrint(StringType s); + +#endif diff --git a/CLion/ExerciseBook/04.11/04.11.c b/CLion/ExerciseBook/04.11/04.11.c new file mode 100644 index 0000000..daaa1b4 --- /dev/null +++ b/CLion/ExerciseBook/04.11/04.11.c @@ -0,0 +1,69 @@ +#include +#include +#include "String.h" //**字符串**// + +/* + * R=S-S∩T,数组a存储R中每个字符在S中第一次出现的位置 + * + * 注:数组a的0号单元存储的是a中元素的个数 + */ +void Algo_4_11(StringType* R, StringType S, StringType T, int** a) { + int i, p; + StringType ch; + + *a = (int*) malloc((StrLength(S) + 1) * sizeof(int)); + + StrAssign(R, ""); + + for(i = 1, (*a)[0] = 0; i <= StrLength(S); i++) { + // 取出字符进行判断 + ch = SubString(S, i, 1); + + // 获取S[i]在T中的位置 + p = Index(T, ch, 1); + + // 如果S[i]不在T中 + if(p == 0) { + // 获取S[i]在R中的位置 + p = Index(*R, ch, 1); + } + + // 如果S[i]既不在T中,又没在R中出现过 + if(p == 0) { + (*a)[0]++; + (*a)[(*a)[0]] = i; + + // 向R中添加S[i] + StrInsert(R, (*a)[0], ch); + } + } +} + + +int main(int argc, char* argv[]) { + char* s = "amdhcjgfdlpinbefcopgkqikeb"; + char* t = "mhjlpinopkqik"; + int* a; + StringType T, S, R; + int i; + + printf("初始化S和T...\n"); + StrAssign(&S, s); + StrAssign(&T, t); + printf("S = "); + StrPrint(S); + printf("T = "); + StrPrint(T); + + Algo_4_11(&R, S, T, &a); + printf("R = "); + StrPrint(R); + + printf("a = "); + for(i = 1; i <= a[0]; i++) { + printf("%d ", a[i]); + } + printf("\n"); + + return 0; +} diff --git a/CLion/ExerciseBook/04.11/CMakeLists.txt b/CLion/ExerciseBook/04.11/CMakeLists.txt new file mode 100644 index 0000000..6564f26 --- /dev/null +++ b/CLion/ExerciseBook/04.11/CMakeLists.txt @@ -0,0 +1,7 @@ +# 包含公共库 +include_directories(${CMAKE_SOURCE_DIR}/Status) + +# 生成可执行文件 +add_executable(04.11 String.h String.c 04.11.c) +# 链接公共库 +target_link_libraries(04.11 Scanf_lib) \ No newline at end of file diff --git a/CLion/ExerciseBook/04.11/String.c b/CLion/ExerciseBook/04.11/String.c new file mode 100644 index 0000000..a476438 --- /dev/null +++ b/CLion/ExerciseBook/04.11/String.c @@ -0,0 +1,151 @@ +/*=========================== + * 习题4.10~4.14中使用的字符串 + ============================*/ + +#include "String.h" + +// 初始化:构造一个值为s的串t +void StrAssign(StringType* t, const char* s) { + if(s == NULL) { + *t = ""; + } + + *t = (char*) malloc((strlen(s) + 1) * sizeof(char)); + + strcpy(*t, s); +} + +// 比较:返回s与t的大小,如果大小一致,返回0 +int StrCompare(StringType s, StringType t) { + return strcmp(s, t); +} + +// 计数:返回字符串s的长度 +int StrLength(StringType s) { + return (int) strlen(s); +} + +// 联接:返回由s与t联接后的串 +StringType Concat(StringType s, StringType t) { + StringType r; + + if(s == NULL) { + s = ""; + } + + if(t == NULL) { + t = ""; + } + + r = (char*) malloc((strlen(s) + strlen(t) + 1) * sizeof(char)); + r[0] = '\0'; + + strcat(r, s); + strcat(r, t); + + return r; +} + +// 求子串:从s的start位置起,截取len个字符后返回 +StringType SubString(StringType s, int start, int len) { + int n; + char* sub; + + n = (int) strlen(s); + + if(start < 1 || start > n || start + len - 1 > n || len < 0) { + return ""; + } + + sub = (char*) malloc((len + 1) * sizeof(char)); + strncpy(sub, s + start - 1, len); + sub[len] = '\0'; + + return sub; +} + +// 查找:从s的pos位置起查找t,如果找到,返回其位置 +int Index(StringType s, StringType t, int pos) { + int m, n, i; + StringType sub; + + // 失败情形提前处理 + if(pos < 1 || pos > StrLength(s) || StrLength(t) == 0) { + return 0; + } + + n = StrLength(s); + m = StrLength(t); + i = pos; + + // 保证长度不越界 + while(i <= n - m + 1) { + // 获取S[i, i+m-1] + sub = SubString(s, i, m); + + // 如果子串与模式串不匹配,则需要继续推进 + if(StrCompare(sub, t) != 0) { + ++i; + } else { + return i; + } + } + + return 0; +} + +// 插入:在s的pos处插入t +Status StrInsert(StringType* s, int pos, StringType t) { + StringType r; + StringType s1, s2; + + if(pos < 1 || pos > StrLength(*s) + 1) { + return ERROR; + } + + r = (StringType) malloc((strlen(*s) + strlen(t) + 1) * sizeof(char)); + r[0] = '\0'; + + // 如果待插入的串为空,则提前返回 + if(StrLength(t) == 0) { + return OK; + } + + s1 = SubString(*s, 1, pos - 1); + s2 = SubString(*s, pos, (int) strlen(*s) - pos + 1); + + strcat(r, s1); + strcat(r, t); + strcat(r, s2); + + *s = r; + + return OK; +} + +// 删除:从s的pos位置起,删除len个字符 +Status StrDelete(StringType* s, int pos, int len) { + StringType r; + + if(pos < 1 || pos + len - 1 > StrLength(*s) || len < 0) { + return ERROR; + } + + // 如果待删除的长度为0,则提前返回 + if(len == 0) { + return OK; + } + + r = (StringType) malloc((StrLength(*s) - len + 1) * sizeof(char)); + strncpy(r, *s, pos - 1); + strcpy(r + pos - 1, *s + pos + len - 1); + + *s = r; + + return OK; +} + +// 输出字符串 +void StrPrint(StringType s) { + printf("%s\n", s); +} diff --git a/CLion/ExerciseBook/04.11/String.h b/CLion/ExerciseBook/04.11/String.h new file mode 100644 index 0000000..f4711a9 --- /dev/null +++ b/CLion/ExerciseBook/04.11/String.h @@ -0,0 +1,43 @@ +/*=========================== + * 习题4.10~4.14中使用的字符串 + ============================*/ + +#ifndef STRING_H +#define STRING_H + +#include +#include // 提供 strlen 原型 +#include "Status.h" //**▲01 绪论**// + +/* 字符串类型 */ +typedef char* StringType; + + +// 初始化:构造一个值为s的串t +void StrAssign(StringType* t, const char* s); + +// 比较:返回s与t的大小,如果大小一致,返回0 +int StrCompare(StringType s, StringType t); + +// 计数:返回字符串s的长度 +int StrLength(StringType s); + +// 联接:返回由s与t联接后的串 +StringType Concat(StringType s, StringType t); + +// 求子串:从s的start位置起,截取len个字符后返回 +StringType SubString(StringType s, int start, int len); + +// 查找:从s的pos位置起查找t,如果找到,返回其位置 +int Index(StringType s, StringType t, int pos); + +// 插入:在s的pos处插入t +Status StrInsert(StringType* s, int pos, StringType t); + +// 删除:从s的pos位置起,删除len个字符 +Status StrDelete(StringType* s, int pos, int len); + +// 输出字符串 +void StrPrint(StringType s); + +#endif diff --git a/CLion/ExerciseBook/04.12/04.12.c b/CLion/ExerciseBook/04.12/04.12.c new file mode 100644 index 0000000..dd73f38 --- /dev/null +++ b/CLion/ExerciseBook/04.12/04.12.c @@ -0,0 +1,56 @@ +#include +#include "Status.h" //**▲01 绪论**// +#include "String.h" //**字符串**// + +/* + * 替换:Replace + * + * 用V替换主串S中出现的所有与T相等的且不重叠的子串 + */ +Status Algo_4_12(StringType* S, StringType T, StringType V) { + int i; + + if(StrLength(*S) == 0 || StrLength(T) == 0) { + return ERROR; + } + + i = 1; + + // 在主串S中寻找模式串T第一次出现的位置 + while((i = Index(*S, T, i)) != 0) { + StrDelete(S, i, StrLength(T)); // 从S中删除T + StrInsert(S, i, V); // 向S中插入V + + i += StrLength(V); // i切换到下一个位置 + } + + return OK; +} + + +int main(int argc, char* argv[]) { + char* s = "----***--*-**-****-*****-----"; + char* t = "**"; + char* v = "^^"; + StringType T, S, V; + + printf("替换前...\n"); + + StrAssign(&S, s); + StrAssign(&T, t); + StrAssign(&V, v); + + printf("S = "); + StrPrint(S); + printf("T = "); + StrPrint(T); + printf("V = "); + StrPrint(V); + + printf("替换后...\n"); + printf("S = "); + Algo_4_12(&S, T, V); + StrPrint(S); + + return 0; +} diff --git a/CLion/ExerciseBook/04.12/CMakeLists.txt b/CLion/ExerciseBook/04.12/CMakeLists.txt new file mode 100644 index 0000000..ab3a77a --- /dev/null +++ b/CLion/ExerciseBook/04.12/CMakeLists.txt @@ -0,0 +1,7 @@ +# 包含公共库 +include_directories(${CMAKE_SOURCE_DIR}/Status) + +# 生成可执行文件 +add_executable(04.12 String.h String.c 04.12.c) +# 链接公共库 +target_link_libraries(04.12 Scanf_lib) \ No newline at end of file diff --git a/CLion/ExerciseBook/04.12/String.c b/CLion/ExerciseBook/04.12/String.c new file mode 100644 index 0000000..a476438 --- /dev/null +++ b/CLion/ExerciseBook/04.12/String.c @@ -0,0 +1,151 @@ +/*=========================== + * 习题4.10~4.14中使用的字符串 + ============================*/ + +#include "String.h" + +// 初始化:构造一个值为s的串t +void StrAssign(StringType* t, const char* s) { + if(s == NULL) { + *t = ""; + } + + *t = (char*) malloc((strlen(s) + 1) * sizeof(char)); + + strcpy(*t, s); +} + +// 比较:返回s与t的大小,如果大小一致,返回0 +int StrCompare(StringType s, StringType t) { + return strcmp(s, t); +} + +// 计数:返回字符串s的长度 +int StrLength(StringType s) { + return (int) strlen(s); +} + +// 联接:返回由s与t联接后的串 +StringType Concat(StringType s, StringType t) { + StringType r; + + if(s == NULL) { + s = ""; + } + + if(t == NULL) { + t = ""; + } + + r = (char*) malloc((strlen(s) + strlen(t) + 1) * sizeof(char)); + r[0] = '\0'; + + strcat(r, s); + strcat(r, t); + + return r; +} + +// 求子串:从s的start位置起,截取len个字符后返回 +StringType SubString(StringType s, int start, int len) { + int n; + char* sub; + + n = (int) strlen(s); + + if(start < 1 || start > n || start + len - 1 > n || len < 0) { + return ""; + } + + sub = (char*) malloc((len + 1) * sizeof(char)); + strncpy(sub, s + start - 1, len); + sub[len] = '\0'; + + return sub; +} + +// 查找:从s的pos位置起查找t,如果找到,返回其位置 +int Index(StringType s, StringType t, int pos) { + int m, n, i; + StringType sub; + + // 失败情形提前处理 + if(pos < 1 || pos > StrLength(s) || StrLength(t) == 0) { + return 0; + } + + n = StrLength(s); + m = StrLength(t); + i = pos; + + // 保证长度不越界 + while(i <= n - m + 1) { + // 获取S[i, i+m-1] + sub = SubString(s, i, m); + + // 如果子串与模式串不匹配,则需要继续推进 + if(StrCompare(sub, t) != 0) { + ++i; + } else { + return i; + } + } + + return 0; +} + +// 插入:在s的pos处插入t +Status StrInsert(StringType* s, int pos, StringType t) { + StringType r; + StringType s1, s2; + + if(pos < 1 || pos > StrLength(*s) + 1) { + return ERROR; + } + + r = (StringType) malloc((strlen(*s) + strlen(t) + 1) * sizeof(char)); + r[0] = '\0'; + + // 如果待插入的串为空,则提前返回 + if(StrLength(t) == 0) { + return OK; + } + + s1 = SubString(*s, 1, pos - 1); + s2 = SubString(*s, pos, (int) strlen(*s) - pos + 1); + + strcat(r, s1); + strcat(r, t); + strcat(r, s2); + + *s = r; + + return OK; +} + +// 删除:从s的pos位置起,删除len个字符 +Status StrDelete(StringType* s, int pos, int len) { + StringType r; + + if(pos < 1 || pos + len - 1 > StrLength(*s) || len < 0) { + return ERROR; + } + + // 如果待删除的长度为0,则提前返回 + if(len == 0) { + return OK; + } + + r = (StringType) malloc((StrLength(*s) - len + 1) * sizeof(char)); + strncpy(r, *s, pos - 1); + strcpy(r + pos - 1, *s + pos + len - 1); + + *s = r; + + return OK; +} + +// 输出字符串 +void StrPrint(StringType s) { + printf("%s\n", s); +} diff --git a/CLion/ExerciseBook/04.12/String.h b/CLion/ExerciseBook/04.12/String.h new file mode 100644 index 0000000..f4711a9 --- /dev/null +++ b/CLion/ExerciseBook/04.12/String.h @@ -0,0 +1,43 @@ +/*=========================== + * 习题4.10~4.14中使用的字符串 + ============================*/ + +#ifndef STRING_H +#define STRING_H + +#include +#include // 提供 strlen 原型 +#include "Status.h" //**▲01 绪论**// + +/* 字符串类型 */ +typedef char* StringType; + + +// 初始化:构造一个值为s的串t +void StrAssign(StringType* t, const char* s); + +// 比较:返回s与t的大小,如果大小一致,返回0 +int StrCompare(StringType s, StringType t); + +// 计数:返回字符串s的长度 +int StrLength(StringType s); + +// 联接:返回由s与t联接后的串 +StringType Concat(StringType s, StringType t); + +// 求子串:从s的start位置起,截取len个字符后返回 +StringType SubString(StringType s, int start, int len); + +// 查找:从s的pos位置起查找t,如果找到,返回其位置 +int Index(StringType s, StringType t, int pos); + +// 插入:在s的pos处插入t +Status StrInsert(StringType* s, int pos, StringType t); + +// 删除:从s的pos位置起,删除len个字符 +Status StrDelete(StringType* s, int pos, int len); + +// 输出字符串 +void StrPrint(StringType s); + +#endif diff --git a/CLion/ExerciseBook/04.13/04.13.c b/CLion/ExerciseBook/04.13/04.13.c new file mode 100644 index 0000000..1fd33b9 --- /dev/null +++ b/CLion/ExerciseBook/04.13/04.13.c @@ -0,0 +1,41 @@ +#include +#include "String.h" //**字符串**// + +/* + * 删除S中包含的T + */ +Status Algo_4_13(StringType* S, StringType T) { + int i; + + // 在S中查找T,如果找到就删除 + while((i = Index(*S, T, 1)) != 0) { + if(StrDelete(S, i, StrLength(T)) == ERROR) { + return ERROR; + } + } + + return OK; +} + + +int main(int argc, char* argv[]) { + char* s = "----***--*-**-****-*****-----"; + char* t = "**"; + StringType T, S; + + printf("删除前...\n"); + StrAssign(&S, s); + StrAssign(&T, t); + + printf("S = "); + StrPrint(S); + printf("T = "); + StrPrint(T); + + printf("删除后...\n"); + printf("S = "); + Algo_4_13(&S, T); + StrPrint(S); + + return 0; +} diff --git a/CLion/ExerciseBook/04.13/CMakeLists.txt b/CLion/ExerciseBook/04.13/CMakeLists.txt new file mode 100644 index 0000000..7e1710f --- /dev/null +++ b/CLion/ExerciseBook/04.13/CMakeLists.txt @@ -0,0 +1,7 @@ +# 包含公共库 +include_directories(${CMAKE_SOURCE_DIR}/Status) + +# 生成可执行文件 +add_executable(04.13 String.h String.c 04.13.c) +# 链接公共库 +target_link_libraries(04.13 Scanf_lib) \ No newline at end of file diff --git a/CLion/ExerciseBook/04.13/String.c b/CLion/ExerciseBook/04.13/String.c new file mode 100644 index 0000000..a476438 --- /dev/null +++ b/CLion/ExerciseBook/04.13/String.c @@ -0,0 +1,151 @@ +/*=========================== + * 习题4.10~4.14中使用的字符串 + ============================*/ + +#include "String.h" + +// 初始化:构造一个值为s的串t +void StrAssign(StringType* t, const char* s) { + if(s == NULL) { + *t = ""; + } + + *t = (char*) malloc((strlen(s) + 1) * sizeof(char)); + + strcpy(*t, s); +} + +// 比较:返回s与t的大小,如果大小一致,返回0 +int StrCompare(StringType s, StringType t) { + return strcmp(s, t); +} + +// 计数:返回字符串s的长度 +int StrLength(StringType s) { + return (int) strlen(s); +} + +// 联接:返回由s与t联接后的串 +StringType Concat(StringType s, StringType t) { + StringType r; + + if(s == NULL) { + s = ""; + } + + if(t == NULL) { + t = ""; + } + + r = (char*) malloc((strlen(s) + strlen(t) + 1) * sizeof(char)); + r[0] = '\0'; + + strcat(r, s); + strcat(r, t); + + return r; +} + +// 求子串:从s的start位置起,截取len个字符后返回 +StringType SubString(StringType s, int start, int len) { + int n; + char* sub; + + n = (int) strlen(s); + + if(start < 1 || start > n || start + len - 1 > n || len < 0) { + return ""; + } + + sub = (char*) malloc((len + 1) * sizeof(char)); + strncpy(sub, s + start - 1, len); + sub[len] = '\0'; + + return sub; +} + +// 查找:从s的pos位置起查找t,如果找到,返回其位置 +int Index(StringType s, StringType t, int pos) { + int m, n, i; + StringType sub; + + // 失败情形提前处理 + if(pos < 1 || pos > StrLength(s) || StrLength(t) == 0) { + return 0; + } + + n = StrLength(s); + m = StrLength(t); + i = pos; + + // 保证长度不越界 + while(i <= n - m + 1) { + // 获取S[i, i+m-1] + sub = SubString(s, i, m); + + // 如果子串与模式串不匹配,则需要继续推进 + if(StrCompare(sub, t) != 0) { + ++i; + } else { + return i; + } + } + + return 0; +} + +// 插入:在s的pos处插入t +Status StrInsert(StringType* s, int pos, StringType t) { + StringType r; + StringType s1, s2; + + if(pos < 1 || pos > StrLength(*s) + 1) { + return ERROR; + } + + r = (StringType) malloc((strlen(*s) + strlen(t) + 1) * sizeof(char)); + r[0] = '\0'; + + // 如果待插入的串为空,则提前返回 + if(StrLength(t) == 0) { + return OK; + } + + s1 = SubString(*s, 1, pos - 1); + s2 = SubString(*s, pos, (int) strlen(*s) - pos + 1); + + strcat(r, s1); + strcat(r, t); + strcat(r, s2); + + *s = r; + + return OK; +} + +// 删除:从s的pos位置起,删除len个字符 +Status StrDelete(StringType* s, int pos, int len) { + StringType r; + + if(pos < 1 || pos + len - 1 > StrLength(*s) || len < 0) { + return ERROR; + } + + // 如果待删除的长度为0,则提前返回 + if(len == 0) { + return OK; + } + + r = (StringType) malloc((StrLength(*s) - len + 1) * sizeof(char)); + strncpy(r, *s, pos - 1); + strcpy(r + pos - 1, *s + pos + len - 1); + + *s = r; + + return OK; +} + +// 输出字符串 +void StrPrint(StringType s) { + printf("%s\n", s); +} diff --git a/CLion/ExerciseBook/04.13/String.h b/CLion/ExerciseBook/04.13/String.h new file mode 100644 index 0000000..f4711a9 --- /dev/null +++ b/CLion/ExerciseBook/04.13/String.h @@ -0,0 +1,43 @@ +/*=========================== + * 习题4.10~4.14中使用的字符串 + ============================*/ + +#ifndef STRING_H +#define STRING_H + +#include +#include // 提供 strlen 原型 +#include "Status.h" //**▲01 绪论**// + +/* 字符串类型 */ +typedef char* StringType; + + +// 初始化:构造一个值为s的串t +void StrAssign(StringType* t, const char* s); + +// 比较:返回s与t的大小,如果大小一致,返回0 +int StrCompare(StringType s, StringType t); + +// 计数:返回字符串s的长度 +int StrLength(StringType s); + +// 联接:返回由s与t联接后的串 +StringType Concat(StringType s, StringType t); + +// 求子串:从s的start位置起,截取len个字符后返回 +StringType SubString(StringType s, int start, int len); + +// 查找:从s的pos位置起查找t,如果找到,返回其位置 +int Index(StringType s, StringType t, int pos); + +// 插入:在s的pos处插入t +Status StrInsert(StringType* s, int pos, StringType t); + +// 删除:从s的pos位置起,删除len个字符 +Status StrDelete(StringType* s, int pos, int len); + +// 输出字符串 +void StrPrint(StringType s); + +#endif diff --git a/CLion/ExerciseBook/04.14/04.14.c b/CLion/ExerciseBook/04.14/04.14.c new file mode 100644 index 0000000..82d606d --- /dev/null +++ b/CLion/ExerciseBook/04.14/04.14.c @@ -0,0 +1,92 @@ +#include +#include +#include "SqStack.h" //**▲03 栈和队列**// +#include "String.h" //**字符串**// + +/* + * 将前缀表达式prefix转换为后缀表达式 + * + *【注】 + * 未对前缀表达式的正确性进行验证 + */ +Status Algo_4_14(const char* prefix, char** suffix) { + StringType P, S; + StringType Operator; // 运算符 + SqStack stack; // 表达式栈 + StringType e; // 栈顶元素 + StringType o; // 靠近栈顶的运算符 + int i, len; + int readStr; // 是否需要读取字符串 + + len = (int) strlen(prefix); + + if(len == 0) { + *suffix = NULL; + return ERROR; + } + + // 运算符和操作数 + StrAssign(&Operator, "+-*/"); + + // 前缀表达式 + StrAssign(&P, prefix); + + // 后缀表达式栈 + InitStack(&stack); + + readStr = 1; + i = 1; + + // 遍历前缀表达式,逐个获取元素 + while(TRUE) { + if(readStr == 1) { + S = SubString(P, i++, 1); + } + + // 如果遇到了运算符,则直接入栈 + if(Index(Operator, S, 1) != 0) { + Push(&stack, S); + readStr = 1; + + // 如果遇到了操作数 + } else { + // 获取栈顶元素,如果栈已经为空,则S中存储了后缀表达式 + if(GetTop(stack, &e) == ERROR) { + break; + } + + // 如果栈顶元素是运算符,则将操作数直接入栈 + if(Index(Operator, e, 1) != 0) { + Push(&stack, S); + readStr = 1; + + // 否则栈顶也是操作数,需要进行简单运算 + } else { + Pop(&stack, &e); // 弹出栈顶操作数 + Pop(&stack, &o); // 弹出靠近栈顶的运算符 + + S = Concat(e, S); + S = Concat(S, o); + + // 此种情形下不需要读取字符串,而需要判断刚刚计算出的Sub + readStr = 0; + } + } + } + + // 获取后缀表达式 + *suffix = S; + + return OK; +} + + +int main(int argc, char* argv[]) { + char* prefix = "-+a*bc/de"; // 其后缀表达式为:abc*+de/- + char* suffix; + + Algo_4_14(prefix, &suffix); + + printf("前缀表达式:%s\n", prefix); + printf("后缀表达式:%s\n", suffix); +} diff --git a/CLion/ExerciseBook/04.14/CMakeLists.txt b/CLion/ExerciseBook/04.14/CMakeLists.txt new file mode 100644 index 0000000..e379689 --- /dev/null +++ b/CLion/ExerciseBook/04.14/CMakeLists.txt @@ -0,0 +1,7 @@ +# 包含公共库 +include_directories(${CMAKE_SOURCE_DIR}/Status) + +# 生成可执行文件 +add_executable(04.14 SqStack.h SqStack.c String.h String.c 04.14.c) +# 链接公共库 +target_link_libraries(04.14 Scanf_lib) \ No newline at end of file diff --git a/CLion/ExerciseBook/04.14/SqStack.c b/CLion/ExerciseBook/04.14/SqStack.c new file mode 100644 index 0000000..fd5d388 --- /dev/null +++ b/CLion/ExerciseBook/04.14/SqStack.c @@ -0,0 +1,89 @@ +/*========================= + * 栈的顺序存储结构(顺序栈) + ==========================*/ + +#include "SqStack.h" //**▲03 栈和队列**// + +/* + * 初始化 + * + * 构造一个空栈。初始化成功则返回OK,否则返回ERROR。 + */ +Status InitStack(SqStack* S) { + if(S == NULL) { + return ERROR; + } + + (*S).base = (SElemType*) malloc(STACK_INIT_SIZE * sizeof(SElemType)); + if((*S).base == NULL) { + exit(OVERFLOW); + } + + (*S).top = (*S).base; + (*S).stacksize = STACK_INIT_SIZE; + + return OK; +} + +/* + * 取值 + * + * 返回栈顶元素,并用e接收。 + */ +Status GetTop(SqStack S, SElemType* e) { + if(S.base == NULL || S.top == S.base) { + return ERROR; + } + + // 不会改变栈中元素 + *e = *(S.top - 1); + + return OK; +} + +/* + * 入栈 + * + * 将元素e压入到栈顶。 + */ +Status Push(SqStack* S, SElemType e) { + if(S == NULL || (*S).base == NULL) { + return ERROR; + } + + // 栈满时,追加存储空间 + if((*S).top - (*S).base >= (*S).stacksize) { + (*S).base = (SElemType*) realloc((*S).base, ((*S).stacksize + STACKINCREMENT) * sizeof(SElemType)); + if((*S).base == NULL) { + exit(OVERFLOW); // 存储分配失败 + } + + (*S).top = (*S).base + (*S).stacksize; + (*S).stacksize += STACKINCREMENT; + } + + // 进栈先赋值,栈顶指针再自增 + *(S->top++) = e; + + return OK; +} + +/* + * 出栈 + * + * 将栈顶元素弹出,并用e接收。 + */ +Status Pop(SqStack* S, SElemType* e) { + if(S == NULL || (*S).base == NULL) { + return ERROR; + } + + if((*S).top == (*S).base) { + return ERROR; + } + + // 出栈栈顶指针先递减,再赋值 + *e = *(--(*S).top); + + return OK; +} diff --git a/CLion/ExerciseBook/04.14/SqStack.h b/CLion/ExerciseBook/04.14/SqStack.h new file mode 100644 index 0000000..3e743cc --- /dev/null +++ b/CLion/ExerciseBook/04.14/SqStack.h @@ -0,0 +1,61 @@ +/*========================= + * 栈的顺序存储结构(顺序栈) + ==========================*/ + +#ifndef SQSTACK_H +#define SQSTACK_H + +#include +#include // 提供malloc、realloc、free、exit原型 +#include "Status.h" //**▲01 绪论**// +#include "String.h" //**▲04 串**// + +/* 宏定义 */ +#define STACK_INIT_SIZE 100 // 顺序栈存储空间的初始分配量 +#define STACKINCREMENT 10 // 顺序栈存储空间的分配增量 + +/* + * 顺序栈元素类型定义 + * + *【注】 + * 这里的元素类型为字符串 + */ +typedef StringType SElemType; + +// 顺序栈元素结构 +typedef struct { + SElemType* base; // 栈底指针 + SElemType* top; // 栈顶指针 + int stacksize; // 当前已分配的存储空间,以元素为单位 +} SqStack; + + +/* + * 初始化 + * + * 构造一个空栈。初始化成功则返回OK,否则返回ERROR。 + */ +Status InitStack(SqStack* S); + +/* + * 取值 + * + * 返回栈顶元素,并用e接收。 + */ +Status GetTop(SqStack S, SElemType* e); + +/* + * 入栈 + * + * 将元素e压入到栈顶。 + */ +Status Push(SqStack* S, SElemType e); + +/* + * 出栈 + * + * 将栈顶元素弹出,并用e接收。 + */ +Status Pop(SqStack* S, SElemType* e); + +#endif diff --git a/CLion/ExerciseBook/04.14/String.c b/CLion/ExerciseBook/04.14/String.c new file mode 100644 index 0000000..a476438 --- /dev/null +++ b/CLion/ExerciseBook/04.14/String.c @@ -0,0 +1,151 @@ +/*=========================== + * 习题4.10~4.14中使用的字符串 + ============================*/ + +#include "String.h" + +// 初始化:构造一个值为s的串t +void StrAssign(StringType* t, const char* s) { + if(s == NULL) { + *t = ""; + } + + *t = (char*) malloc((strlen(s) + 1) * sizeof(char)); + + strcpy(*t, s); +} + +// 比较:返回s与t的大小,如果大小一致,返回0 +int StrCompare(StringType s, StringType t) { + return strcmp(s, t); +} + +// 计数:返回字符串s的长度 +int StrLength(StringType s) { + return (int) strlen(s); +} + +// 联接:返回由s与t联接后的串 +StringType Concat(StringType s, StringType t) { + StringType r; + + if(s == NULL) { + s = ""; + } + + if(t == NULL) { + t = ""; + } + + r = (char*) malloc((strlen(s) + strlen(t) + 1) * sizeof(char)); + r[0] = '\0'; + + strcat(r, s); + strcat(r, t); + + return r; +} + +// 求子串:从s的start位置起,截取len个字符后返回 +StringType SubString(StringType s, int start, int len) { + int n; + char* sub; + + n = (int) strlen(s); + + if(start < 1 || start > n || start + len - 1 > n || len < 0) { + return ""; + } + + sub = (char*) malloc((len + 1) * sizeof(char)); + strncpy(sub, s + start - 1, len); + sub[len] = '\0'; + + return sub; +} + +// 查找:从s的pos位置起查找t,如果找到,返回其位置 +int Index(StringType s, StringType t, int pos) { + int m, n, i; + StringType sub; + + // 失败情形提前处理 + if(pos < 1 || pos > StrLength(s) || StrLength(t) == 0) { + return 0; + } + + n = StrLength(s); + m = StrLength(t); + i = pos; + + // 保证长度不越界 + while(i <= n - m + 1) { + // 获取S[i, i+m-1] + sub = SubString(s, i, m); + + // 如果子串与模式串不匹配,则需要继续推进 + if(StrCompare(sub, t) != 0) { + ++i; + } else { + return i; + } + } + + return 0; +} + +// 插入:在s的pos处插入t +Status StrInsert(StringType* s, int pos, StringType t) { + StringType r; + StringType s1, s2; + + if(pos < 1 || pos > StrLength(*s) + 1) { + return ERROR; + } + + r = (StringType) malloc((strlen(*s) + strlen(t) + 1) * sizeof(char)); + r[0] = '\0'; + + // 如果待插入的串为空,则提前返回 + if(StrLength(t) == 0) { + return OK; + } + + s1 = SubString(*s, 1, pos - 1); + s2 = SubString(*s, pos, (int) strlen(*s) - pos + 1); + + strcat(r, s1); + strcat(r, t); + strcat(r, s2); + + *s = r; + + return OK; +} + +// 删除:从s的pos位置起,删除len个字符 +Status StrDelete(StringType* s, int pos, int len) { + StringType r; + + if(pos < 1 || pos + len - 1 > StrLength(*s) || len < 0) { + return ERROR; + } + + // 如果待删除的长度为0,则提前返回 + if(len == 0) { + return OK; + } + + r = (StringType) malloc((StrLength(*s) - len + 1) * sizeof(char)); + strncpy(r, *s, pos - 1); + strcpy(r + pos - 1, *s + pos + len - 1); + + *s = r; + + return OK; +} + +// 输出字符串 +void StrPrint(StringType s) { + printf("%s\n", s); +} diff --git a/CLion/ExerciseBook/04.14/String.h b/CLion/ExerciseBook/04.14/String.h new file mode 100644 index 0000000..f4711a9 --- /dev/null +++ b/CLion/ExerciseBook/04.14/String.h @@ -0,0 +1,43 @@ +/*=========================== + * 习题4.10~4.14中使用的字符串 + ============================*/ + +#ifndef STRING_H +#define STRING_H + +#include +#include // 提供 strlen 原型 +#include "Status.h" //**▲01 绪论**// + +/* 字符串类型 */ +typedef char* StringType; + + +// 初始化:构造一个值为s的串t +void StrAssign(StringType* t, const char* s); + +// 比较:返回s与t的大小,如果大小一致,返回0 +int StrCompare(StringType s, StringType t); + +// 计数:返回字符串s的长度 +int StrLength(StringType s); + +// 联接:返回由s与t联接后的串 +StringType Concat(StringType s, StringType t); + +// 求子串:从s的start位置起,截取len个字符后返回 +StringType SubString(StringType s, int start, int len); + +// 查找:从s的pos位置起查找t,如果找到,返回其位置 +int Index(StringType s, StringType t, int pos); + +// 插入:在s的pos处插入t +Status StrInsert(StringType* s, int pos, StringType t); + +// 删除:从s的pos位置起,删除len个字符 +Status StrDelete(StringType* s, int pos, int len); + +// 输出字符串 +void StrPrint(StringType s); + +#endif diff --git a/CLion/ExerciseBook/04.15-04.17/04.15-04.17.c b/CLion/ExerciseBook/04.15-04.17/04.15-04.17.c new file mode 100644 index 0000000..bcb35a6 --- /dev/null +++ b/CLion/ExerciseBook/04.15-04.17/04.15-04.17.c @@ -0,0 +1,92 @@ +#include +#include "Status.h" //**▲01 绪论**// +#include "SString.h" //**▲04 串**// + +/* + * 初始化:StrAssign + * + *【注】 + * 该函数已在SString相关文件中定义 + */ +Status Algo_4_15(SString T, char* chars); + +/* + * 比较:StrCompare + * + *【注】 + * 该函数已在SString相关文件中定义 + */ +int Algo_4_16(SString S, SString T); + +/* + * 替换:Replace + * + *【注】 + * 该函数已在SString相关文件中定义 + */ +Status Algo_4_17(SString S, SString T, SString V); + + +int main(int argc, char* argv[]) { + char* t = "ab**c*de***fg"; + char* s = "ab**c*de***fh"; + SString T, S, M1, M2; + int i; + + printf("███题 4.15 验证...███\n"); + Algo_4_15(T, t); + Algo_4_15(S, s); + printf("T = "); + StrPrint(T); + printf("S = "); + StrPrint(S); + + printf("███题 4.16 验证...███\n"); + i = Algo_4_16(S, T); + if(i > 0) { + printf("S > T\n"); + } else if(i < 0) { + printf("S < T\n"); + } else { + printf("S == T\n"); + } + + printf("███题 4.17 验证...███\n"); + Algo_4_15(M1, "**"); + Algo_4_15(M2, "^"); + Algo_4_17(S, M1, M2); + printf("用 \"^\" 替换 \"**\" 后:\nS = "); + StrPrint(S); + + return 0; +} + +/* + * 初始化:StrAssign + * + *【注】 + * 该函数已在SString相关文件中定义 + */ +Status Algo_4_15(SString T, char* chars) { + return StrAssign(T, chars); +} + +/* + * 比较:StrCompare + * + *【注】 + * 该函数已在SString相关文件中定义 + */ +int Algo_4_16(SString S, SString T) { + return StrCompare(S, T); +} + +/* + * 替换:Replace + * + *【注】 + * 该函数已在SString相关文件中定义 + */ +Status Algo_4_17(SString S, SString T, SString V) { + return Replace(S, T, V); +} diff --git a/CLion/ExerciseBook/04.15-04.17/CMakeLists.txt b/CLion/ExerciseBook/04.15-04.17/CMakeLists.txt new file mode 100644 index 0000000..3483e43 --- /dev/null +++ b/CLion/ExerciseBook/04.15-04.17/CMakeLists.txt @@ -0,0 +1,7 @@ +# 包含公共库 +include_directories(${CMAKE_SOURCE_DIR}/Status) + +# 生成可执行文件 +add_executable(04.15-04.17 SString.h SString.c 04.15-04.17.c) +# 链接公共库 +target_link_libraries(04.15-04.17 Scanf_lib) \ No newline at end of file diff --git a/CLion/ExerciseBook/04.15-04.17/SString.c b/CLion/ExerciseBook/04.15-04.17/SString.c new file mode 100644 index 0000000..8673b3b --- /dev/null +++ b/CLion/ExerciseBook/04.15-04.17/SString.c @@ -0,0 +1,406 @@ +/*============================= + * 串的定长顺序存储表示(顺序串) + * + * 包含算法: 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 DestroyString(SString S) { + 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; +} + +/* + * ████████ 算法4.1 ████████ + * + * 查找 + * + * 从pos处开始搜索模式串T在主串S中首次出现的位置,如果不存在,则返回0。 + * 如果查找成功,返回匹配的位置。 + * + *【注】 + * 1.此实现需要依赖串的最小操作子集 + * 2.该实现比较低效 + */ +int Index_1(SString S, SString T, int pos) { + int i, n, m; // 记录S和T的长度 + SString sub; + + /* + * 失败情形提前处理 + * 这里与教材写法略微不同 + */ + if(pos < 1 || pos > S[0] || StrEmpty(T)) { + return 0; + } + + n = StrLength(S); + m = StrLength(T); + i = pos; + + // 保证长度不越界 + while(i <= n - m + 1) { + // 获取S[i, i+m-1] + SubString(sub, S, i, m); + + // 如果子串与模式串不匹配,则需要继续推进 + if(StrCompare(sub, T) != 0) { + ++i; + } else { + return i; + } + } + + return 0; +} + +/* + * ████████ 算法4.5 ████████ + * + * 查找 + * + * 从pos处开始搜索模式串T在主串S中首次出现的位置,如果不存在,则返回0。 + * 如果查找成功,返回匹配的位置。 + * + *【注】 + * 1.此实现不依赖串的最小操作子集 + * 2.该实现比较低效 + */ +int Index_2(SString S, SString T, int pos) { + int i = pos; + int j = 1; + + if(pos < 1 || pos > S[0] || StrEmpty(T)) { + return 0; + } + + while(i <= S[0] && j <= T[0]) { + // 遇到相同字符,则继续比较后继字符 + if(S[i] == T[j]) { + i++; + j++; + + // 遇到不同的字符,则游标需要回退,重新比较 + } else { + i = i - (j - 1) + 1; // j-1代表徒劳地前进了j-1个元素,在第j个元素上功亏一篑 + j = 1; // 游标j回到串T的第一个位置 + } + } + + // 增加了一个T[0]>0的判断 + if(j > T[0] && T[0] > 0) { // T不为空串 + return i - T[0]; // 匹配成功 + } else { + return 0; + } +} + +/* + * 插入 + * + * 将串T插入到主串S的pos位置处。 + */ +Status StrInsert(SString S, int pos, SString T) { + int i; + + if(pos < 1 || pos > S[0] + 1 || S[0] + T[0] > MAXSTRLEN) { + return ERROR; + } + + // 如果待插入的串为空,则提前返回 + if(StrEmpty(T)) { + return OK; + } + + // 在S中腾出位置,为插入T做准备 + for(i = S[0]; i >= pos; i--) { + // 从后向前遍历,将前面的元素挪到后面 + S[i + T[0]] = S[i]; + } + + // 将串T插入在S中腾出的位置上 + for(i = pos; i <= pos + T[0] - 1; i++) { + S[i] = T[i - pos + 1]; + } + + // 长度增加 + S[0] += T[0]; + + 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; +} + +/* + * 替换 + * + * 用V替换主串S中出现的所有与T相等的且不重叠的子串。 + * + *【注】 + * 1.该操作依赖最小操作子集 + * 2.该实现比较低效 + */ +Status Replace(SString S, SString T, SString V) { + int i; + + if(StrEmpty(S) || StrEmpty(T)) { + return ERROR; + } + + // 在主串S中寻找模式串T第一次出现的位置 + i = Index_2(S, T, 1); + + // 如果存在匹配的字符串,且可以被完全替换(替换后不溢出) + while(i != 0 && S[0] - T[0] + V[0] <= MAXSTRLEN) { + StrDelete(S, i, StrLength(T)); // 从S中删除T + StrInsert(S, i, V); // 向S中插入V + + i += StrLength(V); // i切换到下一个位置 + + i = Index_2(S, T, i); // 查找下一个匹配的字符串 + } + + if(i == 0) { // S中的T已全部被替换 + return OK; + } else { // S中尚有T,但是V已经插不进去了 + return ERROR; + } +} + +/* + * ████████ 算法4.2 ████████ + * + * 串联接 + * + * 联接S1和S2,并存储到T中返回。如果联接后的长度溢出,则只保留未溢出的部分。 + * 返回值表示联接后的串是否完整。 + * + *【注】 + * 该操作属于最小操作子集 + */ +Status Concat(SString T, SString S1, SString S2) { + int i; + int uncut; // 新串是否完整 + + // 完全不需要裁剪 + if(S1[0] + S2[0] <= MAXSTRLEN) { + // 复制S1到T中 + for(i = 1; i <= S1[0]; i++) { + T[i] = S1[i]; + } + + // 复制S2到T中 + for(i = S1[0] + 1; i <= S1[0] + S2[0]; i++) { + T[i] = S2[i - S1[0]]; + } + + // 设置新长度 + T[0] = S1[0] + S2[0]; + + // 未裁剪,完整 + uncut = TRUE; + + // 需要裁剪S2 + } else if(S1[0] <= MAXSTRLEN) { + // 复制S1到T中 + for(i = 1; i <= S1[0]; i++) { + T[i] = S1[i]; + } + + // 将S2的一部分复制到T中 + for(i = S1[0] + 1; i <= MAXSTRLEN; i++) { + T[i] = S2[i - S1[0]]; + } + + // 设置新长度 + T[0] = MAXSTRLEN; + + uncut = FALSE; + + // 只需要复制S1的一部分 + } else { + // 连同长度信息一起复制 + for(i = 0; i <= MAXSTRLEN; i++) { + T[i] = S1[i]; + } + + uncut = FALSE; + } + + return uncut; +} + +// 输出:打印字符串 +void StrPrint(SString S) { + int i; + + for(i = 1; i<=S[0] ; i++) { + printf("%c", S[i]); + } + + printf("\n"); +} diff --git a/CLion/ExerciseBook/04.15-04.17/SString.h b/CLion/ExerciseBook/04.15-04.17/SString.h new file mode 100644 index 0000000..d164913 --- /dev/null +++ b/CLion/ExerciseBook/04.15-04.17/SString.h @@ -0,0 +1,179 @@ +/*============================= + * 串的定长顺序存储表示(顺序串) + * + * 包含算法: 4.1、4.2、4.3、4.5 + ==============================*/ + +#ifndef SSTRING_H +#define SSTRING_H + +#include +#include // 提供strlen原型 +#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 DestroyString(SString S); + +/* + * 清空 + * + * 将串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); + +/* + * ████████ 算法4.1 ████████ + * + * 查找 + * + * 从pos处开始搜索模式串T在主串S中首次出现的位置,如果不存在,则返回0。 + * 如果查找成功,返回匹配的位置。 + * + *【注】 + * 1.此实现需要依赖串的最小操作子集 + * 2.该实现比较低效 + */ +int Index_1(SString S, SString T, int pos); + +/* + * ████████ 算法4.5 ████████ + * + * 查找 + * + * 从pos处开始搜索模式串T在主串S中首次出现的位置,如果不存在,则返回0。 + * 如果查找成功,返回匹配的位置。 + * + *【注】 + * 1.此实现不依赖串的最小操作子集 + * 2.该实现比较低效 + */ +int Index_2(SString S, SString T, int pos); + +/* + * 插入 + * + * 将串T插入到主串S的pos位置处。 + */ +Status StrInsert(SString S, int pos, SString T); + +/* + * 删除 + * + * 删除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); + +/* + * 替换 + * + * 用V替换主串S中出现的所有与T相等的且不重叠的子串。 + * + *【注】 + * 该操作依赖最小操作子集,效率较低。 + */ +Status Replace(SString S, SString T, SString V); + +/* + * ████████ 算法4.2 ████████ + * + * 串联接 + * + * 联接S1和S2,并存储到T中返回。如果联接后的长度溢出,则只保留未溢出的部分。 + * 返回值表示联接后的串是否完整。 + * + *【注】 + * 该操作属于最小操作子集 + */ +Status Concat(SString T, SString S1, SString S2); + +// 输出:打印字符串 +void StrPrint(SString S); + +#endif diff --git a/CLion/ExerciseBook/04.18/04.18.c b/CLion/ExerciseBook/04.18/04.18.c new file mode 100644 index 0000000..38049c4 --- /dev/null +++ b/CLion/ExerciseBook/04.18/04.18.c @@ -0,0 +1,62 @@ +#include +#include +#include "SString.h" //**▲04 串**// + +/* + * 统计字符串S中不同字符总数与每种字符的个数,返回统计结果 + */ +int* Algo_4_18(SString S); + + +int main(int argc, char* argv[]) { + char* s = "dbasydujhge638940[gptokljrsehgadcsbnmv,c.b'ng[p098437eywdghswqdecxvghju"; + SString S; + int* total; + int i; + + StrAssign(S, s); + printf("S = "); + StrPrint(S); + + total = Algo_4_18(S); + printf(" S 中不同的字符共计 %d 个:\n", total[0]); + for(i = 1; i <= 127; i++) { + if(total[i] != 0) { + printf("字符 \'%c\' 有 %d 个.\n", i, total[i]); + } + } + printf("统计完毕...\n"); + + return 0; +} + + +/* + * 统计字符串S中不同字符总数与每种字符的个数,返回统计结果 + */ +int* Algo_4_18(SString S) { + int i; + int* total; + + /* + * total长度设为128, + * 0号单元存储不同字符的总数, + * 其他单元存储各种不同字符的数量。 + * + * 注:不统计空字符'\0' + */ + total = (int*) malloc(128 * sizeof(int)); + memset(total, 0, 128 * sizeof(int)); + + for(i = 1; i <= S[0]; i++) { + // 如果遇到了新字符,则统计不同字符的数量 + if(total[S[i]] == 0) { + total[0]++; + } + + // 统计遇到的字符数量 + total[S[i]]++; + } + + return total; +} diff --git a/CLion/ExerciseBook/04.18/CMakeLists.txt b/CLion/ExerciseBook/04.18/CMakeLists.txt new file mode 100644 index 0000000..5df8341 --- /dev/null +++ b/CLion/ExerciseBook/04.18/CMakeLists.txt @@ -0,0 +1,7 @@ +# 包含公共库 +include_directories(${CMAKE_SOURCE_DIR}/Status) + +# 生成可执行文件 +add_executable(04.18 SString.h SString.c 04.18.c) +# 链接公共库 +target_link_libraries(04.18 Scanf_lib) \ No newline at end of file diff --git a/CLion/ExerciseBook/04.18/SString.c b/CLion/ExerciseBook/04.18/SString.c new file mode 100644 index 0000000..8673b3b --- /dev/null +++ b/CLion/ExerciseBook/04.18/SString.c @@ -0,0 +1,406 @@ +/*============================= + * 串的定长顺序存储表示(顺序串) + * + * 包含算法: 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 DestroyString(SString S) { + 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; +} + +/* + * ████████ 算法4.1 ████████ + * + * 查找 + * + * 从pos处开始搜索模式串T在主串S中首次出现的位置,如果不存在,则返回0。 + * 如果查找成功,返回匹配的位置。 + * + *【注】 + * 1.此实现需要依赖串的最小操作子集 + * 2.该实现比较低效 + */ +int Index_1(SString S, SString T, int pos) { + int i, n, m; // 记录S和T的长度 + SString sub; + + /* + * 失败情形提前处理 + * 这里与教材写法略微不同 + */ + if(pos < 1 || pos > S[0] || StrEmpty(T)) { + return 0; + } + + n = StrLength(S); + m = StrLength(T); + i = pos; + + // 保证长度不越界 + while(i <= n - m + 1) { + // 获取S[i, i+m-1] + SubString(sub, S, i, m); + + // 如果子串与模式串不匹配,则需要继续推进 + if(StrCompare(sub, T) != 0) { + ++i; + } else { + return i; + } + } + + return 0; +} + +/* + * ████████ 算法4.5 ████████ + * + * 查找 + * + * 从pos处开始搜索模式串T在主串S中首次出现的位置,如果不存在,则返回0。 + * 如果查找成功,返回匹配的位置。 + * + *【注】 + * 1.此实现不依赖串的最小操作子集 + * 2.该实现比较低效 + */ +int Index_2(SString S, SString T, int pos) { + int i = pos; + int j = 1; + + if(pos < 1 || pos > S[0] || StrEmpty(T)) { + return 0; + } + + while(i <= S[0] && j <= T[0]) { + // 遇到相同字符,则继续比较后继字符 + if(S[i] == T[j]) { + i++; + j++; + + // 遇到不同的字符,则游标需要回退,重新比较 + } else { + i = i - (j - 1) + 1; // j-1代表徒劳地前进了j-1个元素,在第j个元素上功亏一篑 + j = 1; // 游标j回到串T的第一个位置 + } + } + + // 增加了一个T[0]>0的判断 + if(j > T[0] && T[0] > 0) { // T不为空串 + return i - T[0]; // 匹配成功 + } else { + return 0; + } +} + +/* + * 插入 + * + * 将串T插入到主串S的pos位置处。 + */ +Status StrInsert(SString S, int pos, SString T) { + int i; + + if(pos < 1 || pos > S[0] + 1 || S[0] + T[0] > MAXSTRLEN) { + return ERROR; + } + + // 如果待插入的串为空,则提前返回 + if(StrEmpty(T)) { + return OK; + } + + // 在S中腾出位置,为插入T做准备 + for(i = S[0]; i >= pos; i--) { + // 从后向前遍历,将前面的元素挪到后面 + S[i + T[0]] = S[i]; + } + + // 将串T插入在S中腾出的位置上 + for(i = pos; i <= pos + T[0] - 1; i++) { + S[i] = T[i - pos + 1]; + } + + // 长度增加 + S[0] += T[0]; + + 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; +} + +/* + * 替换 + * + * 用V替换主串S中出现的所有与T相等的且不重叠的子串。 + * + *【注】 + * 1.该操作依赖最小操作子集 + * 2.该实现比较低效 + */ +Status Replace(SString S, SString T, SString V) { + int i; + + if(StrEmpty(S) || StrEmpty(T)) { + return ERROR; + } + + // 在主串S中寻找模式串T第一次出现的位置 + i = Index_2(S, T, 1); + + // 如果存在匹配的字符串,且可以被完全替换(替换后不溢出) + while(i != 0 && S[0] - T[0] + V[0] <= MAXSTRLEN) { + StrDelete(S, i, StrLength(T)); // 从S中删除T + StrInsert(S, i, V); // 向S中插入V + + i += StrLength(V); // i切换到下一个位置 + + i = Index_2(S, T, i); // 查找下一个匹配的字符串 + } + + if(i == 0) { // S中的T已全部被替换 + return OK; + } else { // S中尚有T,但是V已经插不进去了 + return ERROR; + } +} + +/* + * ████████ 算法4.2 ████████ + * + * 串联接 + * + * 联接S1和S2,并存储到T中返回。如果联接后的长度溢出,则只保留未溢出的部分。 + * 返回值表示联接后的串是否完整。 + * + *【注】 + * 该操作属于最小操作子集 + */ +Status Concat(SString T, SString S1, SString S2) { + int i; + int uncut; // 新串是否完整 + + // 完全不需要裁剪 + if(S1[0] + S2[0] <= MAXSTRLEN) { + // 复制S1到T中 + for(i = 1; i <= S1[0]; i++) { + T[i] = S1[i]; + } + + // 复制S2到T中 + for(i = S1[0] + 1; i <= S1[0] + S2[0]; i++) { + T[i] = S2[i - S1[0]]; + } + + // 设置新长度 + T[0] = S1[0] + S2[0]; + + // 未裁剪,完整 + uncut = TRUE; + + // 需要裁剪S2 + } else if(S1[0] <= MAXSTRLEN) { + // 复制S1到T中 + for(i = 1; i <= S1[0]; i++) { + T[i] = S1[i]; + } + + // 将S2的一部分复制到T中 + for(i = S1[0] + 1; i <= MAXSTRLEN; i++) { + T[i] = S2[i - S1[0]]; + } + + // 设置新长度 + T[0] = MAXSTRLEN; + + uncut = FALSE; + + // 只需要复制S1的一部分 + } else { + // 连同长度信息一起复制 + for(i = 0; i <= MAXSTRLEN; i++) { + T[i] = S1[i]; + } + + uncut = FALSE; + } + + return uncut; +} + +// 输出:打印字符串 +void StrPrint(SString S) { + int i; + + for(i = 1; i<=S[0] ; i++) { + printf("%c", S[i]); + } + + printf("\n"); +} diff --git a/CLion/ExerciseBook/04.18/SString.h b/CLion/ExerciseBook/04.18/SString.h new file mode 100644 index 0000000..d164913 --- /dev/null +++ b/CLion/ExerciseBook/04.18/SString.h @@ -0,0 +1,179 @@ +/*============================= + * 串的定长顺序存储表示(顺序串) + * + * 包含算法: 4.1、4.2、4.3、4.5 + ==============================*/ + +#ifndef SSTRING_H +#define SSTRING_H + +#include +#include // 提供strlen原型 +#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 DestroyString(SString S); + +/* + * 清空 + * + * 将串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); + +/* + * ████████ 算法4.1 ████████ + * + * 查找 + * + * 从pos处开始搜索模式串T在主串S中首次出现的位置,如果不存在,则返回0。 + * 如果查找成功,返回匹配的位置。 + * + *【注】 + * 1.此实现需要依赖串的最小操作子集 + * 2.该实现比较低效 + */ +int Index_1(SString S, SString T, int pos); + +/* + * ████████ 算法4.5 ████████ + * + * 查找 + * + * 从pos处开始搜索模式串T在主串S中首次出现的位置,如果不存在,则返回0。 + * 如果查找成功,返回匹配的位置。 + * + *【注】 + * 1.此实现不依赖串的最小操作子集 + * 2.该实现比较低效 + */ +int Index_2(SString S, SString T, int pos); + +/* + * 插入 + * + * 将串T插入到主串S的pos位置处。 + */ +Status StrInsert(SString S, int pos, SString T); + +/* + * 删除 + * + * 删除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); + +/* + * 替换 + * + * 用V替换主串S中出现的所有与T相等的且不重叠的子串。 + * + *【注】 + * 该操作依赖最小操作子集,效率较低。 + */ +Status Replace(SString S, SString T, SString V); + +/* + * ████████ 算法4.2 ████████ + * + * 串联接 + * + * 联接S1和S2,并存储到T中返回。如果联接后的长度溢出,则只保留未溢出的部分。 + * 返回值表示联接后的串是否完整。 + * + *【注】 + * 该操作属于最小操作子集 + */ +Status Concat(SString T, SString S1, SString S2); + +// 输出:打印字符串 +void StrPrint(SString S); + +#endif diff --git a/CLion/ExerciseBook/04.19/04.19.c b/CLion/ExerciseBook/04.19/04.19.c new file mode 100644 index 0000000..6b9845c --- /dev/null +++ b/CLion/ExerciseBook/04.19/04.19.c @@ -0,0 +1,77 @@ +#include +#include +#include "SString.h" //**▲04 串**// + +/* + * R=S-S∩T,数组a存储R中每个字符在S中第一次出现的位置 + * + * 注:数组a的0号单元存储的是a中元素的个数 + */ +void Algo_4_19(SString R, SString S, SString T, int** a); + + +int main(int argc, char* argv[]) { + char* s = "amdhcjgfdlpinbefcopgkqikeb"; + char* t = "mhjlpinopkqik"; + int* a; + SString T, S, R; + int i; + + printf("初始化S和T...\n"); + StrAssign(S, s); + StrAssign(T, t); + + printf("S = "); + StrPrint(S); + printf("T = "); + StrPrint(T); + + Algo_4_19(R, S, T, &a); + printf("R = "); + StrPrint(R); + printf("a = "); + for(i = 1; i <= a[0]; i++) { + printf("%d ", a[i]); + } + printf("\n"); + + return 0; +} + + +/* + * R=S-S∩T,数组a存储R中每个字符在S中第一次出现的位置 + * + * 注:数组a的0号单元存储的是a中元素的个数 + */ +void Algo_4_19(SString R, SString S, SString T, int** a) { + int i, p; + SString ch; + + *a = (int*) malloc((StrLength(S) + 1) * sizeof(int)); + + StrAssign(R, ""); + + for(i = 1, (*a)[0] = 0; i <= StrLength(S); i++) { + // 取出字符进行判断 + SubString(ch, S, i, 1); + + // 获取S[i]在T中的位置 + p = Index_2(T, ch, 1); + + // 如果S[i]不在T中 + if(p == 0) { + // 获取S[i]在R中的位置 + p = Index_2(R, ch, 1); + } + + // 如果S[i]既不在T中,又没在R中出现过 + if(p == 0) { + (*a)[0]++; + (*a)[(*a)[0]] = i; + + // 向R中添加S[i] + StrInsert(R, (*a)[0], ch); + } + } +} diff --git a/CLion/ExerciseBook/04.19/CMakeLists.txt b/CLion/ExerciseBook/04.19/CMakeLists.txt new file mode 100644 index 0000000..73378ec --- /dev/null +++ b/CLion/ExerciseBook/04.19/CMakeLists.txt @@ -0,0 +1,7 @@ +# 包含公共库 +include_directories(${CMAKE_SOURCE_DIR}/Status) + +# 生成可执行文件 +add_executable(04.19 SString.h SString.c 04.19.c) +# 链接公共库 +target_link_libraries(04.19 Scanf_lib) \ No newline at end of file diff --git a/CLion/ExerciseBook/04.19/SString.c b/CLion/ExerciseBook/04.19/SString.c new file mode 100644 index 0000000..8673b3b --- /dev/null +++ b/CLion/ExerciseBook/04.19/SString.c @@ -0,0 +1,406 @@ +/*============================= + * 串的定长顺序存储表示(顺序串) + * + * 包含算法: 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 DestroyString(SString S) { + 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; +} + +/* + * ████████ 算法4.1 ████████ + * + * 查找 + * + * 从pos处开始搜索模式串T在主串S中首次出现的位置,如果不存在,则返回0。 + * 如果查找成功,返回匹配的位置。 + * + *【注】 + * 1.此实现需要依赖串的最小操作子集 + * 2.该实现比较低效 + */ +int Index_1(SString S, SString T, int pos) { + int i, n, m; // 记录S和T的长度 + SString sub; + + /* + * 失败情形提前处理 + * 这里与教材写法略微不同 + */ + if(pos < 1 || pos > S[0] || StrEmpty(T)) { + return 0; + } + + n = StrLength(S); + m = StrLength(T); + i = pos; + + // 保证长度不越界 + while(i <= n - m + 1) { + // 获取S[i, i+m-1] + SubString(sub, S, i, m); + + // 如果子串与模式串不匹配,则需要继续推进 + if(StrCompare(sub, T) != 0) { + ++i; + } else { + return i; + } + } + + return 0; +} + +/* + * ████████ 算法4.5 ████████ + * + * 查找 + * + * 从pos处开始搜索模式串T在主串S中首次出现的位置,如果不存在,则返回0。 + * 如果查找成功,返回匹配的位置。 + * + *【注】 + * 1.此实现不依赖串的最小操作子集 + * 2.该实现比较低效 + */ +int Index_2(SString S, SString T, int pos) { + int i = pos; + int j = 1; + + if(pos < 1 || pos > S[0] || StrEmpty(T)) { + return 0; + } + + while(i <= S[0] && j <= T[0]) { + // 遇到相同字符,则继续比较后继字符 + if(S[i] == T[j]) { + i++; + j++; + + // 遇到不同的字符,则游标需要回退,重新比较 + } else { + i = i - (j - 1) + 1; // j-1代表徒劳地前进了j-1个元素,在第j个元素上功亏一篑 + j = 1; // 游标j回到串T的第一个位置 + } + } + + // 增加了一个T[0]>0的判断 + if(j > T[0] && T[0] > 0) { // T不为空串 + return i - T[0]; // 匹配成功 + } else { + return 0; + } +} + +/* + * 插入 + * + * 将串T插入到主串S的pos位置处。 + */ +Status StrInsert(SString S, int pos, SString T) { + int i; + + if(pos < 1 || pos > S[0] + 1 || S[0] + T[0] > MAXSTRLEN) { + return ERROR; + } + + // 如果待插入的串为空,则提前返回 + if(StrEmpty(T)) { + return OK; + } + + // 在S中腾出位置,为插入T做准备 + for(i = S[0]; i >= pos; i--) { + // 从后向前遍历,将前面的元素挪到后面 + S[i + T[0]] = S[i]; + } + + // 将串T插入在S中腾出的位置上 + for(i = pos; i <= pos + T[0] - 1; i++) { + S[i] = T[i - pos + 1]; + } + + // 长度增加 + S[0] += T[0]; + + 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; +} + +/* + * 替换 + * + * 用V替换主串S中出现的所有与T相等的且不重叠的子串。 + * + *【注】 + * 1.该操作依赖最小操作子集 + * 2.该实现比较低效 + */ +Status Replace(SString S, SString T, SString V) { + int i; + + if(StrEmpty(S) || StrEmpty(T)) { + return ERROR; + } + + // 在主串S中寻找模式串T第一次出现的位置 + i = Index_2(S, T, 1); + + // 如果存在匹配的字符串,且可以被完全替换(替换后不溢出) + while(i != 0 && S[0] - T[0] + V[0] <= MAXSTRLEN) { + StrDelete(S, i, StrLength(T)); // 从S中删除T + StrInsert(S, i, V); // 向S中插入V + + i += StrLength(V); // i切换到下一个位置 + + i = Index_2(S, T, i); // 查找下一个匹配的字符串 + } + + if(i == 0) { // S中的T已全部被替换 + return OK; + } else { // S中尚有T,但是V已经插不进去了 + return ERROR; + } +} + +/* + * ████████ 算法4.2 ████████ + * + * 串联接 + * + * 联接S1和S2,并存储到T中返回。如果联接后的长度溢出,则只保留未溢出的部分。 + * 返回值表示联接后的串是否完整。 + * + *【注】 + * 该操作属于最小操作子集 + */ +Status Concat(SString T, SString S1, SString S2) { + int i; + int uncut; // 新串是否完整 + + // 完全不需要裁剪 + if(S1[0] + S2[0] <= MAXSTRLEN) { + // 复制S1到T中 + for(i = 1; i <= S1[0]; i++) { + T[i] = S1[i]; + } + + // 复制S2到T中 + for(i = S1[0] + 1; i <= S1[0] + S2[0]; i++) { + T[i] = S2[i - S1[0]]; + } + + // 设置新长度 + T[0] = S1[0] + S2[0]; + + // 未裁剪,完整 + uncut = TRUE; + + // 需要裁剪S2 + } else if(S1[0] <= MAXSTRLEN) { + // 复制S1到T中 + for(i = 1; i <= S1[0]; i++) { + T[i] = S1[i]; + } + + // 将S2的一部分复制到T中 + for(i = S1[0] + 1; i <= MAXSTRLEN; i++) { + T[i] = S2[i - S1[0]]; + } + + // 设置新长度 + T[0] = MAXSTRLEN; + + uncut = FALSE; + + // 只需要复制S1的一部分 + } else { + // 连同长度信息一起复制 + for(i = 0; i <= MAXSTRLEN; i++) { + T[i] = S1[i]; + } + + uncut = FALSE; + } + + return uncut; +} + +// 输出:打印字符串 +void StrPrint(SString S) { + int i; + + for(i = 1; i<=S[0] ; i++) { + printf("%c", S[i]); + } + + printf("\n"); +} diff --git a/CLion/ExerciseBook/04.19/SString.h b/CLion/ExerciseBook/04.19/SString.h new file mode 100644 index 0000000..d164913 --- /dev/null +++ b/CLion/ExerciseBook/04.19/SString.h @@ -0,0 +1,179 @@ +/*============================= + * 串的定长顺序存储表示(顺序串) + * + * 包含算法: 4.1、4.2、4.3、4.5 + ==============================*/ + +#ifndef SSTRING_H +#define SSTRING_H + +#include +#include // 提供strlen原型 +#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 DestroyString(SString S); + +/* + * 清空 + * + * 将串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); + +/* + * ████████ 算法4.1 ████████ + * + * 查找 + * + * 从pos处开始搜索模式串T在主串S中首次出现的位置,如果不存在,则返回0。 + * 如果查找成功,返回匹配的位置。 + * + *【注】 + * 1.此实现需要依赖串的最小操作子集 + * 2.该实现比较低效 + */ +int Index_1(SString S, SString T, int pos); + +/* + * ████████ 算法4.5 ████████ + * + * 查找 + * + * 从pos处开始搜索模式串T在主串S中首次出现的位置,如果不存在,则返回0。 + * 如果查找成功,返回匹配的位置。 + * + *【注】 + * 1.此实现不依赖串的最小操作子集 + * 2.该实现比较低效 + */ +int Index_2(SString S, SString T, int pos); + +/* + * 插入 + * + * 将串T插入到主串S的pos位置处。 + */ +Status StrInsert(SString S, int pos, SString T); + +/* + * 删除 + * + * 删除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); + +/* + * 替换 + * + * 用V替换主串S中出现的所有与T相等的且不重叠的子串。 + * + *【注】 + * 该操作依赖最小操作子集,效率较低。 + */ +Status Replace(SString S, SString T, SString V); + +/* + * ████████ 算法4.2 ████████ + * + * 串联接 + * + * 联接S1和S2,并存储到T中返回。如果联接后的长度溢出,则只保留未溢出的部分。 + * 返回值表示联接后的串是否完整。 + * + *【注】 + * 该操作属于最小操作子集 + */ +Status Concat(SString T, SString S1, SString S2); + +// 输出:打印字符串 +void StrPrint(SString S); + +#endif diff --git a/CLion/ExerciseBook/04.20/04.20.c b/CLion/ExerciseBook/04.20/04.20.c new file mode 100644 index 0000000..a5aa91e --- /dev/null +++ b/CLion/ExerciseBook/04.20/04.20.c @@ -0,0 +1,47 @@ +#include +#include "Status.h" //**▲01 绪论**// +#include "SString.h" //**▲04 串**// + +/* + * 删除S中包含的T + */ +Status Algo_4_20(SString S, SString T); + + +int main(int argc, char* argv[]) { + char* s = "----***--*-**-****-*****-----"; + char* t = "**"; + SString T, S; + + printf("删除前...\n"); + StrAssign(S, s); + StrAssign(T, t); + printf("S = "); + StrPrint(S); + printf("T = "); + StrPrint(T); + + printf("删除后...\n"); + printf("S = "); + Algo_4_20(S, T); + StrPrint(S); + + return 0; +} + + +/* + * 删除S中包含的T + */ +Status Algo_4_20(SString S, SString T) { + int i; + + // 在S中查找T,如果找到就删除 + while((i = Index_2(S, T, 1)) != 0) { + if(StrDelete(S, i, StrLength(T)) == ERROR) { + return ERROR; + } + } + + return OK; +} diff --git a/CLion/ExerciseBook/04.20/CMakeLists.txt b/CLion/ExerciseBook/04.20/CMakeLists.txt new file mode 100644 index 0000000..9dcf39c --- /dev/null +++ b/CLion/ExerciseBook/04.20/CMakeLists.txt @@ -0,0 +1,7 @@ +# 包含公共库 +include_directories(${CMAKE_SOURCE_DIR}/Status) + +# 生成可执行文件 +add_executable(04.20 SString.h SString.c 04.20.c) +# 链接公共库 +target_link_libraries(04.20 Scanf_lib) \ No newline at end of file diff --git a/CLion/ExerciseBook/04.20/SString.c b/CLion/ExerciseBook/04.20/SString.c new file mode 100644 index 0000000..8673b3b --- /dev/null +++ b/CLion/ExerciseBook/04.20/SString.c @@ -0,0 +1,406 @@ +/*============================= + * 串的定长顺序存储表示(顺序串) + * + * 包含算法: 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 DestroyString(SString S) { + 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; +} + +/* + * ████████ 算法4.1 ████████ + * + * 查找 + * + * 从pos处开始搜索模式串T在主串S中首次出现的位置,如果不存在,则返回0。 + * 如果查找成功,返回匹配的位置。 + * + *【注】 + * 1.此实现需要依赖串的最小操作子集 + * 2.该实现比较低效 + */ +int Index_1(SString S, SString T, int pos) { + int i, n, m; // 记录S和T的长度 + SString sub; + + /* + * 失败情形提前处理 + * 这里与教材写法略微不同 + */ + if(pos < 1 || pos > S[0] || StrEmpty(T)) { + return 0; + } + + n = StrLength(S); + m = StrLength(T); + i = pos; + + // 保证长度不越界 + while(i <= n - m + 1) { + // 获取S[i, i+m-1] + SubString(sub, S, i, m); + + // 如果子串与模式串不匹配,则需要继续推进 + if(StrCompare(sub, T) != 0) { + ++i; + } else { + return i; + } + } + + return 0; +} + +/* + * ████████ 算法4.5 ████████ + * + * 查找 + * + * 从pos处开始搜索模式串T在主串S中首次出现的位置,如果不存在,则返回0。 + * 如果查找成功,返回匹配的位置。 + * + *【注】 + * 1.此实现不依赖串的最小操作子集 + * 2.该实现比较低效 + */ +int Index_2(SString S, SString T, int pos) { + int i = pos; + int j = 1; + + if(pos < 1 || pos > S[0] || StrEmpty(T)) { + return 0; + } + + while(i <= S[0] && j <= T[0]) { + // 遇到相同字符,则继续比较后继字符 + if(S[i] == T[j]) { + i++; + j++; + + // 遇到不同的字符,则游标需要回退,重新比较 + } else { + i = i - (j - 1) + 1; // j-1代表徒劳地前进了j-1个元素,在第j个元素上功亏一篑 + j = 1; // 游标j回到串T的第一个位置 + } + } + + // 增加了一个T[0]>0的判断 + if(j > T[0] && T[0] > 0) { // T不为空串 + return i - T[0]; // 匹配成功 + } else { + return 0; + } +} + +/* + * 插入 + * + * 将串T插入到主串S的pos位置处。 + */ +Status StrInsert(SString S, int pos, SString T) { + int i; + + if(pos < 1 || pos > S[0] + 1 || S[0] + T[0] > MAXSTRLEN) { + return ERROR; + } + + // 如果待插入的串为空,则提前返回 + if(StrEmpty(T)) { + return OK; + } + + // 在S中腾出位置,为插入T做准备 + for(i = S[0]; i >= pos; i--) { + // 从后向前遍历,将前面的元素挪到后面 + S[i + T[0]] = S[i]; + } + + // 将串T插入在S中腾出的位置上 + for(i = pos; i <= pos + T[0] - 1; i++) { + S[i] = T[i - pos + 1]; + } + + // 长度增加 + S[0] += T[0]; + + 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; +} + +/* + * 替换 + * + * 用V替换主串S中出现的所有与T相等的且不重叠的子串。 + * + *【注】 + * 1.该操作依赖最小操作子集 + * 2.该实现比较低效 + */ +Status Replace(SString S, SString T, SString V) { + int i; + + if(StrEmpty(S) || StrEmpty(T)) { + return ERROR; + } + + // 在主串S中寻找模式串T第一次出现的位置 + i = Index_2(S, T, 1); + + // 如果存在匹配的字符串,且可以被完全替换(替换后不溢出) + while(i != 0 && S[0] - T[0] + V[0] <= MAXSTRLEN) { + StrDelete(S, i, StrLength(T)); // 从S中删除T + StrInsert(S, i, V); // 向S中插入V + + i += StrLength(V); // i切换到下一个位置 + + i = Index_2(S, T, i); // 查找下一个匹配的字符串 + } + + if(i == 0) { // S中的T已全部被替换 + return OK; + } else { // S中尚有T,但是V已经插不进去了 + return ERROR; + } +} + +/* + * ████████ 算法4.2 ████████ + * + * 串联接 + * + * 联接S1和S2,并存储到T中返回。如果联接后的长度溢出,则只保留未溢出的部分。 + * 返回值表示联接后的串是否完整。 + * + *【注】 + * 该操作属于最小操作子集 + */ +Status Concat(SString T, SString S1, SString S2) { + int i; + int uncut; // 新串是否完整 + + // 完全不需要裁剪 + if(S1[0] + S2[0] <= MAXSTRLEN) { + // 复制S1到T中 + for(i = 1; i <= S1[0]; i++) { + T[i] = S1[i]; + } + + // 复制S2到T中 + for(i = S1[0] + 1; i <= S1[0] + S2[0]; i++) { + T[i] = S2[i - S1[0]]; + } + + // 设置新长度 + T[0] = S1[0] + S2[0]; + + // 未裁剪,完整 + uncut = TRUE; + + // 需要裁剪S2 + } else if(S1[0] <= MAXSTRLEN) { + // 复制S1到T中 + for(i = 1; i <= S1[0]; i++) { + T[i] = S1[i]; + } + + // 将S2的一部分复制到T中 + for(i = S1[0] + 1; i <= MAXSTRLEN; i++) { + T[i] = S2[i - S1[0]]; + } + + // 设置新长度 + T[0] = MAXSTRLEN; + + uncut = FALSE; + + // 只需要复制S1的一部分 + } else { + // 连同长度信息一起复制 + for(i = 0; i <= MAXSTRLEN; i++) { + T[i] = S1[i]; + } + + uncut = FALSE; + } + + return uncut; +} + +// 输出:打印字符串 +void StrPrint(SString S) { + int i; + + for(i = 1; i<=S[0] ; i++) { + printf("%c", S[i]); + } + + printf("\n"); +} diff --git a/CLion/ExerciseBook/04.20/SString.h b/CLion/ExerciseBook/04.20/SString.h new file mode 100644 index 0000000..d164913 --- /dev/null +++ b/CLion/ExerciseBook/04.20/SString.h @@ -0,0 +1,179 @@ +/*============================= + * 串的定长顺序存储表示(顺序串) + * + * 包含算法: 4.1、4.2、4.3、4.5 + ==============================*/ + +#ifndef SSTRING_H +#define SSTRING_H + +#include +#include // 提供strlen原型 +#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 DestroyString(SString S); + +/* + * 清空 + * + * 将串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); + +/* + * ████████ 算法4.1 ████████ + * + * 查找 + * + * 从pos处开始搜索模式串T在主串S中首次出现的位置,如果不存在,则返回0。 + * 如果查找成功,返回匹配的位置。 + * + *【注】 + * 1.此实现需要依赖串的最小操作子集 + * 2.该实现比较低效 + */ +int Index_1(SString S, SString T, int pos); + +/* + * ████████ 算法4.5 ████████ + * + * 查找 + * + * 从pos处开始搜索模式串T在主串S中首次出现的位置,如果不存在,则返回0。 + * 如果查找成功,返回匹配的位置。 + * + *【注】 + * 1.此实现不依赖串的最小操作子集 + * 2.该实现比较低效 + */ +int Index_2(SString S, SString T, int pos); + +/* + * 插入 + * + * 将串T插入到主串S的pos位置处。 + */ +Status StrInsert(SString S, int pos, SString T); + +/* + * 删除 + * + * 删除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); + +/* + * 替换 + * + * 用V替换主串S中出现的所有与T相等的且不重叠的子串。 + * + *【注】 + * 该操作依赖最小操作子集,效率较低。 + */ +Status Replace(SString S, SString T, SString V); + +/* + * ████████ 算法4.2 ████████ + * + * 串联接 + * + * 联接S1和S2,并存储到T中返回。如果联接后的长度溢出,则只保留未溢出的部分。 + * 返回值表示联接后的串是否完整。 + * + *【注】 + * 该操作属于最小操作子集 + */ +Status Concat(SString T, SString S1, SString S2); + +// 输出:打印字符串 +void StrPrint(SString S); + +#endif diff --git a/CLion/ExerciseBook/04.21/04.21.c b/CLion/ExerciseBook/04.21/04.21.c new file mode 100644 index 0000000..4dac89b --- /dev/null +++ b/CLion/ExerciseBook/04.21/04.21.c @@ -0,0 +1,336 @@ +#include +#include // 提供 malloc、realloc、free、exit 原型 +#include +#include "Status.h" //**▲01 绪论**// + +/* + * 单链表元素类型定义 + * + *【注】 + * 这里的链表虽然用作字符串,但是元素类型仍然用int,原因是: + * 1.需要借用头结点存储结点的数量,所以用int比直接用char合适 + * 2.char可以与int兼容,所以结点虽然是int,但也可以用来存储char + */ +typedef int ElemType; + +/* + * 单链表结构 + * + * 注:这里的单链表存在头结点 + */ +typedef struct SNode { + ElemType data; // 数据结点 + struct SNode* next; // 指向下一个结点的指针 +} SNode; + +// 指向单链表结点的指针,用作字符串类型 +typedef SNode* String; + + +/* + * 初始化 + * + * 构造一个值为chars的串T。 + */ +Status StrAssign_4_21(String* S, char* chars); + +/* + * 复制 + * + * 将串S复制到串T。 + */ +Status StrCopy_4_21(String* S, String T); + +/* + * 比较 + * + * 比较串S和串T,返回比较结果。 + */ +int StrCompare_4_21(String S, String T); + +/* + * 计数 + * + * 返回串S中元素的个数。 + */ +int StrLength_4_21(String S); + +/* + * 串联接 + * + * 联接S1和S2,并存储到T中返回。如果联接后的长度溢出,则只保留未溢出的部分。 + * 返回值表示联接后的串是否完整。 + */ +Status Concat_4_21(String* R, String S1, String S2); + +/* + * 求子串 + * + * 用Sub返回S[pos, pos+len-1]。 + * 返回值指示是否截取成功。 + */ +Status SubString_4_21(String* Sub, String S, int pos, int len); + +// 字符串输出 +void StrPrint_4_21(String S); + + +int main(int argc, char* argv[]) { + char* chars = "0123456789"; + String S, T; + int i; + + printf("████████ StrAssign \n"); + { + printf("█ 为顺序串 S 赋值...\n"); + StrAssign_4_21(&S, chars); + printf("█ S = "); + StrPrint_4_21(S); + } + PressEnterToContinue(); + + printf("████████ StrLength \n"); + { + i = StrLength_4_21(S); + printf("█ S 的长度为 %d \n", i); + } + PressEnterToContinue(); + + printf("████████ StrCopy \n"); + { + printf("█ 复制 S 到 T ...\n"); + StrCopy_4_21(&T, S); + printf("█ T = "); + StrPrint_4_21(T); + } + PressEnterToContinue(); + + printf("████████ StrCompare \n"); + { + printf("█ 比较字符串 S 和 T ...\n"); + i = StrCompare_4_21(S, T); + i == 0 ? printf("█ S==T\n") : (i < 0 ? printf("█ ST\n")); + } + PressEnterToContinue(); + + printf("████████ SubString \n"); + { + String Sub; + + printf("█ 用 Sub 返回 S 中第 6 个字符起的 5 个字符...\n"); + SubString_4_21(&Sub, S, 6, 5); + printf("█ Sub = "); + StrPrint_4_21(Sub); + } + PressEnterToContinue(); + + + printf("████████ Concat \n"); + { + String Tmp, S1, S2; + + StrAssign_4_21(&S1, "+++++"); + StrAssign_4_21(&S2, "-----"); + + printf("█ 联接 \"+++++\" 和 \"-----\" 形成 Tmp ...\n"); + Concat_4_21(&Tmp, S1, S2); + printf("█ Tmp = "); + StrPrint_4_21(Tmp); + } + PressEnterToContinue(); + + return 0; +} + + +/* + * 初始化 + * + * 构造一个值为chars的串T。 + */ +Status StrAssign_4_21(String* S, char* chars) { + int i, len; + String p; + + if(S == NULL || chars == NULL) { + return ERROR; + } + + len = (int) strlen(chars); + + *S = (SNode*) malloc(sizeof(SNode)); + (*S)->data = len; + + p = *S; + + for(i = 0; i < len; i++) { + p->next = (SNode*) malloc(sizeof(SNode)); + p->next->data = chars[i]; + p = p->next; + } + + p->next = NULL; + + return OK; +} + +/* + * 复制 + * + * 将串S复制到串T。 + */ +Status StrCopy_4_21(String* S, String T) { + String p, r, t; + + if(S == NULL || T == NULL) { + return ERROR; + } + + for(t = T; t != NULL; t = t->next) { + r = (SNode*) malloc(sizeof(SNode)); + r->data = t->data; + + if(t == T) { + *S = r; + p = r; + } else { + p->next = r; + p = p->next; + } + } + + p->next = NULL; + + return OK; +} + +/* + * 比较 + * + * 比较串S和串T,返回比较结果。 + */ +int StrCompare_4_21(String S, String T) { + String s, t; + + if(S == NULL || T == NULL) { + return StrLength_4_21(S) - StrLength_4_21(T); + } + + s = S->next; + t = T->next; + + while(s != NULL && t != NULL) { + if(s->data != t->data) { + return s->data - t->data; + } + + s = s->next; + t = t->next; + } + + if(s == NULL && t != NULL) { + return -1; + } else if(s != NULL && t == NULL) { + return 1; + } else { + return 0; + } +} + +/* + * 计数 + * + * 返回串S中元素的个数。 + */ +int StrLength_4_21(String S) { + return S == NULL ? 0 : S->data; +} + +/* + * 串联接 + * + * 联接S1和S2,并存储到T中返回。如果联接后的长度溢出,则只保留未溢出的部分。 + * 返回值表示联接后的串是否完整。 + */ +Status Concat_4_21(String* R, String S1, String S2) { + String r, s, p; + + if(R == NULL || S1 == NULL || S2 == NULL) { + return ERROR; + } + + *R = (SNode*) malloc(sizeof(SNode)); + (*R)->data = S1->data + S2->data; + + r = *R; + + for(s = S1->next; s != NULL; s = s->next) { + p = (SNode*) malloc(sizeof(SNode)); + p->data = s->data; + r->next = p; + r = r->next; + } + + for(s = S2->next; s != NULL; s = s->next) { + p = (SNode*) malloc(sizeof(SNode)); + p->data = s->data; + r->next = p; + r = r->next; + } + + r->next = NULL; + + return OK; +} + +/* + * 求子串 + * + * 用Sub返回S[pos, pos+len-1]。 + * 返回值指示是否截取成功。 + */ +Status SubString_4_21(String* Sub, String S, int pos, int len) { + int i, slen; + String sub, s, p; + + slen = StrLength_4_21(S); + + if(Sub == NULL || S == NULL || pos < 1 || pos > slen || len < 0 || pos + len - 1 > slen) { + return ERROR; + } + + *Sub = (SNode*) malloc(sizeof(SNode)); + (*Sub)->data = len; + + for(i = 0, s = S; i < pos; i++, s = s->next) { + // 查找第pos个结点,并用s指向它 + } + + sub = *Sub; + + for(i = 0; i < len; i++) { + sub->next = (SNode*) malloc(sizeof(SNode)); + sub->next->data = s->data; + sub = sub->next; + + s = s->next; + } + + sub->next = NULL; + + return OK; +} + +// 字符串输出 +void StrPrint_4_21(String S) { + String p; + + if(S == NULL) { + return; + } + + for(p = S->next; p != NULL; p = p->next) { + printf("%c", p->data); + } + printf("\n"); +} diff --git a/CLion/ExerciseBook/04.21/CMakeLists.txt b/CLion/ExerciseBook/04.21/CMakeLists.txt new file mode 100644 index 0000000..6c8d8c2 --- /dev/null +++ b/CLion/ExerciseBook/04.21/CMakeLists.txt @@ -0,0 +1,7 @@ +# 包含公共库 +include_directories(${CMAKE_SOURCE_DIR}/Status) + +# 生成可执行文件 +add_executable(04.21 04.21.c) +# 链接公共库 +target_link_libraries(04.21 Scanf_lib) \ No newline at end of file diff --git a/CLion/ExerciseBook/04.22/04.22.c b/CLion/ExerciseBook/04.22/04.22.c new file mode 100644 index 0000000..2f5a8ef --- /dev/null +++ b/CLion/ExerciseBook/04.22/04.22.c @@ -0,0 +1,59 @@ +#include +#include "LString.h" //**▲04 串**// + +/* + * 将S插入到T中的字符c之后。 + * 如果有多个c,则将S插入到从左向右遍历T时遇到的首个c之后。 + * 如果T在不存在c,则将S插入到T的末尾。 + */ +void Algo_4_22(LString* T, char ch, LString S); + + +int main(int argc, char* argv[]) { + char* t = "----***--*-**-**^**-*****-----"; + char* s = "12345"; + char ch = '^'; + LString T, S; + + StrAssign(&T, t); + StrAssign(&S, s); + printf("T = "); + StrPrint(T); + printf("S = "); + StrPrint(S); + + Algo_4_22(&T, ch, S); + printf("T = "); + StrPrint(T); + + return 0; +} + + +/* + * 将S插入到T中的字符c之后。 + * 如果有多个c,则将S插入到从左向右遍历T时遇到的首个c之后。 + * 如果T在不存在c,则将S插入到T的末尾。 + */ +void Algo_4_22(LString* T, char c, LString S) { + int i; + char tmp[2]; + LString Tmp; + + // 构造目标串 + tmp[0] = c; + tmp[1] = '\0'; + StrAssign(&Tmp, tmp); + + // 寻找字符c在T中的位置 + i = Index((*T), Tmp, 1); + + // 如果找到了c,则将S插入到字符c之后 + if(i != 0) { + StrInsert(T, i + 1, S); + + // 如果没找到c,则将S插入到T的末尾 + } else { + StrInsert(T, (*T).curlen + 1, S); + } +} diff --git a/CLion/ExerciseBook/04.22/CMakeLists.txt b/CLion/ExerciseBook/04.22/CMakeLists.txt new file mode 100644 index 0000000..56e4da6 --- /dev/null +++ b/CLion/ExerciseBook/04.22/CMakeLists.txt @@ -0,0 +1,7 @@ +# 包含公共库 +include_directories(${CMAKE_SOURCE_DIR}/Status) + +# 生成可执行文件 +add_executable(04.22 LString.h LString.c 04.22.c) +# 链接公共库 +target_link_libraries(04.22 Scanf_lib) \ No newline at end of file diff --git a/CLion/ExerciseBook/04.22/LString.c b/CLion/ExerciseBook/04.22/LString.c new file mode 100644 index 0000000..bbec257 --- /dev/null +++ b/CLion/ExerciseBook/04.22/LString.c @@ -0,0 +1,747 @@ +/*============================= + * 串的块链分配存储表示(块链串) + ==============================*/ + +#include "LString.h" //**▲04 串**// + +/* + * 初始化 + * + * 构造一个值为chars的串T。 + * + *【注】 + * 该操作属于最小操作子集 + */ +Status StrAssign(LString* T, const char* chars) { + int len; // chars的长度 + int i, count; // 遍历块链串和字符串chars的游标 + int m; // 总块数 + int n; // 如果存在未填满的块,存储该块中的有效元素数量 + Chunk* r; + + // 求chars的长度 + len = (int) strlen(chars); + + // 没有有效元素 + if(len == 0) { + (*T).head = NULL; + (*T).tail = NULL; + (*T).curlen = 0; + + return OK; + } + + m = len / CHUNKSIZE; // 先计算需要填满的块 + n = len % CHUNKSIZE; // 如果存在未填满的块,计算该块中填充的有效元素数量 + if(n != 0) { + m++; // 计算总块数 + } + + // 1.创建块链串的结构 + for(i = 1; i <= m; i++) { + // 创建新块 + r = (Chunk*) malloc(sizeof(Chunk)); + if(r == NULL) { + exit(OVERFLOW); + } + r->next = NULL; + + // 第一个块 + if(i == 1) { + (*T).head = (*T).tail = r; + + // 联接后面的块 + } else { + (*T).tail->next = r; + (*T).tail = r; + } + } + + r = (*T).head; + i = 0; // 块链串T的游标 + count = 0; // 统计遍历过的元素,顺便作为chars的游标 + + // 2.为块链串填充内容 + while(count < len) { + r->ch[i] = chars[count]; + + i = (i + 1) % CHUNKSIZE; + if(i == 0) { + r = r->next; // 指向下一个块 + } + + count++; + } + + // 3.如果存在未填满的块 + if(n != 0) { + // 填充非串值内容(补上'\0') + while(i < CHUNKSIZE) { + (*T).tail->ch[i] = '\0'; + i++; + } + } + + // 4.记录长度信息 + (*T).curlen = len; + + return OK; +} + +/* + * 销毁 + * + *【注】 + * 块链串的结构可以销毁,但不是在销毁操作中 + */ +Status DestroyString(LString* S) { + return OK; +} + +/* + * 清空 + * + * 将串S清空。 + */ +Status ClearString(LString* S) { + Chunk* p, * q; + + p = (*S).head; + + // 释放所有串占用的空间 + while(p != NULL) { + q = p->next; + free(p); + p = q; + } + + (*S).head = NULL; + (*S).tail = NULL; + (*S).curlen = 0; + + return OK; +} + +/* + * 判空 + * + * 判断串S中是否包含有效数据。 + * + * 返回值: + * TRUE : 串S为空 + * FALSE: 串S不为空 + */ +Status StrEmpty(LString S) { + return S.curlen == 0 ? TRUE : FALSE; +} + +/* + * 计数 + * + * 返回串S中元素的个数。 + * + *【注】 + * 该操作属于最小操作子集 + */ +int StrLength(LString S) { + return S.curlen; +} + +/* + * 求子串 + * + * 用Sub返回S[pos, pos+len-1]。 + * 返回值指示是否截取成功。 + * + *【注】 + * 该操作属于最小操作子集 + */ +Status SubString(LString* Sub, LString S, int pos, int len) { + int m; // Sub的总块数 + int n; // 如果Sub存在未填满的块,存储该块中的有效元素数量 + int i, j, count; + Chunk* r, * p; + + if(pos < 1 || pos > S.curlen || len < 0 || pos + len - 1 > S.curlen) { + return ERROR; + } + + // 如果是截取0个字符,不需要分配空间 + if(len == 0) { + (*Sub).head = NULL; + (*Sub).tail = NULL; + (*Sub).curlen = 0; + + return OK; + } + + m = len / CHUNKSIZE; // 先计算需要填满的块 + n = len % CHUNKSIZE; // 如果Sub存在未填满的块,计算该块中填充的有效元素数量 + if(n != 0) { + m++; // 计算Sub的总块数 + } + + // 1.创建Sub的结构 + for(i = 1; i <= m; i++) { + // 创建新块 + r = (Chunk*) malloc(sizeof(Chunk)); + if(r == NULL) { + exit(OVERFLOW); + } + r->next = NULL; + + // 第一个块 + if(i == 1) { + (*Sub).head = (*Sub).tail = r; + + // 联接后面的块 + } else { + (*Sub).tail->next = r; + (*Sub).tail = r; + } + } + + // 查找S中第pos个元素所在的块,并用指针p指向它 + for(count = 1, p = S.head; pos > count * CHUNKSIZE; count++, p = p->next) { + // 空循环 + } + + r = (*Sub).head; // 指向Sub的块 + + i = 0; // 块链串Sub的游标 + j = (pos - 1) % CHUNKSIZE; // 块链串S 的游标 + count = 0; // 统计遍历过的元素 + + // 2.为块链串Sub填充内容 + while(count < len) { + r->ch[i] = p->ch[j]; + + i = (i + 1) % CHUNKSIZE; + if(i == 0) { + r = r->next; // 指向Sub中下一个块 + } + + j = (j + 1) % CHUNKSIZE; + if(j == 0) { + p = p->next; // 指向S中下一个块 + } + + count++; + } + + // 3.如果存在未填满的块 + if(n != 0) { + // 填充非串值内容(补上'\0') + while(i < CHUNKSIZE) { + (*Sub).tail->ch[i] = '\0'; + i++; + } + } + + // 4.记录长度信息 + (*Sub).curlen = len; + + return OK; +} + +/* + * 查找 + * + * 从pos处开始搜索模式串T在主串S中首次出现的位置,如果不存在,则返回0。 + * 如果查找成功,返回匹配的位置。 + * + *【注】 + * 1.此实现需要依赖串的最小操作子集 + * 2.该实现比较低效 + */ +int Index(LString S, LString T, int pos) { + int i, s, t; + LString sub; + + if(pos < 1 || pos > S.curlen || StrEmpty(T)) { + return 0; + } + + s = S.curlen; //主串S长度 + t = T.curlen; //模式串T长度 + i = pos; + + while(i + t - 1 <= s) { + // 获取S[i, i+m-1] + SubString(&sub, S, i, t); + + // 如果子串与模式串不匹配,则需要继续推进 + if(StrCompare(sub, T) != 0) { + ++i; + } else { + return i; + } + } + + return 0; //找不到匹配的则返回0 +} + +/* + * 插入 + * + * 将串T插入到主串S的pos位置处。 + */ +Status StrInsert(LString* S, int pos, LString T) { + Chunk* pre, * p; // pre指向目标块的前驱,p指向目标块 + Chunk* h, * t; // 指向新增的块链的头部和尾部 + Chunk* r; + Chunk* s; + int i, j, count; + + if(pos < 1 || pos > (*S).curlen + 1) { + return ERROR; + } + + // 如果待插入的串为空,则提前返回 + if(StrEmpty(T)) { + return OK; + } + + // 记录待插入块的起始块和终止块 + h = t = NULL; + + // 复制T中的块(只复制结构) + for(r = T.head; r != NULL; r = r->next) { + s = (Chunk*) malloc(sizeof(Chunk)); + if(s == NULL) { + exit(OVERFLOW); + } + s->next = NULL; + + if(r == T.head) { + h = t = s; + } else { + t->next = s; + t = s; + } + } + + // 查找S中第pos个元素所在的块(注:称为目标块),并用指针pre指向它的前驱 + if(pos >= 1 && pos <= CHUNKSIZE) { + pre = NULL; // 说明第pos个元素所在块为head + p = (*S).head; + } else { + for(count = 1, pre = (*S).head; count < (pos - 1) / CHUNKSIZE; count++, pre = pre->next) { + // 空循环 + } + p = pre->next; + } + + /* + * 接下来,将h到t范围的块插入到pos所在的块之前 + */ + + if(pre == NULL) { + t->next = (*S).head; + (*S).head = h; + } else { + pre->next = h; + t->next = p; + } + + if(pre == (*S).tail) { + (*S).tail = t; + } + + /* + * 移动/复制元素 + */ + + j = 0; + + // 如果插入到了某个块的“中间” + if((pos - 1) % CHUNKSIZE != 0) { + // 移动目标块中pos位置之前的元素 + for(i = 1; i <= (pos - 1) % CHUNKSIZE; i++) { + h->ch[j++] = p->ch[i - 1]; + p->ch[i - 1] = '\0'; + } + } + + r = T.head; + i = 0; + + // 复制T中的元素到S中 + for(count = 1; count <= T.curlen; count++) { + h->ch[j] = r->ch[i]; + + j = (j + 1) % CHUNKSIZE; + i = (i + 1) % CHUNKSIZE; + + if(j == 0) { + h = h->next; + } + + if(i == 0) { + r = r->next; + } + } + + // 如果T中最后一个块中包含'\0' + if(T.curlen % CHUNKSIZE != 0) { + r = p; // 指向目标块 + i = (pos - 1) % CHUNKSIZE; + + // 移动目标块中pos位置及其之后的元素 + for(count = pos; count <= (*S).curlen; count++) { + h->ch[j] = r->ch[i]; + r->ch[i] = '\0'; + + j = (j + 1) % CHUNKSIZE; + i = (i + 1) % CHUNKSIZE; + + if(j == 0) { + h = h->next; + } + + if(i == 0) { + r = r->next; + } + } + } + + (*S).curlen += T.curlen; + + return OK; +} + +/* + * 删除 + * + * 删除S[pos, pos+len-1]。 + */ +Status StrDelete(LString* S, int pos, int len) { + Chunk* pre; // 指向元素S[pos]所在的块的前驱 + Chunk* p; // 指向元素S[pos]所在的块 + Chunk* q; // 指向元素S[pos+len]所在的块 + Chunk* r; + int i, j, count, total; + + if(pos < 1 || pos > (*S).curlen || len < 0 || pos + len - 1 > (*S).curlen) { + return ERROR; + } + + // 如果待删除的长度为0,则提前返回 + if(len == 0) { + return OK; + } + + // 查找S[pos]所在的块,并用指针pre指向它的前驱 + if(pos >= 1 && pos <= CHUNKSIZE) { + pre = NULL; // 说明第pos个元素所在块为head + p = (*S).head; + } else { + for(count = 1, pre = (*S).head; count < (pos - 1) / CHUNKSIZE; count++, pre = pre->next) { + // 空循环 + } + p = pre->next; + } + + // 查找S[pos+len]所在的块 + for(count = (pos - 1) / CHUNKSIZE, q = p; count < (pos + len - 1) / CHUNKSIZE; count++, q = q->next) { + // 空循环 + } + + // 计算可能需要移动的元素个数 + total = (*S).curlen - (pos + len) + 1; + + // 把最终的长度先定下来 + (*S).curlen -= len; + + i = (pos - 1) % CHUNKSIZE; + j = (pos + len - 1) % CHUNKSIZE; + + if(p != q) { + // 删除p与q之间的块 + r = p->next; + while(r != q) { + p->next = r->next; + free(r); + r = p->next; + } + + if(q == NULL) { + (*S).tail = p; + } + + // 如果需要删除p指向的整个块 + if((pos - 1) % CHUNKSIZE == 0) { + // p已经指向块链的头部 + if(pre == NULL) { + (*S).head = q; + } else { + pre->next = q; + } + + free(p); + p = q; + + if(q == NULL) { + (*S).tail = pre; + } + } + } + + // 已经就位 + if(p == q && i == j) { + return OK; + } + + for(count = 1; count <= total; count++) { + // 移动元素 + p->ch[i] = q->ch[j]; + + i = (i + 1) % CHUNKSIZE; + j = (j + 1) % CHUNKSIZE; + + if(i == 0) { + pre = p; + p = p->next; + } + + if(j == 0) { + q = q->next; + } + } + + // 恰好填满了最后的块 + if(i == 0) { + (*S).tail = pre; + r = p; + } else { + (*S).tail = p; + + // 剩余部分填充非串值字符 + while(i < CHUNKSIZE) { + p->ch[i++] = '\0'; + } + + r = p->next; + } + + // 释放多余的空间 + while(r != NULL) { + (*S).tail->next = r->next; + free(r); + r = (*S).tail->next; + } + + return OK; +} + +/* + * 比较 + * + * 比较串S和串T,返回比较结果。 + * + *【注】 + * 该操作属于最小操作子集 + */ +int StrCompare(LString S, LString T) { + int i; + Chunk* s = S.head; + Chunk* t = T.head; + + while(s != NULL && t != NULL) { + for(i = 0; i < CHUNKSIZE; i++) { + if(s->ch[i] != t->ch[i]) { + return s->ch[i] - t->ch[i]; + } + } + + s = s->next; + t = t->next; + } + + if(s != NULL) { + return 1; + } else if(t != NULL) { + return -1; + } else { + return 0; + } +} + +/* + * 复制 + * + * 将串S复制到串T。 + */ +Status StrCopy(LString* T, LString S) { + int i; + Chunk* s, * p; + + for(p = S.head; p; p = p->next) { + s = (Chunk*) malloc(sizeof(Chunk)); + if(s == NULL) { + exit(OVERFLOW); + } + s->next = NULL; + + if(p == S.head) { + (*T).head = (*T).tail = s; + } else { + (*T).tail->next = s; + (*T).tail = s; + } + + for(i = 0; i < CHUNKSIZE; i++) { + (*s).ch[i] = (*p).ch[i]; + } + } + + (*T).curlen = S.curlen; + + return OK; +} + +/* + * 替换 + * + * 用V替换主串S中出现的所有与T相等的且不重叠的子串。 + * + *【注】 + * 1.该操作依赖最小操作子集 + * 2.该实现比较低效 + */ +Status Replace(LString* S, LString T, LString V) { + int i; + + if(StrEmpty(*S) || StrEmpty(T)) { + return ERROR; + } + + // 在主串S中寻找模式串T第一次出现的位置 + i = Index(*S, T, 1); + + // 如果存在匹配的字符串 + while(i != 0) { + StrDelete(S, i, StrLength(T)); // 从S中删除T + StrInsert(S, i, V); // 向S中插入V + + i += StrLength(V); // i切换到下一个位置 + + i = Index(*S, T, i); // 查找下一个匹配的字符串 + } + + return OK; +} + +/* + * 串联接 + * + * 联接S1和S2,并存储到T中返回。如果联接后的长度溢出,则只保留未溢出的部分。 + * 返回值表示联接后的串是否完整。 + * + *【注】 + * 该操作属于最小操作子集 + */ +Status Concat(LString* T, LString S1, LString S2) { + Chunk* p; // 用来遍历S1和S2 + Chunk* r; // 遍历T + Chunk* s; + int i, j, count; + + // 计算长度信息 + (*T).curlen = S1.curlen + S2.curlen; + + // 计算需要创建多少个块 + count = (*T).curlen / CHUNKSIZE + ((*T).curlen % CHUNKSIZE == 0 ? 0 : 1); + + // 复制S1的结构 + for(i = 1; i <= count; i++) { + s = (Chunk*) malloc(sizeof(Chunk)); + if(s == NULL) { + exit(OVERFLOW); + } + s->next = NULL; + + if(i == 1) { + (*T).head = (*T).tail = s; + } else { + (*T).tail->next = s; + (*T).tail = s; + } + } + + i = 0; + r = (*T).head; + + // 复制S1中的数据 + j = 0; + p = S1.head; + for(count = 0; count < S1.curlen; count++) { + r->ch[i] = p->ch[j]; + + i = (i + 1) % CHUNKSIZE; + j = (j + 1) % CHUNKSIZE; + + if(i == 0) { + r = r->next; + } + + if(j == 0) { + p = p->next; + } + } + + // 复制S2中的数据 + j = 0; + p = S2.head; + for(count = 0; count < S2.curlen; count++) { + r->ch[i] = p->ch[j]; + + i = (i + 1) % CHUNKSIZE; + j = (j + 1) % CHUNKSIZE; + + if(i == 0) { + r = r->next; + } + + if(j == 0) { + p = p->next; + } + } + + // 多余的空间填充非串值字符 + if(i != 0) { + while(i < CHUNKSIZE) { + r->ch[i] = '\0'; + i++; + } + } + + return OK; +} + +// 测试函数,打印字符串 +void StrPrint(LString S) { + int i = 0; + Chunk* p = S.head; + + if(S.curlen == 0 || S.head == NULL || S.tail == NULL) { + return; + } + + while(p != NULL) { + // 遇到非串值符号时结束遍历 + if(p->ch[i] == '\0') { + break; + } + + printf("%c", p->ch[i]); + + i = (i + 1) % CHUNKSIZE; + + if(i == 0) { + p = p->next; + } + } + + printf("\n"); +} diff --git a/CLion/ExerciseBook/04.22/LString.h b/CLion/ExerciseBook/04.22/LString.h new file mode 100644 index 0000000..54359bb --- /dev/null +++ b/CLion/ExerciseBook/04.22/LString.h @@ -0,0 +1,169 @@ +/*============================= + * 串的块链分配存储表示(块链串) + ==============================*/ + +#ifndef LSTRING_H +#define LSTRING_H + +#include +#include // 提供malloc、realloc、free、exit原型 +#include // 提供strlen原型 +#include "Status.h" //**▲01 绪论**// + +/* 宏定义 */ +#define CHUNKSIZE 3 // 块大小(自定义) + +/* 串的块链存储结构 */ +typedef struct Chunk { + char ch[CHUNKSIZE]; // 当前块中的内容 + struct Chunk* next; // 指向下一个块 +} Chunk; + +/* 串的块链存储类型定义 */ +typedef struct { + Chunk* head; //串的头指针 + Chunk* tail; //串的尾指针 + int curlen; //串的当前长度 +} LString; + + +/* + * ████ 提示 ████ + * + * 遵循教材的书写习惯,pos指示字符的位序(不是索引),从1开始计数 + */ + +/* + * ████ 注意 ████ + * + * 1.教材示例中使用#作为非串值字符,而这里使用C语言中的\0作为非串值字符 + * 2.教材中指出,块链的最后一个块中,末尾可能是用非串值字符填充的。 + * 例如块大小为4,长度为14的块可能为:ABCD -> EFGH -> IJKL -> MN\0\0 + */ + + +/* + * 初始化 + * + * 构造一个值为chars的串T。 + * + *【注】 + * 该操作属于最小操作子集 + */ +Status StrAssign(LString* T, const char* chars); + +/* + * 销毁 + * + * 将串S销毁。 + */ +Status DestroyString(LString* S); + +/* + * 清空 + * + * 将串S清空。 + */ +Status ClearString(LString* S); + +/* + * 判空 + * + * 判断串S中是否包含有效数据。 + * + * 返回值: + * TRUE : 串S为空 + * FALSE: 串S不为空 + */ +Status StrEmpty(LString S); + +/* + * 计数 + * + * 返回串S中元素的个数。 + * + *【注】 + * 该操作属于最小操作子集 + */ +int StrLength(LString S); + +/* + * 求子串 + * + * 用Sub返回S[pos, pos+len-1]。 + * 返回值指示是否截取成功。 + * + *【注】 + * 该操作属于最小操作子集 + */ +Status SubString(LString* Sub, LString S, int pos, int len); + +/* + * 查找 + * + * 从pos处开始搜索模式串T在主串S中首次出现的位置,如果不存在,则返回0。 + * 如果查找成功,返回匹配的位置。 + * + *【注】 + * 1.此实现需要依赖串的最小操作子集 + * 2.该实现比较低效 + */ +int Index(LString S, LString T, int pos); + +/* + * 插入 + * + * 将串T插入到主串S的pos位置处。 + */ +Status StrInsert(LString* S, int pos, LString T); + +/* + * 删除 + * + * 删除S[pos, pos+len-1]。 + */ +Status StrDelete(LString* S, int pos, int len); + +/* + * 比较 + * + * 比较串S和串T,返回比较结果。 + * + *【注】 + * 该操作属于最小操作子集 + */ +Status StrCompare(LString S, LString T); + +/* + * 复制 + * + * 将串S复制到串T。 + */ +Status StrCopy(LString* T, LString S); + +/* + * 替换 + * + * 用V替换主串S中出现的所有与T相等的且不重叠的子串。 + * + *【注】 + * 1.该操作依赖最小操作子集 + * 2.该实现比较低效 + */ +Status Replace(LString* S, LString T, LString V); + +/* + * 串联接 + * + * 联接S1和S2,并存储到T中返回。如果联接后的长度溢出,则只保留未溢出的部分。 + * 返回值表示联接后的串是否完整。 + * + *【注】 + * 该操作属于最小操作子集 + */ +Status Concat(LString* T, LString S1, LString S2); + +// 测试函数,打印字符串 +void StrPrint(LString S); + +#endif diff --git a/CLion/ExerciseBook/04.23/04.23.c b/CLion/ExerciseBook/04.23/04.23.c new file mode 100644 index 0000000..20d78c4 --- /dev/null +++ b/CLion/ExerciseBook/04.23/04.23.c @@ -0,0 +1,107 @@ +#include +#include "LString.h" //**▲04 串**// + +/* + * 判断给定的串是否对称。 + * 空串或单字符的串会被认为是对称的。 + */ +Status Algo_4_23(LString T); + + +int main(int argc, char* argv[]) { + char* t = "abcdefgfedcba"; + LString T; + + StrAssign(&T, t); + printf("T = "); + StrPrint(T); + + Algo_4_23(T) ? printf("T是对称串!\n") : printf("T是非对称串!!\n"); + + return 0; +} + + +/* + * 判断给定的串是否对称。 + * 空串或单字符的串会被认为是对称的。 + */ +Status Algo_4_23(LString T) { + int len; // T的长度 + + int a1, b1; // T的前半部分边界 + int a2, b2; // T的后半部分边界 + int k; // 限制遍历T时需要经过的元素数量 + int i; // 遍历T时的游标 + Chunk* t; + + char* stack; // 模拟栈 + int top; // 栈游标 + + char c; // 从T中取出的字符 + + len = StrLength(T); + + // 空串被认为是对称的 + if(len == 0) { + return OK; + } + + // 如果串的长度是偶数 + if(len % 2 == 0) { + a1 = 0; + b1 = len / 2 - 1; + a2 = len / 2; + b2 = len - 1; + // 如果串的长度是奇数 + } else { + a1 = 0; + b1 = len / 2 - 1; + a2 = len / 2 + 1; + b2 = len - 1; + } + + stack = (char*) malloc(len * sizeof(char)); + top = -1; + + i = 0; + t = T.head; + + // 对于串的前半部分,将其入栈 + for(k = a1; k <= b1; k++) { + c = t->ch[i]; + i = (i + 1) % CHUNKSIZE; + if(i == 0) { + t = t->next; + } + + stack[++top] = c; + } + + // 如果串长为奇数,需要跨过一个字符 + if(len % 2 == 1) { + i = (i + 1) % CHUNKSIZE; + if(i == 0) { + t = t->next; + } + } + + for(k = a2; k <= b2; k++) { + c = t->ch[i]; + i = (i + 1) % CHUNKSIZE; + if(i == 0) { + t = t->next; + } + + // 遇到了不对称的字符 + if(stack[top--] != c) { + return ERROR; + } + } + + if(top == -1) { + return OK; + } else { + return ERROR; + } +} diff --git a/CLion/ExerciseBook/04.23/CMakeLists.txt b/CLion/ExerciseBook/04.23/CMakeLists.txt new file mode 100644 index 0000000..577b55d --- /dev/null +++ b/CLion/ExerciseBook/04.23/CMakeLists.txt @@ -0,0 +1,7 @@ +# 包含公共库 +include_directories(${CMAKE_SOURCE_DIR}/Status) + +# 生成可执行文件 +add_executable(04.23 LString.h LString.c 04.23.c) +# 链接公共库 +target_link_libraries(04.23 Scanf_lib) \ No newline at end of file diff --git a/CLion/ExerciseBook/04.23/LString.c b/CLion/ExerciseBook/04.23/LString.c new file mode 100644 index 0000000..77783f4 --- /dev/null +++ b/CLion/ExerciseBook/04.23/LString.c @@ -0,0 +1,748 @@ +/*============================= + * 串的块链分配存储表示(块链串) + ==============================*/ + +#include "LString.h" //**▲04 串**// + +/* + * 初始化 + * + * 构造一个值为chars的串T。 + * + *【注】 + * 该操作属于最小操作子集 + */ +Status StrAssign(LString* T, const char* chars) { + int len; // chars的长度 + int i, count; // 遍历块链串和字符串chars的游标 + int m; // 总块数 + int n; // 如果存在未填满的块,存储该块中的有效元素数量 + Chunk* r; + + // 求chars的长度 + len = (int) strlen(chars); + + // 没有有效元素 + if(len == 0) { + (*T).head = NULL; + (*T).tail = NULL; + (*T).curlen = 0; + + return OK; + } + + m = len / CHUNKSIZE; // 先计算需要填满的块 + n = len % CHUNKSIZE; // 如果存在未填满的块,计算该块中填充的有效元素数量 + if(n != 0) { + m++; // 计算总块数 + } + + // 1.创建块链串的结构 + for(i = 1; i <= m; i++) { + // 创建新块 + r = (Chunk*) malloc(sizeof(Chunk)); + if(r == NULL) { + exit(OVERFLOW); + } + r->next = NULL; + + // 第一个块 + if(i == 1) { + (*T).head = (*T).tail = r; + + // 联接后面的块 + } else { + (*T).tail->next = r; + (*T).tail = r; + } + } + + r = (*T).head; + i = 0; // 块链串T的游标 + count = 0; // 统计遍历过的元素,顺便作为chars的游标 + + // 2.为块链串填充内容 + while(count < len) { + r->ch[i] = chars[count]; + + i = (i + 1) % CHUNKSIZE; + if(i == 0) { + r = r->next; // 指向下一个块 + } + + count++; + } + + // 3.如果存在未填满的块 + if(n != 0) { + // 填充非串值内容(补上'\0') + while(i < CHUNKSIZE) { + (*T).tail->ch[i] = '\0'; + i++; + } + } + + // 4.记录长度信息 + (*T).curlen = len; + + return OK; +} + +/* + * 销毁 + * + *【注】 + * 块链串的结构可以销毁,但不是在销毁操作中 + */ +Status DestroyString(LString* S) { + return OK; +} + +/* + * 清空 + * + * 将串S清空。 + */ +Status ClearString(LString* S) { + Chunk* p, * q; + + p = (*S).head; + + // 释放所有串占用的空间 + while(p != NULL) { + q = p->next; + free(p); + p = q; + } + + (*S).head = NULL; + (*S).tail = NULL; + (*S).curlen = 0; + + return OK; +} + +/* + * 判空 + * + * 判断串S中是否包含有效数据。 + * + * 返回值: + * TRUE : 串S为空 + * FALSE: 串S不为空 + */ +Status StrEmpty(LString S) { + return S.curlen == 0 ? TRUE : FALSE; +} + +/* + * 计数 + * + * 返回串S中元素的个数。 + * + *【注】 + * 该操作属于最小操作子集 + */ +int StrLength(LString S) { + return S.curlen; +} + +/* + * 求子串 + * + * 用Sub返回S[pos, pos+len-1]。 + * 返回值指示是否截取成功。 + * + *【注】 + * 该操作属于最小操作子集 + */ +Status SubString(LString* Sub, LString S, int pos, int len) { + int m; // Sub的总块数 + int n; // 如果Sub存在未填满的块,存储该块中的有效元素数量 + int i, j, count; + Chunk* r, * p; + + if(pos < 1 || pos > S.curlen || len < 0 || pos + len - 1 > S.curlen) { + return ERROR; + } + + // 如果是截取0个字符,不需要分配空间 + if(len == 0) { + (*Sub).head = NULL; + (*Sub).tail = NULL; + (*Sub).curlen = 0; + + return OK; + } + + m = len / CHUNKSIZE; // 先计算需要填满的块 + n = len % CHUNKSIZE; // 如果Sub存在未填满的块,计算该块中填充的有效元素数量 + if(n != 0) { + m++; // 计算Sub的总块数 + } + + // 1.创建Sub的结构 + for(i = 1; i <= m; i++) { + // 创建新块 + r = (Chunk*) malloc(sizeof(Chunk)); + if(r == NULL) { + exit(OVERFLOW); + } + r->next = NULL; + + // 第一个块 + if(i == 1) { + (*Sub).head = (*Sub).tail = r; + + // 联接后面的块 + } else { + (*Sub).tail->next = r; + (*Sub).tail = r; + } + } + + // 查找S中第pos个元素所在的块,并用指针p指向它 + for(count = 1, p = S.head; pos > count * CHUNKSIZE; count++, p = p->next) { + // 空循环 + } + + r = (*Sub).head; // 指向Sub的块 + + i = 0; // 块链串Sub的游标 + j = (pos - 1) % CHUNKSIZE; // 块链串S 的游标 + count = 0; // 统计遍历过的元素 + + // 2.为块链串Sub填充内容 + while(count < len) { + r->ch[i] = p->ch[j]; + + i = (i + 1) % CHUNKSIZE; + if(i == 0) { + r = r->next; // 指向Sub中下一个块 + } + + j = (j + 1) % CHUNKSIZE; + if(j == 0) { + p = p->next; // 指向S中下一个块 + } + + count++; + } + + // 3.如果存在未填满的块 + if(n != 0) { + // 填充非串值内容(补上'\0') + while(i < CHUNKSIZE) { + (*Sub).tail->ch[i] = '\0'; + i++; + } + } + + // 4.记录长度信息 + (*Sub).curlen = len; + + return OK; +} + +/* + * 查找 + * + * 从pos处开始搜索模式串T在主串S中首次出现的位置,如果不存在,则返回0。 + * 如果查找成功,返回匹配的位置。 + * + *【注】 + * 1.此实现需要依赖串的最小操作子集 + * 2.该实现比较低效 + */ +int Index(LString S, LString T, int pos) { + int i, s, t; + LString sub; + + if(pos < 1 || pos > S.curlen || StrEmpty(T)) { + return 0; + } + + s = S.curlen; //主串S长度 + t = T.curlen; //模式串T长度 + i = pos; + + while(i + t - 1 <= s) { + // 获取S[i, i+m-1] + SubString(&sub, S, i, t); + + // 如果子串与模式串不匹配,则需要继续推进 + if(StrCompare(sub, T) != 0) { + ++i; + } else { + return i; + } + } + + return 0; //找不到匹配的则返回0 +} + +/* + * 插入 + * + * 将串T插入到主串S的pos位置处。 + */ +Status StrInsert(LString* S, int pos, LString T) { + Chunk* pre, * p; // pre指向目标块的前驱,p指向目标块 + Chunk* h, * t; // 指向新增的块链的头部和尾部 + Chunk* r; + Chunk* s; + int i, j, count; + + if(pos < 1 || pos > (*S).curlen + 1) { + return ERROR; + } + + // 如果待插入的串为空,则提前返回 + if(StrEmpty(T)) { + return OK; + } + + // 记录待插入块的起始块和终止块 + h = t = NULL; + + // 复制T中的块(只复制结构) + for(r = T.head; r != NULL; r = r->next) { + s = (Chunk*) malloc(sizeof(Chunk)); + if(s == NULL) { + exit(OVERFLOW); + } + s->next = NULL; + + if(r == T.head) { + h = t = s; + } else { + t->next = s; + t = s; + } + } + + // 查找S中第pos个元素所在的块(注:称为目标块),并用指针pre指向它的前驱 + if(pos >= 1 && pos <= CHUNKSIZE) { + pre = NULL; // 说明第pos个元素所在块为head + p = (*S).head; + } else { + for(count = 1, pre = (*S).head; count < (pos - 1) / CHUNKSIZE; count++, pre = pre->next) { + // 空循环 + } + p = pre->next; + } + + /* + * 接下来,将h到t范围的块插入到pos所在的块之前 + */ + + if(pre == NULL) { + t->next = (*S).head; + (*S).head = h; + } else { + pre->next = h; + t->next = p; + } + + if(pre == (*S).tail) { + (*S).tail = t; + } + + /* + * 移动/复制元素 + */ + + j = 0; + + // 如果插入到了某个块的“中间” + if((pos - 1) % CHUNKSIZE != 0) { + // 移动目标块中pos位置之前的元素 + for(i = 1; i <= (pos - 1) % CHUNKSIZE; i++) { + h->ch[j++] = p->ch[i - 1]; + p->ch[i - 1] = '\0'; + } + } + + r = T.head; + i = 0; + + // 复制T中的元素到S中 + for(count = 1; count <= T.curlen; count++) { + h->ch[j] = r->ch[i]; + + j = (j + 1) % CHUNKSIZE; + i = (i + 1) % CHUNKSIZE; + + if(j == 0) { + h = h->next; + } + + if(i == 0) { + r = r->next; + } + } + + // 如果T中最后一个块中包含'\0' + if(T.curlen % CHUNKSIZE != 0) { + r = p; // 指向目标块 + i = (pos - 1) % CHUNKSIZE; + + // 移动目标块中pos位置及其之后的元素 + for(count = pos; count <= (*S).curlen; count++) { + h->ch[j] = r->ch[i]; + r->ch[i] = '\0'; + + j = (j + 1) % CHUNKSIZE; + i = (i + 1) % CHUNKSIZE; + + if(j == 0) { + h = h->next; + } + + if(i == 0) { + r = r->next; + } + } + } + + (*S).curlen += T.curlen; + + return OK; +} + +/* + * 删除 + * + * 删除S[pos, pos+len-1]。 + */ +Status StrDelete(LString* S, int pos, int len) { + Chunk* pre; // 指向元素S[pos]所在的块的前驱 + Chunk* p; // 指向元素S[pos]所在的块 + Chunk* q; // 指向元素S[pos+len]所在的块 + Chunk* r; + int i, j, count, total; + + if(pos < 1 || pos > (*S).curlen || len < 0 || pos + len - 1 > (*S).curlen) { + return ERROR; + } + + // 如果待删除的长度为0,则提前返回 + if(len == 0) { + return OK; + } + + // 查找S[pos]所在的块,并用指针pre指向它的前驱 + if(pos >= 1 && pos <= CHUNKSIZE) { + pre = NULL; // 说明第pos个元素所在块为head + p = (*S).head; + } else { + for(count = 1, pre = (*S).head; count < (pos - 1) / CHUNKSIZE; count++, pre = pre->next) { + // 空循环 + } + p = pre->next; + } + + // 查找S[pos+len]所在的块 + for(count = (pos - 1) / CHUNKSIZE, q = p; count < (pos + len - 1) / CHUNKSIZE; count++, q = q->next) { + // 空循环 + } + + // 计算可能需要移动的元素个数 + total = (*S).curlen - (pos + len) + 1; + + // 把最终的长度先定下来 + (*S).curlen -= len; + + i = (pos - 1) % CHUNKSIZE; + j = (pos + len - 1) % CHUNKSIZE; + + if(p != q) { + // 删除p与q之间的块 + r = p->next; + while(r != q) { + p->next = r->next; + free(r); + r = p->next; + } + + if(q == NULL) { + (*S).tail = p; + } + + // 如果需要删除p指向的整个块 + if((pos - 1) % CHUNKSIZE == 0) { + // p已经指向块链的头部 + if(pre == NULL) { + (*S).head = q; + } else { + pre->next = q; + } + + free(p); + p = q; + + if(q == NULL) { + (*S).tail = pre; + } + } + } + + // 已经就位 + if(p == q && i == j) { + return OK; + } + + for(count = 1; count <= total; count++) { + // 移动元素 + p->ch[i] = q->ch[j]; + + i = (i + 1) % CHUNKSIZE; + j = (j + 1) % CHUNKSIZE; + + if(i == 0) { + pre = p; + p = p->next; + } + + if(j == 0) { + q = q->next; + } + } + + // 恰好填满了最后的块 + if(i == 0) { + (*S).tail = pre; + r = p; + } else { + (*S).tail = p; + + // 剩余部分填充非串值字符 + while(i < CHUNKSIZE) { + p->ch[i++] = '\0'; + } + + r = p->next; + } + + // 释放多余的空间 + while(r != NULL) { + (*S).tail->next = r->next; + free(r); + r = (*S).tail->next; + } + + return OK; +} + +/* + * 比较 + * + * 比较串S和串T,返回比较结果。 + * + *【注】 + * 该操作属于最小操作子集 + */ +int StrCompare(LString S, LString T) { + int i; + Chunk* s = S.head; + Chunk* t = T.head; + + while(s != NULL && t != NULL) { + for(i = 0; i < CHUNKSIZE; i++) { + if(s->ch[i] != t->ch[i]) { + return s->ch[i] - t->ch[i]; + } + } + + s = s->next; + t = t->next; + } + + if(s != NULL) { + return 1; + } else if(t != NULL) { + return -1; + } else { + return 0; + } +} + +/* + * 复制 + * + * 将串S复制到串T。 + */ +Status StrCopy(LString* T, LString S) { + int i; + Chunk* s, * p; + + for(p = S.head; p; p = p->next) { + s = (Chunk*) malloc(sizeof(Chunk)); + if(s == NULL) { + exit(OVERFLOW); + } + s->next = NULL; + + if(p == S.head) { + (*T).head = (*T).tail = s; + } else { + (*T).tail->next = s; + (*T).tail = s; + } + + for(i = 0; i < CHUNKSIZE; i++) { + (*s).ch[i] = (*p).ch[i]; + } + } + + (*T).curlen = S.curlen; + + return OK; +} + +/* + * 替换 + * + * 用V替换主串S中出现的所有与T相等的且不重叠的子串。 + * + *【注】 + * 1.该操作依赖最小操作子集 + * 2.该实现比较低效 + */ +Status Replace(LString* S, LString T, LString V) { + int i; + + if(StrEmpty(*S) || StrEmpty(T)) { + return ERROR; + } + + // 在主串S中寻找模式串T第一次出现的位置 + i = Index(*S, T, 1); + + // 如果存在匹配的字符串 + while(i != 0) { + StrDelete(S, i, StrLength(T)); // 从S中删除T + StrInsert(S, i, V); // 向S中插入V + + i += StrLength(V); // i切换到下一个位置 + + i = Index(*S, T, i); // 查找下一个匹配的字符串 + } + + return OK; +} + +/* + * 串联接 + * + * 联接S1和S2,并存储到T中返回。如果联接后的长度溢出,则只保留未溢出的部分。 + * 返回值表示联接后的串是否完整。 + * + *【注】 + * 该操作属于最小操作子集 + */ +Status Concat(LString* T, LString S1, LString S2) { + Chunk* p; // 用来遍历S1和S2 + Chunk* r; // 遍历T + Chunk* s; + int i, j, count; + + // 计算长度信息 + (*T).curlen = S1.curlen + S2.curlen; + + // 计算需要创建多少个块 + count = (*T).curlen / CHUNKSIZE + ((*T).curlen % CHUNKSIZE == 0 ? 0 : 1); + + // 复制S1的结构 + for(i = 1; i <= count; i++) { + s = (Chunk*) malloc(sizeof(Chunk)); + if(s == NULL) { + exit(OVERFLOW); + } + s->next = NULL; + + if(i == 1) { + (*T).head = (*T).tail = s; + } else { + (*T).tail->next = s; + (*T).tail = s; + } + } + + i = 0; + r = (*T).head; + + // 复制S1中的数据 + j = 0; + p = S1.head; + for(count = 0; count < S1.curlen; count++) { + r->ch[i] = p->ch[j]; + + i = (i + 1) % CHUNKSIZE; + j = (j + 1) % CHUNKSIZE; + + if(i == 0) { + r = r->next; + } + + if(j == 0) { + p = p->next; + } + } + + // 复制S2中的数据 + j = 0; + p = S2.head; + for(count = 0; count < S2.curlen; count++) { + r->ch[i] = p->ch[j]; + + i = (i + 1) % CHUNKSIZE; + j = (j + 1) % CHUNKSIZE; + + if(i == 0) { + r = r->next; + } + + if(j == 0) { + p = p->next; + } + } + + // 多余的空间填充非串值字符 + if(i != 0) { + while(i < CHUNKSIZE) { + r->ch[i] = '\0'; + i++; + } + } + + return OK; +} + +// 测试函数,打印字符串 +void StrPrint(LString S) { + int i = 0; + Chunk* p = S.head; + + if(S.curlen == 0 || S.head == NULL || S.tail == NULL) { + printf("\n"); + return; + } + + while(p != NULL) { + // 遇到非串值符号时结束遍历 + if(p->ch[i] == '\0') { + break; + } + + printf("%c", p->ch[i]); + + i = (i + 1) % CHUNKSIZE; + + if(i == 0) { + p = p->next; + } + } + + printf("\n"); +} diff --git a/CLion/ExerciseBook/04.23/LString.h b/CLion/ExerciseBook/04.23/LString.h new file mode 100644 index 0000000..54359bb --- /dev/null +++ b/CLion/ExerciseBook/04.23/LString.h @@ -0,0 +1,169 @@ +/*============================= + * 串的块链分配存储表示(块链串) + ==============================*/ + +#ifndef LSTRING_H +#define LSTRING_H + +#include +#include // 提供malloc、realloc、free、exit原型 +#include // 提供strlen原型 +#include "Status.h" //**▲01 绪论**// + +/* 宏定义 */ +#define CHUNKSIZE 3 // 块大小(自定义) + +/* 串的块链存储结构 */ +typedef struct Chunk { + char ch[CHUNKSIZE]; // 当前块中的内容 + struct Chunk* next; // 指向下一个块 +} Chunk; + +/* 串的块链存储类型定义 */ +typedef struct { + Chunk* head; //串的头指针 + Chunk* tail; //串的尾指针 + int curlen; //串的当前长度 +} LString; + + +/* + * ████ 提示 ████ + * + * 遵循教材的书写习惯,pos指示字符的位序(不是索引),从1开始计数 + */ + +/* + * ████ 注意 ████ + * + * 1.教材示例中使用#作为非串值字符,而这里使用C语言中的\0作为非串值字符 + * 2.教材中指出,块链的最后一个块中,末尾可能是用非串值字符填充的。 + * 例如块大小为4,长度为14的块可能为:ABCD -> EFGH -> IJKL -> MN\0\0 + */ + + +/* + * 初始化 + * + * 构造一个值为chars的串T。 + * + *【注】 + * 该操作属于最小操作子集 + */ +Status StrAssign(LString* T, const char* chars); + +/* + * 销毁 + * + * 将串S销毁。 + */ +Status DestroyString(LString* S); + +/* + * 清空 + * + * 将串S清空。 + */ +Status ClearString(LString* S); + +/* + * 判空 + * + * 判断串S中是否包含有效数据。 + * + * 返回值: + * TRUE : 串S为空 + * FALSE: 串S不为空 + */ +Status StrEmpty(LString S); + +/* + * 计数 + * + * 返回串S中元素的个数。 + * + *【注】 + * 该操作属于最小操作子集 + */ +int StrLength(LString S); + +/* + * 求子串 + * + * 用Sub返回S[pos, pos+len-1]。 + * 返回值指示是否截取成功。 + * + *【注】 + * 该操作属于最小操作子集 + */ +Status SubString(LString* Sub, LString S, int pos, int len); + +/* + * 查找 + * + * 从pos处开始搜索模式串T在主串S中首次出现的位置,如果不存在,则返回0。 + * 如果查找成功,返回匹配的位置。 + * + *【注】 + * 1.此实现需要依赖串的最小操作子集 + * 2.该实现比较低效 + */ +int Index(LString S, LString T, int pos); + +/* + * 插入 + * + * 将串T插入到主串S的pos位置处。 + */ +Status StrInsert(LString* S, int pos, LString T); + +/* + * 删除 + * + * 删除S[pos, pos+len-1]。 + */ +Status StrDelete(LString* S, int pos, int len); + +/* + * 比较 + * + * 比较串S和串T,返回比较结果。 + * + *【注】 + * 该操作属于最小操作子集 + */ +Status StrCompare(LString S, LString T); + +/* + * 复制 + * + * 将串S复制到串T。 + */ +Status StrCopy(LString* T, LString S); + +/* + * 替换 + * + * 用V替换主串S中出现的所有与T相等的且不重叠的子串。 + * + *【注】 + * 1.该操作依赖最小操作子集 + * 2.该实现比较低效 + */ +Status Replace(LString* S, LString T, LString V); + +/* + * 串联接 + * + * 联接S1和S2,并存储到T中返回。如果联接后的长度溢出,则只保留未溢出的部分。 + * 返回值表示联接后的串是否完整。 + * + *【注】 + * 该操作属于最小操作子集 + */ +Status Concat(LString* T, LString S1, LString S2); + +// 测试函数,打印字符串 +void StrPrint(LString S); + +#endif diff --git a/CLion/ExerciseBook/04.24-04.26/04.24-04.26.c b/CLion/ExerciseBook/04.24-04.26/04.24-04.26.c new file mode 100644 index 0000000..c7bb3d8 --- /dev/null +++ b/CLion/ExerciseBook/04.24-04.26/04.24-04.26.c @@ -0,0 +1,101 @@ +#include +#include "Status.h" //**▲01 绪论**// +#include "HString.h" //**▲04 串**// + +/* + * 联接:Concat + * + *【注】 + * 该函数已在HString相关文件中定义 + */ +Status Algo_4_24(HString* T, HString S1, HString S2); + +/* + * 替换:Replace + * + *【注】 + * 该函数已在HString相关文件中定义 + */ +Status Algo_4_25(HString* S, HString T, HString V); + +/* + * 插入:StrInsert + * + *【注】 + * 该函数已在HString相关文件中定义 + */ +Status Algo_4_26(HString* S, int pos, HString T); + + +int main(int argc, char* argv[]) { + char* s = "---*^***^*^*^*---"; + char* s1 = "*"; + char* s2 = "^*"; + char* v = "*_*"; + HString S1, S2, T, V, S; + + StrAssign(&S1, s1); + StrAssign(&S2, s2); + StrAssign(&V, v); + StrAssign(&S, s); + + printf("S1 = "); + StrPrint(S1); + printf("S2 = "); + StrPrint(S2); + printf("V = "); + StrPrint(V); + printf("S = "); + StrPrint(S); + + printf("███题 4.24 验证...███\n"); + printf("连接S1和S2为T...\n"); + Algo_4_24(&T, S1, S2); + printf("T = "); + StrPrint(T); + + printf("███题 4.25 验证...███\n"); + printf("用 V 替换 S 中的 T...\n"); + Algo_4_25(&S, T, V); + printf("S = "); + StrPrint(S); + + printf("███题 4.26 验证...███\n"); + printf("将 T 插入到 S 的第 2 个位置...\n"); + Algo_4_26(&S, 2, T); + printf("S = "); + StrPrint(S); + + return 0; +} + + +/* + * 联接:Concat + * + *【注】 + * 该函数已在HString相关文件中定义 + */ +Status Algo_4_24(HString* T, HString S1, HString S2) { + return Concat(T, S1, S2); +} + +/* + * 替换:Replace + * + *【注】 + * 该函数已在HString相关文件中定义 + */ +Status Algo_4_25(HString* S, HString T, HString V) { + return Replace(S, T, V); +} + +/* + * 插入:StrInsert + * + *【注】 + * 该函数已在HString相关文件中定义 + */ +Status Algo_4_26(HString* S, int pos, HString T) { + return StrInsert(S, pos, T); +} diff --git a/CLion/ExerciseBook/04.24-04.26/CMakeLists.txt b/CLion/ExerciseBook/04.24-04.26/CMakeLists.txt new file mode 100644 index 0000000..1024464 --- /dev/null +++ b/CLion/ExerciseBook/04.24-04.26/CMakeLists.txt @@ -0,0 +1,7 @@ +# 包含公共库 +include_directories(${CMAKE_SOURCE_DIR}/Status) + +# 生成可执行文件 +add_executable(04.24-04.26 HString.h HString.c 04.24-04.26.c) +# 链接公共库 +target_link_libraries(04.24-04.26 Scanf_lib) \ No newline at end of file diff --git a/CLion/ExerciseBook/04.24-04.26/HString.c b/CLion/ExerciseBook/04.24-04.26/HString.c new file mode 100644 index 0000000..ce68be5 --- /dev/null +++ b/CLion/ExerciseBook/04.24-04.26/HString.c @@ -0,0 +1,381 @@ +/*========================= + * 串的堆分配存储表示(堆串) + * + * 包含算法: 4.4 + ==========================*/ + +#include "HString.h" //**▲04 串**// + +/* + * 初始化 + * + * 构造一个值为chars的串T。 + * + *【注】 + * 该操作属于最小操作子集 + */ +Status StrAssign(HString* T, const char* chars) { + int i, j; + + // 求chars的长度 + i = (int) strlen(chars); + + // 没有有效元素 + if(i == 0) { + (*T).ch = NULL; + (*T).length = 0; + + return OK; + } + + // 存在有效元素时,需要分配存储空间 + (*T).ch = (char*) malloc(i * sizeof(char)); + if(!((*T).ch)) { + exit(OVERFLOW); + } + + for(j = 0; j < i; j++) { + (*T).ch[j] = chars[j]; + } + + (*T).length = i; + + return OK; +} + +/* + * 销毁 + * + * 将串S销毁。 + * + *【注】 + * 堆串的结构可以销毁,但不是在销毁操作中 + */ +Status DestroyString(HString* S) { + return OK; +} + +/* + * 清空 + * + * 将串S清空。 + */ +Status ClearString(HString* S) { + // 没有有效元素时,销毁堆串结构 + if((*S).ch != 0) { + free((*S).ch); + (*S).ch = NULL; + } + + (*S).length = 0; + + return OK; +} + +/* + * 判空 + * + * 判断串S中是否包含有效数据。 + * + * 返回值: + * TRUE : 串S为空 + * FALSE: 串S不为空 + */ +Status StrEmpty(HString S) { + return S.length == 0 ? TRUE : FALSE; +} + +/* + * 计数 + * + * 返回串S中元素的个数。 + * + *【注】 + * 该操作属于最小操作子集 + */ +int StrLength(HString S) { + return S.length; +} + +/* + * 求子串 + * + * 用Sub返回S[pos, pos+len-1]。 + * 返回值指示是否截取成功。 + * + *【注】 + * 该操作属于最小操作子集 + */ +Status SubString(HString* Sub, HString S, int pos, int len) { + int i; + + if(pos < 1 || pos > S.length || len < 0 || pos + len - 1 > S.length) { + return ERROR; + } + + // 如果是截取0个字符,不需要分配空间 + if(len == 0) { + (*Sub).ch = NULL; + (*Sub).length = 0; + + return OK; + } + + (*Sub).ch = (char*) malloc(len * sizeof(char)); + if(!(*Sub).ch) { + exit(OVERFLOW); + } + + // 复制元素 + for(i = 0; i < len; i++) { + (*Sub).ch[i] = S.ch[i + pos - 1]; + } + + // 确定新长度 + (*Sub).length = len; + + return OK; +} + +/* + * 查找 + * + * 从pos处开始搜索模式串T在主串S中首次出现的位置,如果不存在,则返回0。 + * 如果查找成功,返回匹配的位置。 + * + *【注】 + * 1.此实现需要依赖串的最小操作子集 + * 2.该实现比较低效 + */ +int Index(HString S, HString T, int pos) { + int i, s, t; + HString sub; + + if(pos < 1 || pos > S.length || StrEmpty(T)) { + return 0; + } + + s = S.length; + t = T.length; + i = pos; + + // 保证长度不越界 + while(i + t - 1 <= s) { + // 获取S[i, i+t-1] + SubString(&sub, S, i, t); + + // 如果子串与模式串不匹配,则需要继续推进 + if(StrCompare(sub, T) != 0) { + ++i; + } else { + return i; + } + } + + return 0; +} + +/* + * ████████ 算法4.4 ████████ + * + * 插入 + * + * 将串T插入到主串S的pos位置处。 + */ +Status StrInsert(HString* S, int pos, HString T) { + int i; + + if(pos < 1 || pos > (*S).length + 1) { + return ERROR; + } + + // 如果待插入的串为空,则提前返回 + if(StrEmpty(T)) { + return OK; + } + + // 分配新空间,会将旧元素一起复制过去 + (*S).ch = (char*) realloc((*S).ch, ((*S).length + T.length) * sizeof(char)); + if(!(*S).ch) { + exit(OVERFLOW); + } + + // 在S中腾出位置,为插入T做准备 + for(i = (*S).length - 1; i >= pos - 1; i--) { + // 从后向前遍历,将前面的元素挪到后面 + (*S).ch[i + T.length] = (*S).ch[i]; + } + + // 将串T插入在S中腾出的位置上 + for(i = pos - 1; i <= pos + T.length - 2; i++) { + (*S).ch[i] = T.ch[i - pos + 1]; + } + + // 长度增加 + (*S).length += T.length; + + return OK; +} + +/* + * 删除 + * + * 删除S[pos, pos+len-1]。 + */ +Status StrDelete(HString* S, int pos, int len) { + int i; + + if(pos < 1 || pos + len - 1 > (*S).length || len < 0) { + return ERROR; + } + + // 如果待删除的长度为0,则提前返回 + if(len == 0) { + return OK; + } + + // 把后面的元素挪到前面,覆盖掉被删除的元素 + for(i = pos + len - 1; i <= (*S).length - 1; i++) { + (*S).ch[i - len] = (*S).ch[i]; + } + + // 长度减少 + (*S).length -= len; + + // 缩减分配的空间(如果长度减少为0,这里会返回空指针) + (*S).ch = (char*) realloc((*S).ch, (*S).length * sizeof(char)); + + return OK; +} + +/* + * 比较 + * + * 比较串S和串T,返回比较结果。 + * + *【注】 + * 该操作属于最小操作子集 + */ +Status StrCompare(HString S, HString T) { + int i; + + for(i = 0; i < S.length && i < T.length; i++) { + // 遇到不同的字符时,比较其大小 + if(S.ch[i] != T.ch[i]) { + return S.ch[i] - T.ch[i]; + } + } + + return S.length - T.length; +} + +/* + * 复制 + * + * 将串S复制到串T。 + */ +Status StrCopy(HString* T, HString S) { + int i; + + if(StrEmpty(S)) { + (*T).ch = NULL; + (*T).length = 0; + } else { + // 分配空间 + (*T).ch = (char*) malloc(S.length * sizeof(char)); + if(!(*T).ch) { + exit(OVERFLOW); + } + + // 复制元素 + for(i = 0; i < S.length; i++) { + (*T).ch[i] = S.ch[i]; + } + + // 复制长度信息 + (*T).length = S.length; + } + + return OK; +} + +/* + * 替换 + * + * 用V替换主串S中出现的所有与T相等的且不重叠的子串。 + * + *【注】 + * 1.该操作依赖最小操作子集 + * 2.该实现比较低效 + */ +Status Replace(HString* S, HString T, HString V) { + int i; + + if(StrEmpty(*S) || StrEmpty(T)) { + return ERROR; + } + + // 在主串S中寻找模式串T第一次出现的位置 + i = Index(*S, T, 1); + + // 如果存在匹配的字符串 + while(i != 0) { + StrDelete(S, i, StrLength(T)); // 从S中删除T + StrInsert(S, i, V); // 向S中插入V + + i += StrLength(V); // i切换到下一个位置 + + i = Index(*S, T, i); // 查找下一个匹配的字符串 + } + + return OK; +} + +/* + * 串联接 + * + * 联接S1和S2,并存储到T中返回。如果联接后的长度溢出,则只保留未溢出的部分。 + * 返回值表示联接后的串是否完整。 + * 堆串的空间被认为是无限的,因此这里总是返回TRUE,指示串不会被裁剪。 + * + *【注】 + * 该操作属于最小操作子集 + */ +Status Concat(HString* T, HString S1, HString S2) { + int i; + + // 确定新长度 + (*T).length = S1.length + S2.length; + + // 分配空间 + (*T).ch = (char*) malloc((*T).length * sizeof(char)); + if(!(*T).ch) { + exit(OVERFLOW); + } + + // 先把S1的内容拷贝出来 + for(i = 0; i < S1.length; i++) { + (*T).ch[i] = S1.ch[i]; + } + + // 再拷贝S2的内容 + for(i = 0; i < S2.length; i++) { + (*T).ch[S1.length + i] = S2.ch[i]; + } + + return TRUE; +} + +// 输出:打印字符串 +void StrPrint(HString S) { + int i; + + if(S.length == 0) { + return; + } + + for(i = 0; i < S.length; i++) { + printf("%c", S.ch[i]); + } + printf("\n"); +} \ No newline at end of file diff --git a/CLion/ExerciseBook/04.24-04.26/HString.h b/CLion/ExerciseBook/04.24-04.26/HString.h new file mode 100644 index 0000000..98deed4 --- /dev/null +++ b/CLion/ExerciseBook/04.24-04.26/HString.h @@ -0,0 +1,159 @@ +/*========================= + * 串的堆分配存储表示(堆串) + * + * 包含算法: 4.4 + ==========================*/ + +#ifndef HSTRING +#define HSTRING + +#include +#include // 提供malloc、realloc、free、exit原型 +#include // 提供strlen原型 +#include "Status.h" //**▲01 绪论**// + +/* + * 串的堆存储表示 + * + * 注:有效元素从ch的0号单元开始存储 + */ +typedef struct { + char* ch; // 若是非空串,则按串长分配存储区,否则ch为NULL + int length; +} HString; + + +/* + * ████ 提示 ████ + * + * 遵循教材的书写习惯,pos指示字符的位序(不是索引),从1开始计数 + */ + + +/* + * 初始化 + * + * 构造一个值为chars的串T。 + * + *【注】 + * 该操作属于最小操作子集 + */ +Status StrAssign(HString* T, const char* chars); + +/* + * 销毁 + * + * 将串S销毁。 + */ +Status DestroyString(HString* S); + +/* + * 清空 + * + * 将串S清空。 + */ +Status ClearString(HString* S); + +/* + * 判空 + * + * 判断串S中是否包含有效数据。 + * + * 返回值: + * TRUE : 串S为空 + * FALSE: 串S不为空 + */ +Status StrEmpty(HString S); + +/* + * 计数 + * + * 返回串S中元素的个数。 + * + *【注】 + * 该操作属于最小操作子集 + */ +int StrLength(HString S); + +/* + * 求子串 + * + * 用Sub返回S[pos, pos+len-1]。 + * 返回值指示是否截取成功。 + * + *【注】 + * 该操作属于最小操作子集 + */ +Status SubString(HString* Sub, HString S, int pos, int len); + +/* + * 查找 + * + * 从pos处开始搜索模式串T在主串S中首次出现的位置,如果不存在,则返回0。 + * 如果查找成功,返回匹配的位置。 + * + *【注】 + * 1.此实现需要依赖串的最小操作子集 + * 2.该实现比较低效 + */ +int Index(HString S, HString T, int pos); + +/* + * ████████ 算法4.4 ████████ + * + * 插入 + * + * 将串T插入到主串S的pos位置处。 + */ +Status StrInsert(HString* S, int pos, HString T); + +/* + * 删除 + * + * 删除S[pos, pos+len-1]。 + */ +Status StrDelete(HString* S, int pos, int len); + +/* + * 比较 + * + * 比较串S和串T,返回比较结果。 + * + *【注】 + * 该操作属于最小操作子集 + */ +Status StrCompare(HString S, HString T); + +/* + * 复制 + * + * 将串S复制到串T。 + */ +Status StrCopy(HString* T, HString S); + +/* + * 替换 + * + * 用V替换主串S中出现的所有与T相等的且不重叠的子串。 + * + *【注】 + * 1.该操作依赖最小操作子集 + * 2.该实现比较低效 + */ +Status Replace(HString* S, HString T, HString V); + +/* + * 串联接 + * + * 联接S1和S2,并存储到T中返回。如果联接后的长度溢出,则只保留未溢出的部分。 + * 返回值表示联接后的串是否完整。 + * + *【注】 + * 该操作属于最小操作子集 + */ +Status Concat(HString* T, HString S1, HString S2); + +// 输出:打印字符串 +void StrPrint(HString S); + +#endif diff --git a/CLion/ExerciseBook/04.27/04.27.c b/CLion/ExerciseBook/04.27/04.27.c new file mode 100644 index 0000000..b054b80 --- /dev/null +++ b/CLion/ExerciseBook/04.27/04.27.c @@ -0,0 +1,81 @@ +#include +#include "SString.h" //**▲04 串**// + +/* 函数原型 */ +int Algo_4_27(SString S, SString T, int pos); + + +/* + * 查找:Index + * + * 从pos处开始搜索模式串T在主串S中首次出现的位置,如果不存在,则返回0。 + * 如果查找成功,返回匹配的位置。 + * + *【注】 + * 相比与传统的Index函数,其改进之处在于会先比较首个字符与末尾字符, + * 当它们都匹配时,才会继续比较剩下的字符 + */ +int main(int argc, char* argv[]) { + char* s = "aaaaaaaaaaaaaaab"; + char* t = "aaaab"; + SString S, T; + + StrAssign(S, s); + StrAssign(T, t); + printf("S = "); + StrPrint(S); + printf("T = "); + StrPrint(T); + + printf("T在S中首次出现的位置为:"); + printf("%d\n", Algo_4_27(S, T, 1)); + + return 0; +} + + +/* + * 查找:Index + * + * 从pos处开始搜索模式串T在主串S中首次出现的位置,如果不存在,则返回0。 + * 如果查找成功,返回匹配的位置。 + * + *【注】 + * 相比与传统的Index函数,其改进之处在于会先比较首个字符与末尾字符, + * 当它们都匹配时,才会继续比较剩下的字符 + */ +int Algo_4_27(SString S, SString T, int pos) { + int i, j; + + if(pos < 1 || pos > S[0] || T[0] == 0) { + return 0; + } + + i = pos; + j = 1; + + while(i <= S[0] - T[0] + 1) { + // 先尝试比较首个字符与末尾字符 + if(S[i] != T[j] || S[i + T[0] - 1] != T[T[0]]) { + i++; + continue; + } + + // 这里的j不需要等于T[0],因为T[0]这种情形已经验证了 + for(i++,j++; j MAXSTRLEN) { + return ERROR; + } + + T[0] = len; + for(i = 1; i <= len; i++) { + T[i] = chars[i - 1]; + } + + return OK; +} + +/* + * 销毁 + * + * 将串S销毁。 + * + *【注】 + * 顺序串的结构无法销毁 + */ +Status DestroyString(SString S) { + 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; +} + +/* + * ████████ 算法4.1 ████████ + * + * 查找 + * + * 从pos处开始搜索模式串T在主串S中首次出现的位置,如果不存在,则返回0。 + * 如果查找成功,返回匹配的位置。 + * + *【注】 + * 1.此实现需要依赖串的最小操作子集 + * 2.该实现比较低效 + */ +int Index_1(SString S, SString T, int pos) { + int i, n, m; // 记录S和T的长度 + SString sub; + + /* + * 失败情形提前处理 + * 这里与教材写法略微不同 + */ + if(pos < 1 || pos > S[0] || StrEmpty(T)) { + return 0; + } + + n = StrLength(S); + m = StrLength(T); + i = pos; + + // 保证长度不越界 + while(i <= n - m + 1) { + // 获取S[i, i+m-1] + SubString(sub, S, i, m); + + // 如果子串与模式串不匹配,则需要继续推进 + if(StrCompare(sub, T) != 0) { + ++i; + } else { + return i; + } + } + + return 0; +} + +/* + * ████████ 算法4.5 ████████ + * + * 查找 + * + * 从pos处开始搜索模式串T在主串S中首次出现的位置,如果不存在,则返回0。 + * 如果查找成功,返回匹配的位置。 + * + *【注】 + * 1.此实现不依赖串的最小操作子集 + * 2.该实现比较低效 + */ +int Index_2(SString S, SString T, int pos) { + int i = pos; + int j = 1; + + if(pos < 1 || pos > S[0] || StrEmpty(T)) { + return 0; + } + + while(i <= S[0] && j <= T[0]) { + // 遇到相同字符,则继续比较后继字符 + if(S[i] == T[j]) { + i++; + j++; + + // 遇到不同的字符,则游标需要回退,重新比较 + } else { + i = i - (j - 1) + 1; // j-1代表徒劳地前进了j-1个元素,在第j个元素上功亏一篑 + j = 1; // 游标j回到串T的第一个位置 + } + } + + // 增加了一个T[0]>0的判断 + if(j > T[0] && T[0] > 0) { // T不为空串 + return i - T[0]; // 匹配成功 + } else { + return 0; + } +} + +/* + * 插入 + * + * 将串T插入到主串S的pos位置处。 + */ +Status StrInsert(SString S, int pos, SString T) { + int i; + + if(pos < 1 || pos > S[0] + 1 || S[0] + T[0] > MAXSTRLEN) { + return ERROR; + } + + // 如果待插入的串为空,则提前返回 + if(StrEmpty(T)) { + return OK; + } + + // 在S中腾出位置,为插入T做准备 + for(i = S[0]; i >= pos; i--) { + // 从后向前遍历,将前面的元素挪到后面 + S[i + T[0]] = S[i]; + } + + // 将串T插入在S中腾出的位置上 + for(i = pos; i <= pos + T[0] - 1; i++) { + S[i] = T[i - pos + 1]; + } + + // 长度增加 + S[0] += T[0]; + + 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; +} + +/* + * 替换 + * + * 用V替换主串S中出现的所有与T相等的且不重叠的子串。 + * + *【注】 + * 1.该操作依赖最小操作子集 + * 2.该实现比较低效 + */ +Status Replace(SString S, SString T, SString V) { + int i; + + if(StrEmpty(S) || StrEmpty(T)) { + return ERROR; + } + + // 在主串S中寻找模式串T第一次出现的位置 + i = Index_2(S, T, 1); + + // 如果存在匹配的字符串,且可以被完全替换(替换后不溢出) + while(i != 0 && S[0] - T[0] + V[0] <= MAXSTRLEN) { + StrDelete(S, i, StrLength(T)); // 从S中删除T + StrInsert(S, i, V); // 向S中插入V + + i += StrLength(V); // i切换到下一个位置 + + i = Index_2(S, T, i); // 查找下一个匹配的字符串 + } + + if(i == 0) { // S中的T已全部被替换 + return OK; + } else { // S中尚有T,但是V已经插不进去了 + return ERROR; + } +} + +/* + * ████████ 算法4.2 ████████ + * + * 串联接 + * + * 联接S1和S2,并存储到T中返回。如果联接后的长度溢出,则只保留未溢出的部分。 + * 返回值表示联接后的串是否完整。 + * + *【注】 + * 该操作属于最小操作子集 + */ +Status Concat(SString T, SString S1, SString S2) { + int i; + int uncut; // 新串是否完整 + + // 完全不需要裁剪 + if(S1[0] + S2[0] <= MAXSTRLEN) { + // 复制S1到T中 + for(i = 1; i <= S1[0]; i++) { + T[i] = S1[i]; + } + + // 复制S2到T中 + for(i = S1[0] + 1; i <= S1[0] + S2[0]; i++) { + T[i] = S2[i - S1[0]]; + } + + // 设置新长度 + T[0] = S1[0] + S2[0]; + + // 未裁剪,完整 + uncut = TRUE; + + // 需要裁剪S2 + } else if(S1[0] <= MAXSTRLEN) { + // 复制S1到T中 + for(i = 1; i <= S1[0]; i++) { + T[i] = S1[i]; + } + + // 将S2的一部分复制到T中 + for(i = S1[0] + 1; i <= MAXSTRLEN; i++) { + T[i] = S2[i - S1[0]]; + } + + // 设置新长度 + T[0] = MAXSTRLEN; + + uncut = FALSE; + + // 只需要复制S1的一部分 + } else { + // 连同长度信息一起复制 + for(i = 0; i <= MAXSTRLEN; i++) { + T[i] = S1[i]; + } + + uncut = FALSE; + } + + return uncut; +} + +// 输出:打印字符串 +void StrPrint(SString S) { + int i; + + for(i = 1; i<=S[0] ; i++) { + printf("%c", S[i]); + } + + printf("\n"); +} diff --git a/CLion/ExerciseBook/04.27/SString.h b/CLion/ExerciseBook/04.27/SString.h new file mode 100644 index 0000000..d164913 --- /dev/null +++ b/CLion/ExerciseBook/04.27/SString.h @@ -0,0 +1,179 @@ +/*============================= + * 串的定长顺序存储表示(顺序串) + * + * 包含算法: 4.1、4.2、4.3、4.5 + ==============================*/ + +#ifndef SSTRING_H +#define SSTRING_H + +#include +#include // 提供strlen原型 +#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 DestroyString(SString S); + +/* + * 清空 + * + * 将串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); + +/* + * ████████ 算法4.1 ████████ + * + * 查找 + * + * 从pos处开始搜索模式串T在主串S中首次出现的位置,如果不存在,则返回0。 + * 如果查找成功,返回匹配的位置。 + * + *【注】 + * 1.此实现需要依赖串的最小操作子集 + * 2.该实现比较低效 + */ +int Index_1(SString S, SString T, int pos); + +/* + * ████████ 算法4.5 ████████ + * + * 查找 + * + * 从pos处开始搜索模式串T在主串S中首次出现的位置,如果不存在,则返回0。 + * 如果查找成功,返回匹配的位置。 + * + *【注】 + * 1.此实现不依赖串的最小操作子集 + * 2.该实现比较低效 + */ +int Index_2(SString S, SString T, int pos); + +/* + * 插入 + * + * 将串T插入到主串S的pos位置处。 + */ +Status StrInsert(SString S, int pos, SString T); + +/* + * 删除 + * + * 删除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); + +/* + * 替换 + * + * 用V替换主串S中出现的所有与T相等的且不重叠的子串。 + * + *【注】 + * 该操作依赖最小操作子集,效率较低。 + */ +Status Replace(SString S, SString T, SString V); + +/* + * ████████ 算法4.2 ████████ + * + * 串联接 + * + * 联接S1和S2,并存储到T中返回。如果联接后的长度溢出,则只保留未溢出的部分。 + * 返回值表示联接后的串是否完整。 + * + *【注】 + * 该操作属于最小操作子集 + */ +Status Concat(SString T, SString S1, SString S2); + +// 输出:打印字符串 +void StrPrint(SString S); + +#endif diff --git a/CLion/ExerciseBook/04.28-04.29/04.28-04.29.c b/CLion/ExerciseBook/04.28-04.29/04.28-04.29.c new file mode 100644 index 0000000..62bdcc7 --- /dev/null +++ b/CLion/ExerciseBook/04.28-04.29/04.28-04.29.c @@ -0,0 +1,211 @@ +#include +#include +#include +#include "Status.h" //**▲01 绪论**// + +/* + * 单链表元素类型定义 + * + *【注】 + * 这里的链表虽然用作字符串,但是元素类型仍然用int,原因是: + * 1.需要借用头结点存储结点的数量,所以用int比直接用char合适 + * 2.char可以与int兼容,所以结点虽然是int,但也可以用来存储char + */ +typedef int ElemType; + +/* 字符串结点 */ +typedef struct SNode { + ElemType chdata; // 数据结点 + struct SNode* succ; // 指向后继结点 + struct SNode* next; // next在主串中,指向前驱结点,在模式串中,指向该结点处失配时应当参与比较的下一个结点 +} SNode; + +// 字符串 +typedef SNode* String; + + +// 初始化 +Status StrAssign_4_28(String* S, char* chars); + +// 求串长 +int StrLength_4_28(String S); + +// 字符串输出 +void StrPrint_4_28(String S); + +/* + * 计算模式串的next值(改进后的算法) + * + * 功能相当于KMP算法那章的get_nextval函数 + */ +Status Algo_4_28(String T); + +/* + * KMP算法 + * + * 功能相当于KMP算法那章的Index_KMP函数 + */ +int Algo_4_29(String S, String T, int pos); + + +int main(int argc, char* argv[]) { + char* s = "abaaabaababaabcaabaabcacabaabcaabaabcac"; + char* t = "abaabcac"; + String S, T; + int pos, i; + + StrAssign_4_28(&S, s); //主串 + StrAssign_4_28(&T, t); //模式串 + + printf("主 串:S = "); + StrPrint_4_28(S); + printf("模式串:T = "); + StrPrint_4_28(T); + + printf("███题 4.28 验证...███\n"); + Algo_4_28(T); + printf("创建next表...\n"); + + printf("███题 4.29 验证...███\n"); + pos = 18; + i = Algo_4_29(S, T, pos); + printf("模式串 T 从主串 S 的第 %d 个字符起第一次匹配成功的位置为 %d\n", pos, i); + + return 0; +} + + +// 初始化 +Status StrAssign_4_28(String* S, char* chars) { + int i, len; + String p; + + if(S == NULL || chars == NULL) { + return ERROR; + } + + len = (int) strlen(chars); + + // 创建头结点 + *S = (String) malloc(sizeof(SNode)); + (*S)->chdata = len; // 记录串的长度 + (*S)->next = NULL; // 头结点的前驱 + + p = *S; + + for(i = 0; i < len; i++) { + p->succ = (String) malloc(sizeof(SNode)); + p->succ->chdata = chars[i]; + p->succ->next = p; // next默认指向前一个结点 + p = p->succ; + } + + // 最后一个结点的后继为NULL + p->succ = NULL; + + return OK; +} + +// 求串长 +int StrLength_4_28(String S) { + return S == NULL ? 0 : S->chdata; +} + +// 字符串输出 +void StrPrint_4_28(String S) { + String p; + + if(S == NULL) { + printf("\n"); + return; + } + + for(p = S->succ; p != NULL; p = p->succ) { + printf("%c", p->chdata); + } + + printf("\n"); +} + +/* + * 计算模式串的next值(改进后的算法) + * + * 功能相当于KMP算法那章的get_nextval函数 + */ +Status Algo_4_28(String T) { + SNode* i, * j; + + if(StrLength_4_28(T) == 0) { + return ERROR; + } + + i = T->succ; // 相当于之前的i=1 + j = T; // 相当于之前的j=0 + + // 模式串第一个字符处失配时,模式串需要从头比较,主串需要前进到下一个位置比较 + i->next = T; + + // 遍历模式串上的字符 + while(i->succ != NULL) { + if(j == T || i->chdata == j->chdata) { + i = i->succ; + j = j->succ; + + if(i->chdata != j->chdata) { + i->next = j; + } else { + i->next = j->next; + } + } else { + j = j->next; + } + } + + return OK; +} + +/* + * KMP算法 + * + * 功能相当于KMP算法那章的Index_KMP函数 + */ +int Algo_4_29(String S, String T, int pos) { + int count; // 记录i的位置 + SNode* i, * j; // i遍历S,j遍历T + + if(pos < 1 || StrLength_4_28(S) == 0 || StrLength_4_28(T) == 0) { + return 0; + } + + for(count = 1, i = S->succ; count < pos; count++, i = i->succ) { + // 用i指向第pos个结点 + } + + j = T->succ; + + // 比较字符串 + while(i != NULL && j != NULL) { + /* + * 两种情形: + * 1.在模式串的第一个字符处就失配 + * 2.主串和模式串处的字符相等 + */ + if(j == T || i->chdata == j->chdata) { + i = i->succ; + j = j->succ; + + count++; // 记录i的位置 + } else { + // 失配时回到前一个适当的位置 + j = j->next; + } + } + + // 匹配成功,返回匹配位置 + if(j == NULL) { + return count-StrLength_4_28(T); + } else { + // 匹配失败 + return 0; + } +} diff --git a/CLion/ExerciseBook/04.28-04.29/CMakeLists.txt b/CLion/ExerciseBook/04.28-04.29/CMakeLists.txt new file mode 100644 index 0000000..bacd1d9 --- /dev/null +++ b/CLion/ExerciseBook/04.28-04.29/CMakeLists.txt @@ -0,0 +1,7 @@ +# 包含公共库 +include_directories(${CMAKE_SOURCE_DIR}/Status) + +# 生成可执行文件 +add_executable(04.28-04.29 04.28-04.29.c) +# 链接公共库 +target_link_libraries(04.28-04.29 Scanf_lib) \ No newline at end of file diff --git a/CLion/ExerciseBook/04.30/04.30.c b/CLion/ExerciseBook/04.30/04.30.c new file mode 100644 index 0000000..013c5b4 --- /dev/null +++ b/CLion/ExerciseBook/04.30/04.30.c @@ -0,0 +1,116 @@ +#include +#include "SString.h" //**▲04 串**// + +/* + * 在串S中查找首次出现的最长重复子串及其位置 + * Sub用来记录重复子串 + * pos用来记录其在S中出现的位置 + * + * 此处的最长重复子串有以下含义: + * 1.子串必须连续 + * 2.此子串在所有重复子串中是首个出现且最长的; + * 3.子串间可以重叠,比如求取abcabca的结果为abca; + * 4.子串内可以重复,如求取aaaa的结果为aaa。 + */ +Status Algo_4_30(SString S, SString Sub, int* pos); + + +int main(int argc, char* argv[]) { + char* s = "abcdeabcabcbcdefbcdefefghefgh"; + SString Sub, S; + int pos; + + StrAssign(S, s); + printf("主串...\n"); + printf("S = "); + StrPrint(S); + + printf("计算首个最长不重复子串...\n"); + printf("Sub = "); + Algo_4_30(S, Sub, &pos); + StrPrint(Sub); + printf("Sub 在 S 中首次出现的位置为 %d\n", pos); + + return 0; +} + + +/* + * 在串S中查找首次出现的最长重复子串及其位置 + * Sub用来记录重复子串 + * pos用来记录其在S中出现的位置 + * + * 此处的最长重复子串有以下含义: + * 1.子串必须连续 + * 2.此子串在所有重复子串中是首个出现且最长的; + * 3.子串间可以重叠,比如求取abcabca的结果为abca; + * 4.子串内可以重复,如求取aaaa的结果为aaa。 + */ +Status Algo_4_30(SString S, SString Sub, int* pos) { + int i, j, is, js; + int k, start; + int len, maxLen; + + // 主串长度不能少于2 + if(S[0] < 2) { + return ERROR; + } + + start = 0; + maxLen = 0; + + // 遍历主串上所有可能的起点 + for(k = 1; k < S[0]; k++) { + is = k; // 主串起点 + js = k + 1; // 子串起点 + + // 如果剩余的字符数量不比已知的最长重复字符串更长,则无需再遍历下去 + if(S[0] - js + 1 <= maxLen) { + break; + } + + // 查找与is为起点的串重复的串 + while(TRUE) { + // 寻找潜在的重复子串起点 + while(js <= S[0] && S[is] != S[js]) { + js++; + } + + // 说明主串起点处的字符串唯一 + if(js > S[0]) { + break; + } + + // 如果剩余的字符数量不比已知的最长重复字符串更长,则无需再遍历下去 + if(S[0] - js + 1 <= maxLen) { + break; + } + + len = 0; + i = is; + j = js; + + // 计算重复串的长度 + while(j <= S[0] && S[i] == S[j]) { + i++; + j++; + len++; + } + + if(len > maxLen) { + start = k; + maxLen = len; + } + + // 查看后面有没有更长的重复串 + if(j < S[0]) { + js++; + } + } + } + + *pos = start; + SubString(Sub, S, start, maxLen); + + return OK; +} diff --git a/CLion/ExerciseBook/04.30/CMakeLists.txt b/CLion/ExerciseBook/04.30/CMakeLists.txt new file mode 100644 index 0000000..c8daaf7 --- /dev/null +++ b/CLion/ExerciseBook/04.30/CMakeLists.txt @@ -0,0 +1,7 @@ +# 包含公共库 +include_directories(${CMAKE_SOURCE_DIR}/Status) + +# 生成可执行文件 +add_executable(04.30 SString.h SString.c 04.30.c) +# 链接公共库 +target_link_libraries(04.30 Scanf_lib) \ No newline at end of file diff --git a/CLion/ExerciseBook/04.30/SString.c b/CLion/ExerciseBook/04.30/SString.c new file mode 100644 index 0000000..8673b3b --- /dev/null +++ b/CLion/ExerciseBook/04.30/SString.c @@ -0,0 +1,406 @@ +/*============================= + * 串的定长顺序存储表示(顺序串) + * + * 包含算法: 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 DestroyString(SString S) { + 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; +} + +/* + * ████████ 算法4.1 ████████ + * + * 查找 + * + * 从pos处开始搜索模式串T在主串S中首次出现的位置,如果不存在,则返回0。 + * 如果查找成功,返回匹配的位置。 + * + *【注】 + * 1.此实现需要依赖串的最小操作子集 + * 2.该实现比较低效 + */ +int Index_1(SString S, SString T, int pos) { + int i, n, m; // 记录S和T的长度 + SString sub; + + /* + * 失败情形提前处理 + * 这里与教材写法略微不同 + */ + if(pos < 1 || pos > S[0] || StrEmpty(T)) { + return 0; + } + + n = StrLength(S); + m = StrLength(T); + i = pos; + + // 保证长度不越界 + while(i <= n - m + 1) { + // 获取S[i, i+m-1] + SubString(sub, S, i, m); + + // 如果子串与模式串不匹配,则需要继续推进 + if(StrCompare(sub, T) != 0) { + ++i; + } else { + return i; + } + } + + return 0; +} + +/* + * ████████ 算法4.5 ████████ + * + * 查找 + * + * 从pos处开始搜索模式串T在主串S中首次出现的位置,如果不存在,则返回0。 + * 如果查找成功,返回匹配的位置。 + * + *【注】 + * 1.此实现不依赖串的最小操作子集 + * 2.该实现比较低效 + */ +int Index_2(SString S, SString T, int pos) { + int i = pos; + int j = 1; + + if(pos < 1 || pos > S[0] || StrEmpty(T)) { + return 0; + } + + while(i <= S[0] && j <= T[0]) { + // 遇到相同字符,则继续比较后继字符 + if(S[i] == T[j]) { + i++; + j++; + + // 遇到不同的字符,则游标需要回退,重新比较 + } else { + i = i - (j - 1) + 1; // j-1代表徒劳地前进了j-1个元素,在第j个元素上功亏一篑 + j = 1; // 游标j回到串T的第一个位置 + } + } + + // 增加了一个T[0]>0的判断 + if(j > T[0] && T[0] > 0) { // T不为空串 + return i - T[0]; // 匹配成功 + } else { + return 0; + } +} + +/* + * 插入 + * + * 将串T插入到主串S的pos位置处。 + */ +Status StrInsert(SString S, int pos, SString T) { + int i; + + if(pos < 1 || pos > S[0] + 1 || S[0] + T[0] > MAXSTRLEN) { + return ERROR; + } + + // 如果待插入的串为空,则提前返回 + if(StrEmpty(T)) { + return OK; + } + + // 在S中腾出位置,为插入T做准备 + for(i = S[0]; i >= pos; i--) { + // 从后向前遍历,将前面的元素挪到后面 + S[i + T[0]] = S[i]; + } + + // 将串T插入在S中腾出的位置上 + for(i = pos; i <= pos + T[0] - 1; i++) { + S[i] = T[i - pos + 1]; + } + + // 长度增加 + S[0] += T[0]; + + 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; +} + +/* + * 替换 + * + * 用V替换主串S中出现的所有与T相等的且不重叠的子串。 + * + *【注】 + * 1.该操作依赖最小操作子集 + * 2.该实现比较低效 + */ +Status Replace(SString S, SString T, SString V) { + int i; + + if(StrEmpty(S) || StrEmpty(T)) { + return ERROR; + } + + // 在主串S中寻找模式串T第一次出现的位置 + i = Index_2(S, T, 1); + + // 如果存在匹配的字符串,且可以被完全替换(替换后不溢出) + while(i != 0 && S[0] - T[0] + V[0] <= MAXSTRLEN) { + StrDelete(S, i, StrLength(T)); // 从S中删除T + StrInsert(S, i, V); // 向S中插入V + + i += StrLength(V); // i切换到下一个位置 + + i = Index_2(S, T, i); // 查找下一个匹配的字符串 + } + + if(i == 0) { // S中的T已全部被替换 + return OK; + } else { // S中尚有T,但是V已经插不进去了 + return ERROR; + } +} + +/* + * ████████ 算法4.2 ████████ + * + * 串联接 + * + * 联接S1和S2,并存储到T中返回。如果联接后的长度溢出,则只保留未溢出的部分。 + * 返回值表示联接后的串是否完整。 + * + *【注】 + * 该操作属于最小操作子集 + */ +Status Concat(SString T, SString S1, SString S2) { + int i; + int uncut; // 新串是否完整 + + // 完全不需要裁剪 + if(S1[0] + S2[0] <= MAXSTRLEN) { + // 复制S1到T中 + for(i = 1; i <= S1[0]; i++) { + T[i] = S1[i]; + } + + // 复制S2到T中 + for(i = S1[0] + 1; i <= S1[0] + S2[0]; i++) { + T[i] = S2[i - S1[0]]; + } + + // 设置新长度 + T[0] = S1[0] + S2[0]; + + // 未裁剪,完整 + uncut = TRUE; + + // 需要裁剪S2 + } else if(S1[0] <= MAXSTRLEN) { + // 复制S1到T中 + for(i = 1; i <= S1[0]; i++) { + T[i] = S1[i]; + } + + // 将S2的一部分复制到T中 + for(i = S1[0] + 1; i <= MAXSTRLEN; i++) { + T[i] = S2[i - S1[0]]; + } + + // 设置新长度 + T[0] = MAXSTRLEN; + + uncut = FALSE; + + // 只需要复制S1的一部分 + } else { + // 连同长度信息一起复制 + for(i = 0; i <= MAXSTRLEN; i++) { + T[i] = S1[i]; + } + + uncut = FALSE; + } + + return uncut; +} + +// 输出:打印字符串 +void StrPrint(SString S) { + int i; + + for(i = 1; i<=S[0] ; i++) { + printf("%c", S[i]); + } + + printf("\n"); +} diff --git a/CLion/ExerciseBook/04.30/SString.h b/CLion/ExerciseBook/04.30/SString.h new file mode 100644 index 0000000..d164913 --- /dev/null +++ b/CLion/ExerciseBook/04.30/SString.h @@ -0,0 +1,179 @@ +/*============================= + * 串的定长顺序存储表示(顺序串) + * + * 包含算法: 4.1、4.2、4.3、4.5 + ==============================*/ + +#ifndef SSTRING_H +#define SSTRING_H + +#include +#include // 提供strlen原型 +#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 DestroyString(SString S); + +/* + * 清空 + * + * 将串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); + +/* + * ████████ 算法4.1 ████████ + * + * 查找 + * + * 从pos处开始搜索模式串T在主串S中首次出现的位置,如果不存在,则返回0。 + * 如果查找成功,返回匹配的位置。 + * + *【注】 + * 1.此实现需要依赖串的最小操作子集 + * 2.该实现比较低效 + */ +int Index_1(SString S, SString T, int pos); + +/* + * ████████ 算法4.5 ████████ + * + * 查找 + * + * 从pos处开始搜索模式串T在主串S中首次出现的位置,如果不存在,则返回0。 + * 如果查找成功,返回匹配的位置。 + * + *【注】 + * 1.此实现不依赖串的最小操作子集 + * 2.该实现比较低效 + */ +int Index_2(SString S, SString T, int pos); + +/* + * 插入 + * + * 将串T插入到主串S的pos位置处。 + */ +Status StrInsert(SString S, int pos, SString T); + +/* + * 删除 + * + * 删除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); + +/* + * 替换 + * + * 用V替换主串S中出现的所有与T相等的且不重叠的子串。 + * + *【注】 + * 该操作依赖最小操作子集,效率较低。 + */ +Status Replace(SString S, SString T, SString V); + +/* + * ████████ 算法4.2 ████████ + * + * 串联接 + * + * 联接S1和S2,并存储到T中返回。如果联接后的长度溢出,则只保留未溢出的部分。 + * 返回值表示联接后的串是否完整。 + * + *【注】 + * 该操作属于最小操作子集 + */ +Status Concat(SString T, SString S1, SString S2); + +// 输出:打印字符串 +void StrPrint(SString S); + +#endif diff --git a/CLion/ExerciseBook/04.31/04.31.c b/CLion/ExerciseBook/04.31/04.31.c new file mode 100644 index 0000000..2edc497 --- /dev/null +++ b/CLion/ExerciseBook/04.31/04.31.c @@ -0,0 +1,248 @@ +#include +#include +#include "Status.h" //**▲01 绪论**// +#include "SString.h" //**▲04 串**// + +/* + * ████ 提示 ████ + * + * 本问题是一个动态规划问题,详细思路参见《算法导论》第三版第15.4节。 + * + * 注:《算法导论》中的"最长公共子序列"问题会统计不连续的子串,但是本题只会统计连续的子串。 + */ + + +/* 最长公共子串密码表 */ +typedef struct { + char dir; + int len; +} LCS; + +/* 子串坐标 */ +typedef struct { + int s; // 该子串在串S中的位置 + int t; // 该子串在串T中的位置 +} Pos; + +/* 最长公共子串集合 */ +typedef struct { + int maxlen; // 最长公共子串的长度 + Pos* pos; // 所有最长公共子串的坐标 + int count; // 最长公共子串的数量 +} Strs; + + +/* + * 计算S和T中的最长公共子串。 + * + * 其中,坐标最靠左的被称为"第一个出现的最长公共子串"。 + */ +Status Algo_4_31(SString S, SString T); + +/* + * 获取最长公共子串的坐标信息 + */ +void LocationPos(SString S, SString T, Strs* strs); + +/* + * 建立最长公共子串密码表,并获取最长公共子串的长度。 + */ +Status BuildLCS(SString S, SString T, LCS*** lcs, int* maxLen); + +/* + * 打印最长公共子串密码表(可选操作)。 + */ +void PrintLCS(SString S, SString T, LCS** lcs); + + +int main(int argc, char* argv[]) { + char* s = "csajcu123456ewjfskhsdufasawx"; + char* t = "m123456vsadksjewjfshcdsdufassgcx"; + SString S, T; + + StrAssign(S, s); + StrAssign(T, t); + + Algo_4_31(S, T); + + return 0; +} + + +/* + * 计算S和T中的最长公共子串。 + * + * 其中,坐标最靠左的被称为"第一个出现的最长公共子串"。 + */ +Status Algo_4_31(SString S, SString T) { + Strs strs; + SString sub; + int i; + + LocationPos(S, T, &strs); + + printf("最长公共子串的长度为:%d \n", strs.maxlen); + printf("输出所有最长公共子串及其坐标:\n"); + for(i=0; i=size) { + size += 10; + (*strs).pos = (Pos*) realloc((*strs).pos, size * sizeof(Pos)); + } + + (*strs).pos[(*strs).count].s = i-maxLen+1; + (*strs).pos[(*strs).count].t = j-maxLen+1; + (*strs).count++; + } + } +} + +/* + * 建立最长公共子串密码表,并获取最长公共子串的长度。 + */ +Status BuildLCS(SString S, SString T, LCS*** lcs, int* maxLen) { + int sLen, tLen; + int i, j; + int max; + LCS node; + + sLen = StrLength(S); + tLen = StrLength(T); + + if(sLen == 0 || tLen == 0) { + return ERROR; + } + + // 初始化LCS表格 + *lcs = (LCS**) malloc((sLen + 1) * sizeof(LCS*)); + for(i = 0; i <= sLen; i++) { + (*lcs)[i] = (LCS*) malloc((tLen + 1) * sizeof(LCS)); + } + + for(i = 0; i <= sLen; i++) { + (*lcs)[i][0].dir = ' '; + (*lcs)[i][0].len = 0; + } + + for(j = 0; j <= tLen; j++) { + (*lcs)[0][j].dir = ' '; + (*lcs)[0][j].len = 0; + } + + max = 0; + + for(i = 1; i <= sLen; i++) { + for(j = 1; j <= tLen; j++) { + // 此种情形与《算法导论》中的解析略微不同,此处需要统计连续的子串 + if(S[i] == T[j]) { + // 如果前一个字符也相等,说明这是个连续的公共子串 + if(i > 1 && j > 1 && S[i - 1] == T[j - 1]) { + node.dir = '\\'; + node.len = (*lcs)[i - 1][j - 1].len + 1; + + // 断开了 + } else { + node.dir = ' '; + node.len = 1; + } + + if(node.len > max) { + max = node.len; + } + } else { + if((*lcs)[i - 1][j].len >= (*lcs)[i][j - 1].dir) { + node.dir = '^'; + node.len = (*lcs)[i - 1][j].len; + } else { + node.dir = '<'; + node.len = (*lcs)[i][j - 1].len; + } + } + + (*lcs)[i][j] = node; + } + } + + *maxLen = max; + + return ERROR; +} + +/* + * 打印最长公共子串密码表(可选操作)。 + */ +void PrintLCS(SString S, SString T, LCS** lcs) { + int sLen, tLen; + int i, j; + + sLen = StrLength(S); + tLen = StrLength(T); + + if(sLen == 0 || tLen == 0) { + return; + } + + // 第一行 + printf(" "); + for(j = 1; j <= tLen; j++) { + printf(" %c ", T[j]); + } + printf("\n"); + + // 第二行 + printf(" "); + for(j = 1; j <= tLen; j++) { + printf("--- "); + } + printf("\n"); + + for(i = 1; i <= sLen; i++) { + for(j = 1; j <= tLen; j++) { + // 每一行的开始 + if(j == 1) { + printf("%c |", S[i]); + } + + printf("%c%2d ", lcs[i][j].dir, lcs[i][j].len); + } + printf("\n"); + } + + printf("\n"); +} diff --git a/CLion/ExerciseBook/04.31/CMakeLists.txt b/CLion/ExerciseBook/04.31/CMakeLists.txt new file mode 100644 index 0000000..204b130 --- /dev/null +++ b/CLion/ExerciseBook/04.31/CMakeLists.txt @@ -0,0 +1,7 @@ +# 包含公共库 +include_directories(${CMAKE_SOURCE_DIR}/Status) + +# 生成可执行文件 +add_executable(04.31 SString.h SString.c 04.31.c) +# 链接公共库 +target_link_libraries(04.31 Scanf_lib) \ No newline at end of file diff --git a/CLion/ExerciseBook/04.31/SString.c b/CLion/ExerciseBook/04.31/SString.c new file mode 100644 index 0000000..8673b3b --- /dev/null +++ b/CLion/ExerciseBook/04.31/SString.c @@ -0,0 +1,406 @@ +/*============================= + * 串的定长顺序存储表示(顺序串) + * + * 包含算法: 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 DestroyString(SString S) { + 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; +} + +/* + * ████████ 算法4.1 ████████ + * + * 查找 + * + * 从pos处开始搜索模式串T在主串S中首次出现的位置,如果不存在,则返回0。 + * 如果查找成功,返回匹配的位置。 + * + *【注】 + * 1.此实现需要依赖串的最小操作子集 + * 2.该实现比较低效 + */ +int Index_1(SString S, SString T, int pos) { + int i, n, m; // 记录S和T的长度 + SString sub; + + /* + * 失败情形提前处理 + * 这里与教材写法略微不同 + */ + if(pos < 1 || pos > S[0] || StrEmpty(T)) { + return 0; + } + + n = StrLength(S); + m = StrLength(T); + i = pos; + + // 保证长度不越界 + while(i <= n - m + 1) { + // 获取S[i, i+m-1] + SubString(sub, S, i, m); + + // 如果子串与模式串不匹配,则需要继续推进 + if(StrCompare(sub, T) != 0) { + ++i; + } else { + return i; + } + } + + return 0; +} + +/* + * ████████ 算法4.5 ████████ + * + * 查找 + * + * 从pos处开始搜索模式串T在主串S中首次出现的位置,如果不存在,则返回0。 + * 如果查找成功,返回匹配的位置。 + * + *【注】 + * 1.此实现不依赖串的最小操作子集 + * 2.该实现比较低效 + */ +int Index_2(SString S, SString T, int pos) { + int i = pos; + int j = 1; + + if(pos < 1 || pos > S[0] || StrEmpty(T)) { + return 0; + } + + while(i <= S[0] && j <= T[0]) { + // 遇到相同字符,则继续比较后继字符 + if(S[i] == T[j]) { + i++; + j++; + + // 遇到不同的字符,则游标需要回退,重新比较 + } else { + i = i - (j - 1) + 1; // j-1代表徒劳地前进了j-1个元素,在第j个元素上功亏一篑 + j = 1; // 游标j回到串T的第一个位置 + } + } + + // 增加了一个T[0]>0的判断 + if(j > T[0] && T[0] > 0) { // T不为空串 + return i - T[0]; // 匹配成功 + } else { + return 0; + } +} + +/* + * 插入 + * + * 将串T插入到主串S的pos位置处。 + */ +Status StrInsert(SString S, int pos, SString T) { + int i; + + if(pos < 1 || pos > S[0] + 1 || S[0] + T[0] > MAXSTRLEN) { + return ERROR; + } + + // 如果待插入的串为空,则提前返回 + if(StrEmpty(T)) { + return OK; + } + + // 在S中腾出位置,为插入T做准备 + for(i = S[0]; i >= pos; i--) { + // 从后向前遍历,将前面的元素挪到后面 + S[i + T[0]] = S[i]; + } + + // 将串T插入在S中腾出的位置上 + for(i = pos; i <= pos + T[0] - 1; i++) { + S[i] = T[i - pos + 1]; + } + + // 长度增加 + S[0] += T[0]; + + 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; +} + +/* + * 替换 + * + * 用V替换主串S中出现的所有与T相等的且不重叠的子串。 + * + *【注】 + * 1.该操作依赖最小操作子集 + * 2.该实现比较低效 + */ +Status Replace(SString S, SString T, SString V) { + int i; + + if(StrEmpty(S) || StrEmpty(T)) { + return ERROR; + } + + // 在主串S中寻找模式串T第一次出现的位置 + i = Index_2(S, T, 1); + + // 如果存在匹配的字符串,且可以被完全替换(替换后不溢出) + while(i != 0 && S[0] - T[0] + V[0] <= MAXSTRLEN) { + StrDelete(S, i, StrLength(T)); // 从S中删除T + StrInsert(S, i, V); // 向S中插入V + + i += StrLength(V); // i切换到下一个位置 + + i = Index_2(S, T, i); // 查找下一个匹配的字符串 + } + + if(i == 0) { // S中的T已全部被替换 + return OK; + } else { // S中尚有T,但是V已经插不进去了 + return ERROR; + } +} + +/* + * ████████ 算法4.2 ████████ + * + * 串联接 + * + * 联接S1和S2,并存储到T中返回。如果联接后的长度溢出,则只保留未溢出的部分。 + * 返回值表示联接后的串是否完整。 + * + *【注】 + * 该操作属于最小操作子集 + */ +Status Concat(SString T, SString S1, SString S2) { + int i; + int uncut; // 新串是否完整 + + // 完全不需要裁剪 + if(S1[0] + S2[0] <= MAXSTRLEN) { + // 复制S1到T中 + for(i = 1; i <= S1[0]; i++) { + T[i] = S1[i]; + } + + // 复制S2到T中 + for(i = S1[0] + 1; i <= S1[0] + S2[0]; i++) { + T[i] = S2[i - S1[0]]; + } + + // 设置新长度 + T[0] = S1[0] + S2[0]; + + // 未裁剪,完整 + uncut = TRUE; + + // 需要裁剪S2 + } else if(S1[0] <= MAXSTRLEN) { + // 复制S1到T中 + for(i = 1; i <= S1[0]; i++) { + T[i] = S1[i]; + } + + // 将S2的一部分复制到T中 + for(i = S1[0] + 1; i <= MAXSTRLEN; i++) { + T[i] = S2[i - S1[0]]; + } + + // 设置新长度 + T[0] = MAXSTRLEN; + + uncut = FALSE; + + // 只需要复制S1的一部分 + } else { + // 连同长度信息一起复制 + for(i = 0; i <= MAXSTRLEN; i++) { + T[i] = S1[i]; + } + + uncut = FALSE; + } + + return uncut; +} + +// 输出:打印字符串 +void StrPrint(SString S) { + int i; + + for(i = 1; i<=S[0] ; i++) { + printf("%c", S[i]); + } + + printf("\n"); +} diff --git a/CLion/ExerciseBook/04.31/SString.h b/CLion/ExerciseBook/04.31/SString.h new file mode 100644 index 0000000..d164913 --- /dev/null +++ b/CLion/ExerciseBook/04.31/SString.h @@ -0,0 +1,179 @@ +/*============================= + * 串的定长顺序存储表示(顺序串) + * + * 包含算法: 4.1、4.2、4.3、4.5 + ==============================*/ + +#ifndef SSTRING_H +#define SSTRING_H + +#include +#include // 提供strlen原型 +#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 DestroyString(SString S); + +/* + * 清空 + * + * 将串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); + +/* + * ████████ 算法4.1 ████████ + * + * 查找 + * + * 从pos处开始搜索模式串T在主串S中首次出现的位置,如果不存在,则返回0。 + * 如果查找成功,返回匹配的位置。 + * + *【注】 + * 1.此实现需要依赖串的最小操作子集 + * 2.该实现比较低效 + */ +int Index_1(SString S, SString T, int pos); + +/* + * ████████ 算法4.5 ████████ + * + * 查找 + * + * 从pos处开始搜索模式串T在主串S中首次出现的位置,如果不存在,则返回0。 + * 如果查找成功,返回匹配的位置。 + * + *【注】 + * 1.此实现不依赖串的最小操作子集 + * 2.该实现比较低效 + */ +int Index_2(SString S, SString T, int pos); + +/* + * 插入 + * + * 将串T插入到主串S的pos位置处。 + */ +Status StrInsert(SString S, int pos, SString T); + +/* + * 删除 + * + * 删除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); + +/* + * 替换 + * + * 用V替换主串S中出现的所有与T相等的且不重叠的子串。 + * + *【注】 + * 该操作依赖最小操作子集,效率较低。 + */ +Status Replace(SString S, SString T, SString V); + +/* + * ████████ 算法4.2 ████████ + * + * 串联接 + * + * 联接S1和S2,并存储到T中返回。如果联接后的长度溢出,则只保留未溢出的部分。 + * 返回值表示联接后的串是否完整。 + * + *【注】 + * 该操作属于最小操作子集 + */ +Status Concat(SString T, SString S1, SString S2); + +// 输出:打印字符串 +void StrPrint(SString S); + +#endif diff --git a/CLion/ExerciseBook/CMakeLists.txt b/CLion/ExerciseBook/CMakeLists.txt index 61c7125..0d77604 100644 --- a/CLion/ExerciseBook/CMakeLists.txt +++ b/CLion/ExerciseBook/CMakeLists.txt @@ -49,3 +49,21 @@ add_subdirectory(03.30+03.32) add_subdirectory(03.31) add_subdirectory(03.33) add_subdirectory(03.34) + +add_subdirectory(04.10) +add_subdirectory(04.11) +add_subdirectory(04.12) +add_subdirectory(04.13) +add_subdirectory(04.14) +add_subdirectory(04.15-04.17) +add_subdirectory(04.18) +add_subdirectory(04.19) +add_subdirectory(04.20) +add_subdirectory(04.21) +add_subdirectory(04.22) +add_subdirectory(04.23) +add_subdirectory(04.24-04.26) +add_subdirectory(04.27) +add_subdirectory(04.28-04.29) +add_subdirectory(04.30) +add_subdirectory(04.31) diff --git a/Dev-C++/ExerciseBook/04.10/04.10.cpp b/Dev-C++/ExerciseBook/04.10/04.10.cpp new file mode 100644 index 0000000..5a98ea3 --- /dev/null +++ b/Dev-C++/ExerciseBook/04.10/04.10.cpp @@ -0,0 +1,35 @@ +#include +#include "String.h" //**ַ**// + +/* + * ַãTΪR + */ +StringType Algo_4_10(StringType T) { + int i; + StringType R = "", Sub; + + // Ӻǰȡַ + for(i = StrLength(T); i >= 1; i--) { + Sub = SubString(T, i, 1); + R = Concat(R, Sub); + } + + return R; +} + + +int main(int argc, char* argv[]) { + char* s = "0123456789"; + StringType T, R; + + printf("ǰT = "); + StrAssign(&T, s); + StrPrint(T); + + printf("úR = "); + R = Algo_4_10(T); + StrPrint(R); + + return 0; +} + diff --git a/Dev-C++/ExerciseBook/04.10/04.10.dev b/Dev-C++/ExerciseBook/04.10/04.10.dev new file mode 100644 index 0000000..afe9c74 --- /dev/null +++ b/Dev-C++/ExerciseBook/04.10/04.10.dev @@ -0,0 +1,82 @@ +[Project] +FileName=04.10.dev +Name=04.10 +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=04.10.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit2] +FileName=String.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit3] +FileName=String.h +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + diff --git a/Dev-C++/ExerciseBook/04.10/String.cpp b/Dev-C++/ExerciseBook/04.10/String.cpp new file mode 100644 index 0000000..41df51c --- /dev/null +++ b/Dev-C++/ExerciseBook/04.10/String.cpp @@ -0,0 +1,151 @@ +/*=========================== + * ϰ4.10~4.14ʹõַ + ============================*/ + +#include "String.h" + +// ʼһֵΪsĴt +void StrAssign(StringType* t, const char* s) { + if(s == NULL) { + *t = ""; + } + + *t = (char*) malloc((strlen(s) + 1) * sizeof(char)); + + strcpy(*t, s); +} + +// ȽϣstĴССһ£0 +int StrCompare(StringType s, StringType t) { + return strcmp(s, t); +} + +// ַsij +int StrLength(StringType s) { + return (int) strlen(s); +} + +// ӣstӺĴ +StringType Concat(StringType s, StringType t) { + StringType r; + + if(s == NULL) { + s = ""; + } + + if(t == NULL) { + t = ""; + } + + r = (char*) malloc((strlen(s) + strlen(t) + 1) * sizeof(char)); + r[0] = '\0'; + + strcat(r, s); + strcat(r, t); + + return r; +} + +// Ӵsstartλ𣬽ȡlenַ󷵻 +StringType SubString(StringType s, int start, int len) { + int n; + char* sub; + + n = (int) strlen(s); + + if(start < 1 || start > n || start + len - 1 > n || len < 0) { + return ""; + } + + sub = (char*) malloc((len + 1) * sizeof(char)); + strncpy(sub, s + start - 1, len); + sub[len] = '\0'; + + return sub; +} + +// ңsposλtҵλ +int Index(StringType s, StringType t, int pos) { + int m, n, i; + StringType sub; + + // ʧǰ + if(pos < 1 || pos > StrLength(s) || StrLength(t) == 0) { + return 0; + } + + n = StrLength(s); + m = StrLength(t); + i = pos; + + // ֤ȲԽ + while(i <= n - m + 1) { + // ȡS[i, i+m-1] + sub = SubString(s, i, m); + + // Ӵģʽƥ䣬Ҫƽ + if(StrCompare(sub, t) != 0) { + ++i; + } else { + return i; + } + } + + return 0; +} + +// 룺spost +Status StrInsert(StringType* s, int pos, StringType t) { + StringType r; + StringType s1, s2; + + if(pos < 1 || pos > StrLength(*s) + 1) { + return ERROR; + } + + r = (StringType) malloc((strlen(*s) + strlen(t) + 1) * sizeof(char)); + r[0] = '\0'; + + // ĴΪգǰ + if(StrLength(t) == 0) { + return OK; + } + + s1 = SubString(*s, 1, pos - 1); + s2 = SubString(*s, pos, (int) strlen(*s) - pos + 1); + + strcat(r, s1); + strcat(r, t); + strcat(r, s2); + + *s = r; + + return OK; +} + +// ɾsposλɾlenַ +Status StrDelete(StringType* s, int pos, int len) { + StringType r; + + if(pos < 1 || pos + len - 1 > StrLength(*s) || len < 0) { + return ERROR; + } + + // ɾijΪ0ǰ + if(len == 0) { + return OK; + } + + r = (StringType) malloc((StrLength(*s) - len + 1) * sizeof(char)); + strncpy(r, *s, pos - 1); + strcpy(r + pos - 1, *s + pos + len - 1); + + *s = r; + + return OK; +} + +// ַ +void StrPrint(StringType s) { + printf("%s\n", s); +} diff --git a/Dev-C++/ExerciseBook/04.10/String.h b/Dev-C++/ExerciseBook/04.10/String.h new file mode 100644 index 0000000..9d984af --- /dev/null +++ b/Dev-C++/ExerciseBook/04.10/String.h @@ -0,0 +1,43 @@ +/*=========================== + * ϰ4.10~4.14ʹõַ + ============================*/ + +#ifndef STRING_H +#define STRING_H + +#include +#include // ṩ strlen ԭ +#include "Status.h" //**01 **// + +/* ַ */ +typedef char* StringType; + + +// ʼһֵΪsĴt +void StrAssign(StringType* t, const char* s); + +// ȽϣstĴССһ£0 +int StrCompare(StringType s, StringType t); + +// ַsij +int StrLength(StringType s); + +// ӣstӺĴ +StringType Concat(StringType s, StringType t); + +// Ӵsstartλ𣬽ȡlenַ󷵻 +StringType SubString(StringType s, int start, int len); + +// ңsposλtҵλ +int Index(StringType s, StringType t, int pos); + +// 룺spost +Status StrInsert(StringType* s, int pos, StringType t); + +// ɾsposλɾlenַ +Status StrDelete(StringType* s, int pos, int len); + +// ַ +void StrPrint(StringType s); + +#endif diff --git a/Dev-C++/ExerciseBook/04.11/04.11.cpp b/Dev-C++/ExerciseBook/04.11/04.11.cpp new file mode 100644 index 0000000..7dd1b18 --- /dev/null +++ b/Dev-C++/ExerciseBook/04.11/04.11.cpp @@ -0,0 +1,69 @@ +#include +#include +#include "String.h" //**ַ**// + +/* + * R=S-STa洢RÿַSеһγֵλ + * + * עa0ŵԪ洢aԪصĸ + */ +void Algo_4_11(StringType* R, StringType S, StringType T, int** a) { + int i, p; + StringType ch; + + *a = (int*) malloc((StrLength(S) + 1) * sizeof(int)); + + StrAssign(R, ""); + + for(i = 1, (*a)[0] = 0; i <= StrLength(S); i++) { + // ȡַж + ch = SubString(S, i, 1); + + // ȡS[i]Tеλ + p = Index(T, ch, 1); + + // S[i]T + if(p == 0) { + // ȡS[i]Rеλ + p = Index(*R, ch, 1); + } + + // S[i]ȲTУûRгֹ + if(p == 0) { + (*a)[0]++; + (*a)[(*a)[0]] = i; + + // RS[i] + StrInsert(R, (*a)[0], ch); + } + } +} + + +int main(int argc, char* argv[]) { + char* s = "amdhcjgfdlpinbefcopgkqikeb"; + char* t = "mhjlpinopkqik"; + int* a; + StringType T, S, R; + int i; + + printf("ʼST...\n"); + StrAssign(&S, s); + StrAssign(&T, t); + printf("S = "); + StrPrint(S); + printf("T = "); + StrPrint(T); + + Algo_4_11(&R, S, T, &a); + printf("R = "); + StrPrint(R); + + printf("a = "); + for(i = 1; i <= a[0]; i++) { + printf("%d ", a[i]); + } + printf("\n"); + + return 0; +} diff --git a/Dev-C++/ExerciseBook/04.11/04.11.dev b/Dev-C++/ExerciseBook/04.11/04.11.dev new file mode 100644 index 0000000..6b7e1ec --- /dev/null +++ b/Dev-C++/ExerciseBook/04.11/04.11.dev @@ -0,0 +1,82 @@ +[Project] +FileName=04.11.dev +Name=04.11 +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=04.11.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit2] +FileName=String.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit3] +FileName=String.h +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + diff --git a/Dev-C++/ExerciseBook/04.11/String.cpp b/Dev-C++/ExerciseBook/04.11/String.cpp new file mode 100644 index 0000000..41df51c --- /dev/null +++ b/Dev-C++/ExerciseBook/04.11/String.cpp @@ -0,0 +1,151 @@ +/*=========================== + * ϰ4.10~4.14ʹõַ + ============================*/ + +#include "String.h" + +// ʼһֵΪsĴt +void StrAssign(StringType* t, const char* s) { + if(s == NULL) { + *t = ""; + } + + *t = (char*) malloc((strlen(s) + 1) * sizeof(char)); + + strcpy(*t, s); +} + +// ȽϣstĴССһ£0 +int StrCompare(StringType s, StringType t) { + return strcmp(s, t); +} + +// ַsij +int StrLength(StringType s) { + return (int) strlen(s); +} + +// ӣstӺĴ +StringType Concat(StringType s, StringType t) { + StringType r; + + if(s == NULL) { + s = ""; + } + + if(t == NULL) { + t = ""; + } + + r = (char*) malloc((strlen(s) + strlen(t) + 1) * sizeof(char)); + r[0] = '\0'; + + strcat(r, s); + strcat(r, t); + + return r; +} + +// Ӵsstartλ𣬽ȡlenַ󷵻 +StringType SubString(StringType s, int start, int len) { + int n; + char* sub; + + n = (int) strlen(s); + + if(start < 1 || start > n || start + len - 1 > n || len < 0) { + return ""; + } + + sub = (char*) malloc((len + 1) * sizeof(char)); + strncpy(sub, s + start - 1, len); + sub[len] = '\0'; + + return sub; +} + +// ңsposλtҵλ +int Index(StringType s, StringType t, int pos) { + int m, n, i; + StringType sub; + + // ʧǰ + if(pos < 1 || pos > StrLength(s) || StrLength(t) == 0) { + return 0; + } + + n = StrLength(s); + m = StrLength(t); + i = pos; + + // ֤ȲԽ + while(i <= n - m + 1) { + // ȡS[i, i+m-1] + sub = SubString(s, i, m); + + // Ӵģʽƥ䣬Ҫƽ + if(StrCompare(sub, t) != 0) { + ++i; + } else { + return i; + } + } + + return 0; +} + +// 룺spost +Status StrInsert(StringType* s, int pos, StringType t) { + StringType r; + StringType s1, s2; + + if(pos < 1 || pos > StrLength(*s) + 1) { + return ERROR; + } + + r = (StringType) malloc((strlen(*s) + strlen(t) + 1) * sizeof(char)); + r[0] = '\0'; + + // ĴΪգǰ + if(StrLength(t) == 0) { + return OK; + } + + s1 = SubString(*s, 1, pos - 1); + s2 = SubString(*s, pos, (int) strlen(*s) - pos + 1); + + strcat(r, s1); + strcat(r, t); + strcat(r, s2); + + *s = r; + + return OK; +} + +// ɾsposλɾlenַ +Status StrDelete(StringType* s, int pos, int len) { + StringType r; + + if(pos < 1 || pos + len - 1 > StrLength(*s) || len < 0) { + return ERROR; + } + + // ɾijΪ0ǰ + if(len == 0) { + return OK; + } + + r = (StringType) malloc((StrLength(*s) - len + 1) * sizeof(char)); + strncpy(r, *s, pos - 1); + strcpy(r + pos - 1, *s + pos + len - 1); + + *s = r; + + return OK; +} + +// ַ +void StrPrint(StringType s) { + printf("%s\n", s); +} diff --git a/Dev-C++/ExerciseBook/04.11/String.h b/Dev-C++/ExerciseBook/04.11/String.h new file mode 100644 index 0000000..9d984af --- /dev/null +++ b/Dev-C++/ExerciseBook/04.11/String.h @@ -0,0 +1,43 @@ +/*=========================== + * ϰ4.10~4.14ʹõַ + ============================*/ + +#ifndef STRING_H +#define STRING_H + +#include +#include // ṩ strlen ԭ +#include "Status.h" //**01 **// + +/* ַ */ +typedef char* StringType; + + +// ʼһֵΪsĴt +void StrAssign(StringType* t, const char* s); + +// ȽϣstĴССһ£0 +int StrCompare(StringType s, StringType t); + +// ַsij +int StrLength(StringType s); + +// ӣstӺĴ +StringType Concat(StringType s, StringType t); + +// Ӵsstartλ𣬽ȡlenַ󷵻 +StringType SubString(StringType s, int start, int len); + +// ңsposλtҵλ +int Index(StringType s, StringType t, int pos); + +// 룺spost +Status StrInsert(StringType* s, int pos, StringType t); + +// ɾsposλɾlenַ +Status StrDelete(StringType* s, int pos, int len); + +// ַ +void StrPrint(StringType s); + +#endif diff --git a/Dev-C++/ExerciseBook/04.12/04.12.cpp b/Dev-C++/ExerciseBook/04.12/04.12.cpp new file mode 100644 index 0000000..fe34fd9 --- /dev/null +++ b/Dev-C++/ExerciseBook/04.12/04.12.cpp @@ -0,0 +1,56 @@ +#include +#include "Status.h" //**01 **// +#include "String.h" //**ַ**// + +/* + * 滻Replace + * + * V滻SгֵTȵҲصӴ + */ +Status Algo_4_12(StringType* S, StringType T, StringType V) { + int i; + + if(StrLength(*S) == 0 || StrLength(T) == 0) { + return ERROR; + } + + i = 1; + + // SѰģʽTһγֵλ + while((i = Index(*S, T, i)) != 0) { + StrDelete(S, i, StrLength(T)); // SɾT + StrInsert(S, i, V); // SвV + + i += StrLength(V); // iлһλ + } + + return OK; +} + + +int main(int argc, char* argv[]) { + char* s = "----***--*-**-****-*****-----"; + char* t = "**"; + char* v = "^^"; + StringType T, S, V; + + printf("滻ǰ...\n"); + + StrAssign(&S, s); + StrAssign(&T, t); + StrAssign(&V, v); + + printf("S = "); + StrPrint(S); + printf("T = "); + StrPrint(T); + printf("V = "); + StrPrint(V); + + printf("滻...\n"); + printf("S = "); + Algo_4_12(&S, T, V); + StrPrint(S); + + return 0; +} diff --git a/Dev-C++/ExerciseBook/04.12/04.12.dev b/Dev-C++/ExerciseBook/04.12/04.12.dev new file mode 100644 index 0000000..30818c0 --- /dev/null +++ b/Dev-C++/ExerciseBook/04.12/04.12.dev @@ -0,0 +1,82 @@ +[Project] +FileName=04.12.dev +Name=04.12 +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=04.12.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit2] +FileName=String.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit3] +FileName=String.h +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + diff --git a/Dev-C++/ExerciseBook/04.12/String.cpp b/Dev-C++/ExerciseBook/04.12/String.cpp new file mode 100644 index 0000000..41df51c --- /dev/null +++ b/Dev-C++/ExerciseBook/04.12/String.cpp @@ -0,0 +1,151 @@ +/*=========================== + * ϰ4.10~4.14ʹõַ + ============================*/ + +#include "String.h" + +// ʼһֵΪsĴt +void StrAssign(StringType* t, const char* s) { + if(s == NULL) { + *t = ""; + } + + *t = (char*) malloc((strlen(s) + 1) * sizeof(char)); + + strcpy(*t, s); +} + +// ȽϣstĴССһ£0 +int StrCompare(StringType s, StringType t) { + return strcmp(s, t); +} + +// ַsij +int StrLength(StringType s) { + return (int) strlen(s); +} + +// ӣstӺĴ +StringType Concat(StringType s, StringType t) { + StringType r; + + if(s == NULL) { + s = ""; + } + + if(t == NULL) { + t = ""; + } + + r = (char*) malloc((strlen(s) + strlen(t) + 1) * sizeof(char)); + r[0] = '\0'; + + strcat(r, s); + strcat(r, t); + + return r; +} + +// Ӵsstartλ𣬽ȡlenַ󷵻 +StringType SubString(StringType s, int start, int len) { + int n; + char* sub; + + n = (int) strlen(s); + + if(start < 1 || start > n || start + len - 1 > n || len < 0) { + return ""; + } + + sub = (char*) malloc((len + 1) * sizeof(char)); + strncpy(sub, s + start - 1, len); + sub[len] = '\0'; + + return sub; +} + +// ңsposλtҵλ +int Index(StringType s, StringType t, int pos) { + int m, n, i; + StringType sub; + + // ʧǰ + if(pos < 1 || pos > StrLength(s) || StrLength(t) == 0) { + return 0; + } + + n = StrLength(s); + m = StrLength(t); + i = pos; + + // ֤ȲԽ + while(i <= n - m + 1) { + // ȡS[i, i+m-1] + sub = SubString(s, i, m); + + // Ӵģʽƥ䣬Ҫƽ + if(StrCompare(sub, t) != 0) { + ++i; + } else { + return i; + } + } + + return 0; +} + +// 룺spost +Status StrInsert(StringType* s, int pos, StringType t) { + StringType r; + StringType s1, s2; + + if(pos < 1 || pos > StrLength(*s) + 1) { + return ERROR; + } + + r = (StringType) malloc((strlen(*s) + strlen(t) + 1) * sizeof(char)); + r[0] = '\0'; + + // ĴΪգǰ + if(StrLength(t) == 0) { + return OK; + } + + s1 = SubString(*s, 1, pos - 1); + s2 = SubString(*s, pos, (int) strlen(*s) - pos + 1); + + strcat(r, s1); + strcat(r, t); + strcat(r, s2); + + *s = r; + + return OK; +} + +// ɾsposλɾlenַ +Status StrDelete(StringType* s, int pos, int len) { + StringType r; + + if(pos < 1 || pos + len - 1 > StrLength(*s) || len < 0) { + return ERROR; + } + + // ɾijΪ0ǰ + if(len == 0) { + return OK; + } + + r = (StringType) malloc((StrLength(*s) - len + 1) * sizeof(char)); + strncpy(r, *s, pos - 1); + strcpy(r + pos - 1, *s + pos + len - 1); + + *s = r; + + return OK; +} + +// ַ +void StrPrint(StringType s) { + printf("%s\n", s); +} diff --git a/Dev-C++/ExerciseBook/04.12/String.h b/Dev-C++/ExerciseBook/04.12/String.h new file mode 100644 index 0000000..9d984af --- /dev/null +++ b/Dev-C++/ExerciseBook/04.12/String.h @@ -0,0 +1,43 @@ +/*=========================== + * ϰ4.10~4.14ʹõַ + ============================*/ + +#ifndef STRING_H +#define STRING_H + +#include +#include // ṩ strlen ԭ +#include "Status.h" //**01 **// + +/* ַ */ +typedef char* StringType; + + +// ʼһֵΪsĴt +void StrAssign(StringType* t, const char* s); + +// ȽϣstĴССһ£0 +int StrCompare(StringType s, StringType t); + +// ַsij +int StrLength(StringType s); + +// ӣstӺĴ +StringType Concat(StringType s, StringType t); + +// Ӵsstartλ𣬽ȡlenַ󷵻 +StringType SubString(StringType s, int start, int len); + +// ңsposλtҵλ +int Index(StringType s, StringType t, int pos); + +// 룺spost +Status StrInsert(StringType* s, int pos, StringType t); + +// ɾsposλɾlenַ +Status StrDelete(StringType* s, int pos, int len); + +// ַ +void StrPrint(StringType s); + +#endif diff --git a/Dev-C++/ExerciseBook/04.13/04.13.cpp b/Dev-C++/ExerciseBook/04.13/04.13.cpp new file mode 100644 index 0000000..1478bf4 --- /dev/null +++ b/Dev-C++/ExerciseBook/04.13/04.13.cpp @@ -0,0 +1,41 @@ +#include +#include "String.h" //**ַ**// + +/* + * ɾSаT + */ +Status Algo_4_13(StringType* S, StringType T) { + int i; + + // SвTҵɾ + while((i = Index(*S, T, 1)) != 0) { + if(StrDelete(S, i, StrLength(T)) == ERROR) { + return ERROR; + } + } + + return OK; +} + + +int main(int argc, char* argv[]) { + char* s = "----***--*-**-****-*****-----"; + char* t = "**"; + StringType T, S; + + printf("ɾǰ...\n"); + StrAssign(&S, s); + StrAssign(&T, t); + + printf("S = "); + StrPrint(S); + printf("T = "); + StrPrint(T); + + printf("ɾ...\n"); + printf("S = "); + Algo_4_13(&S, T); + StrPrint(S); + + return 0; +} diff --git a/Dev-C++/ExerciseBook/04.13/04.13.dev b/Dev-C++/ExerciseBook/04.13/04.13.dev new file mode 100644 index 0000000..920b539 --- /dev/null +++ b/Dev-C++/ExerciseBook/04.13/04.13.dev @@ -0,0 +1,82 @@ +[Project] +FileName=04.13.dev +Name=04.13 +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=04.13.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit2] +FileName=String.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit3] +FileName=String.h +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + diff --git a/Dev-C++/ExerciseBook/04.13/String.cpp b/Dev-C++/ExerciseBook/04.13/String.cpp new file mode 100644 index 0000000..41df51c --- /dev/null +++ b/Dev-C++/ExerciseBook/04.13/String.cpp @@ -0,0 +1,151 @@ +/*=========================== + * ϰ4.10~4.14ʹõַ + ============================*/ + +#include "String.h" + +// ʼһֵΪsĴt +void StrAssign(StringType* t, const char* s) { + if(s == NULL) { + *t = ""; + } + + *t = (char*) malloc((strlen(s) + 1) * sizeof(char)); + + strcpy(*t, s); +} + +// ȽϣstĴССһ£0 +int StrCompare(StringType s, StringType t) { + return strcmp(s, t); +} + +// ַsij +int StrLength(StringType s) { + return (int) strlen(s); +} + +// ӣstӺĴ +StringType Concat(StringType s, StringType t) { + StringType r; + + if(s == NULL) { + s = ""; + } + + if(t == NULL) { + t = ""; + } + + r = (char*) malloc((strlen(s) + strlen(t) + 1) * sizeof(char)); + r[0] = '\0'; + + strcat(r, s); + strcat(r, t); + + return r; +} + +// Ӵsstartλ𣬽ȡlenַ󷵻 +StringType SubString(StringType s, int start, int len) { + int n; + char* sub; + + n = (int) strlen(s); + + if(start < 1 || start > n || start + len - 1 > n || len < 0) { + return ""; + } + + sub = (char*) malloc((len + 1) * sizeof(char)); + strncpy(sub, s + start - 1, len); + sub[len] = '\0'; + + return sub; +} + +// ңsposλtҵλ +int Index(StringType s, StringType t, int pos) { + int m, n, i; + StringType sub; + + // ʧǰ + if(pos < 1 || pos > StrLength(s) || StrLength(t) == 0) { + return 0; + } + + n = StrLength(s); + m = StrLength(t); + i = pos; + + // ֤ȲԽ + while(i <= n - m + 1) { + // ȡS[i, i+m-1] + sub = SubString(s, i, m); + + // Ӵģʽƥ䣬Ҫƽ + if(StrCompare(sub, t) != 0) { + ++i; + } else { + return i; + } + } + + return 0; +} + +// 룺spost +Status StrInsert(StringType* s, int pos, StringType t) { + StringType r; + StringType s1, s2; + + if(pos < 1 || pos > StrLength(*s) + 1) { + return ERROR; + } + + r = (StringType) malloc((strlen(*s) + strlen(t) + 1) * sizeof(char)); + r[0] = '\0'; + + // ĴΪգǰ + if(StrLength(t) == 0) { + return OK; + } + + s1 = SubString(*s, 1, pos - 1); + s2 = SubString(*s, pos, (int) strlen(*s) - pos + 1); + + strcat(r, s1); + strcat(r, t); + strcat(r, s2); + + *s = r; + + return OK; +} + +// ɾsposλɾlenַ +Status StrDelete(StringType* s, int pos, int len) { + StringType r; + + if(pos < 1 || pos + len - 1 > StrLength(*s) || len < 0) { + return ERROR; + } + + // ɾijΪ0ǰ + if(len == 0) { + return OK; + } + + r = (StringType) malloc((StrLength(*s) - len + 1) * sizeof(char)); + strncpy(r, *s, pos - 1); + strcpy(r + pos - 1, *s + pos + len - 1); + + *s = r; + + return OK; +} + +// ַ +void StrPrint(StringType s) { + printf("%s\n", s); +} diff --git a/Dev-C++/ExerciseBook/04.13/String.h b/Dev-C++/ExerciseBook/04.13/String.h new file mode 100644 index 0000000..9d984af --- /dev/null +++ b/Dev-C++/ExerciseBook/04.13/String.h @@ -0,0 +1,43 @@ +/*=========================== + * ϰ4.10~4.14ʹõַ + ============================*/ + +#ifndef STRING_H +#define STRING_H + +#include +#include // ṩ strlen ԭ +#include "Status.h" //**01 **// + +/* ַ */ +typedef char* StringType; + + +// ʼһֵΪsĴt +void StrAssign(StringType* t, const char* s); + +// ȽϣstĴССһ£0 +int StrCompare(StringType s, StringType t); + +// ַsij +int StrLength(StringType s); + +// ӣstӺĴ +StringType Concat(StringType s, StringType t); + +// Ӵsstartλ𣬽ȡlenַ󷵻 +StringType SubString(StringType s, int start, int len); + +// ңsposλtҵλ +int Index(StringType s, StringType t, int pos); + +// 룺spost +Status StrInsert(StringType* s, int pos, StringType t); + +// ɾsposλɾlenַ +Status StrDelete(StringType* s, int pos, int len); + +// ַ +void StrPrint(StringType s); + +#endif diff --git a/Dev-C++/ExerciseBook/04.14/04.14.cpp b/Dev-C++/ExerciseBook/04.14/04.14.cpp new file mode 100644 index 0000000..b996927 --- /dev/null +++ b/Dev-C++/ExerciseBook/04.14/04.14.cpp @@ -0,0 +1,92 @@ +#include +#include +#include "SqStack.h" //**03 ջͶ**// +#include "String.h" //**ַ**// + +/* + * ǰ׺ʽprefixתΪ׺ʽ + * + *ע + * δǰ׺ʽȷԽ֤ + */ +Status Algo_4_14(const char* prefix, char** suffix) { + StringType P, S; + StringType Operator; // + SqStack stack; // ʽջ + StringType e; // ջԪ + StringType o; // ջ + int i, len; + int readStr; // ǷҪȡַ + + len = (int) strlen(prefix); + + if(len == 0) { + *suffix = NULL; + return ERROR; + } + + // Ͳ + StrAssign(&Operator, "+-*/"); + + // ǰ׺ʽ + StrAssign(&P, prefix); + + // ׺ʽջ + InitStack(&stack); + + readStr = 1; + i = 1; + + // ǰ׺ʽȡԪ + while(TRUE) { + if(readStr == 1) { + S = SubString(P, i++, 1); + } + + // ֱջ + if(Index(Operator, S, 1) != 0) { + Push(&stack, S); + readStr = 1; + + // ˲ + } else { + // ȡջԪأջѾΪգSд洢˺׺ʽ + if(GetTop(stack, &e) == ERROR) { + break; + } + + // ջԪ򽫲ֱջ + if(Index(Operator, e, 1) != 0) { + Push(&stack, S); + readStr = 1; + + // ջҲDzҪм + } else { + Pop(&stack, &e); // ջ + Pop(&stack, &o); // ջ + + S = Concat(e, S); + S = Concat(S, o); + + // ²ҪȡַҪжϸոռSub + readStr = 0; + } + } + } + + // ȡ׺ʽ + *suffix = S; + + return OK; +} + + +int main(int argc, char* argv[]) { + char* prefix = "-+a*bc/de"; // ׺ʽΪabc*+de/- + char* suffix; + + Algo_4_14(prefix, &suffix); + + printf("ǰ׺ʽ%s\n", prefix); + printf("׺ʽ%s\n", suffix); +} diff --git a/Dev-C++/ExerciseBook/04.14/04.14.dev b/Dev-C++/ExerciseBook/04.14/04.14.dev new file mode 100644 index 0000000..ecb682c --- /dev/null +++ b/Dev-C++/ExerciseBook/04.14/04.14.dev @@ -0,0 +1,102 @@ +[Project] +FileName=04.14.dev +Name=04.14 +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=04.14.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit2] +FileName=SqStack.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit4] +FileName=String.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit3] +FileName=SqStack.h +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit5] +FileName=String.h +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + diff --git a/Dev-C++/ExerciseBook/04.14/SqStack.cpp b/Dev-C++/ExerciseBook/04.14/SqStack.cpp new file mode 100644 index 0000000..70e35c0 --- /dev/null +++ b/Dev-C++/ExerciseBook/04.14/SqStack.cpp @@ -0,0 +1,89 @@ +/*========================= + * ջ˳洢ṹ˳ջ + ==========================*/ + +#include "SqStack.h" //**03 ջͶ**// + +/* + * ʼ + * + * һջʼɹ򷵻OK򷵻ERROR + */ +Status InitStack(SqStack* S) { + if(S == NULL) { + return ERROR; + } + + (*S).base = (SElemType*) malloc(STACK_INIT_SIZE * sizeof(SElemType)); + if((*S).base == NULL) { + exit(OVERFLOW); + } + + (*S).top = (*S).base; + (*S).stacksize = STACK_INIT_SIZE; + + return OK; +} + +/* + * ȡֵ + * + * ջԪأeա + */ +Status GetTop(SqStack S, SElemType* e) { + if(S.base == NULL || S.top == S.base) { + return ERROR; + } + + // ıջԪ + *e = *(S.top - 1); + + return OK; +} + +/* + * ջ + * + * Ԫeѹ뵽ջ + */ +Status Push(SqStack* S, SElemType e) { + if(S == NULL || (*S).base == NULL) { + return ERROR; + } + + // ջʱ׷Ӵ洢ռ + if((*S).top - (*S).base >= (*S).stacksize) { + (*S).base = (SElemType*) realloc((*S).base, ((*S).stacksize + STACKINCREMENT) * sizeof(SElemType)); + if((*S).base == NULL) { + exit(OVERFLOW); // 洢ʧ + } + + (*S).top = (*S).base + (*S).stacksize; + (*S).stacksize += STACKINCREMENT; + } + + // ջȸֵջָ + *(S->top++) = e; + + return OK; +} + +/* + * ջ + * + * ջԪصeա + */ +Status Pop(SqStack* S, SElemType* e) { + if(S == NULL || (*S).base == NULL) { + return ERROR; + } + + if((*S).top == (*S).base) { + return ERROR; + } + + // ջջָȵݼٸֵ + *e = *(--(*S).top); + + return OK; +} diff --git a/Dev-C++/ExerciseBook/04.14/SqStack.h b/Dev-C++/ExerciseBook/04.14/SqStack.h new file mode 100644 index 0000000..db29792 --- /dev/null +++ b/Dev-C++/ExerciseBook/04.14/SqStack.h @@ -0,0 +1,61 @@ +/*========================= + * ջ˳洢ṹ˳ջ + ==========================*/ + +#ifndef SQSTACK_H +#define SQSTACK_H + +#include +#include // ṩmallocreallocfreeexitԭ +#include "Status.h" //**01 **// +#include "String.h" //**04 **// + +/* 궨 */ +#define STACK_INIT_SIZE 100 // ˳ջ洢ռijʼ +#define STACKINCREMENT 10 // ˳ջ洢ռķ + +/* + * ˳ջԪͶ + * + *ע + * ԪΪַ + */ +typedef StringType SElemType; + +// ˳ջԪؽṹ +typedef struct { + SElemType* base; // ջָ + SElemType* top; // ջָ + int stacksize; // ǰѷĴ洢ռ䣬ԪΪλ +} SqStack; + + +/* + * ʼ + * + * һջʼɹ򷵻OK򷵻ERROR + */ +Status InitStack(SqStack* S); + +/* + * ȡֵ + * + * ջԪأeա + */ +Status GetTop(SqStack S, SElemType* e); + +/* + * ջ + * + * Ԫeѹ뵽ջ + */ +Status Push(SqStack* S, SElemType e); + +/* + * ջ + * + * ջԪصeա + */ +Status Pop(SqStack* S, SElemType* e); + +#endif diff --git a/Dev-C++/ExerciseBook/04.14/String.cpp b/Dev-C++/ExerciseBook/04.14/String.cpp new file mode 100644 index 0000000..41df51c --- /dev/null +++ b/Dev-C++/ExerciseBook/04.14/String.cpp @@ -0,0 +1,151 @@ +/*=========================== + * ϰ4.10~4.14ʹõַ + ============================*/ + +#include "String.h" + +// ʼһֵΪsĴt +void StrAssign(StringType* t, const char* s) { + if(s == NULL) { + *t = ""; + } + + *t = (char*) malloc((strlen(s) + 1) * sizeof(char)); + + strcpy(*t, s); +} + +// ȽϣstĴССһ£0 +int StrCompare(StringType s, StringType t) { + return strcmp(s, t); +} + +// ַsij +int StrLength(StringType s) { + return (int) strlen(s); +} + +// ӣstӺĴ +StringType Concat(StringType s, StringType t) { + StringType r; + + if(s == NULL) { + s = ""; + } + + if(t == NULL) { + t = ""; + } + + r = (char*) malloc((strlen(s) + strlen(t) + 1) * sizeof(char)); + r[0] = '\0'; + + strcat(r, s); + strcat(r, t); + + return r; +} + +// Ӵsstartλ𣬽ȡlenַ󷵻 +StringType SubString(StringType s, int start, int len) { + int n; + char* sub; + + n = (int) strlen(s); + + if(start < 1 || start > n || start + len - 1 > n || len < 0) { + return ""; + } + + sub = (char*) malloc((len + 1) * sizeof(char)); + strncpy(sub, s + start - 1, len); + sub[len] = '\0'; + + return sub; +} + +// ңsposλtҵλ +int Index(StringType s, StringType t, int pos) { + int m, n, i; + StringType sub; + + // ʧǰ + if(pos < 1 || pos > StrLength(s) || StrLength(t) == 0) { + return 0; + } + + n = StrLength(s); + m = StrLength(t); + i = pos; + + // ֤ȲԽ + while(i <= n - m + 1) { + // ȡS[i, i+m-1] + sub = SubString(s, i, m); + + // Ӵģʽƥ䣬Ҫƽ + if(StrCompare(sub, t) != 0) { + ++i; + } else { + return i; + } + } + + return 0; +} + +// 룺spost +Status StrInsert(StringType* s, int pos, StringType t) { + StringType r; + StringType s1, s2; + + if(pos < 1 || pos > StrLength(*s) + 1) { + return ERROR; + } + + r = (StringType) malloc((strlen(*s) + strlen(t) + 1) * sizeof(char)); + r[0] = '\0'; + + // ĴΪգǰ + if(StrLength(t) == 0) { + return OK; + } + + s1 = SubString(*s, 1, pos - 1); + s2 = SubString(*s, pos, (int) strlen(*s) - pos + 1); + + strcat(r, s1); + strcat(r, t); + strcat(r, s2); + + *s = r; + + return OK; +} + +// ɾsposλɾlenַ +Status StrDelete(StringType* s, int pos, int len) { + StringType r; + + if(pos < 1 || pos + len - 1 > StrLength(*s) || len < 0) { + return ERROR; + } + + // ɾijΪ0ǰ + if(len == 0) { + return OK; + } + + r = (StringType) malloc((StrLength(*s) - len + 1) * sizeof(char)); + strncpy(r, *s, pos - 1); + strcpy(r + pos - 1, *s + pos + len - 1); + + *s = r; + + return OK; +} + +// ַ +void StrPrint(StringType s) { + printf("%s\n", s); +} diff --git a/Dev-C++/ExerciseBook/04.14/String.h b/Dev-C++/ExerciseBook/04.14/String.h new file mode 100644 index 0000000..9d984af --- /dev/null +++ b/Dev-C++/ExerciseBook/04.14/String.h @@ -0,0 +1,43 @@ +/*=========================== + * ϰ4.10~4.14ʹõַ + ============================*/ + +#ifndef STRING_H +#define STRING_H + +#include +#include // ṩ strlen ԭ +#include "Status.h" //**01 **// + +/* ַ */ +typedef char* StringType; + + +// ʼһֵΪsĴt +void StrAssign(StringType* t, const char* s); + +// ȽϣstĴССһ£0 +int StrCompare(StringType s, StringType t); + +// ַsij +int StrLength(StringType s); + +// ӣstӺĴ +StringType Concat(StringType s, StringType t); + +// Ӵsstartλ𣬽ȡlenַ󷵻 +StringType SubString(StringType s, int start, int len); + +// ңsposλtҵλ +int Index(StringType s, StringType t, int pos); + +// 룺spost +Status StrInsert(StringType* s, int pos, StringType t); + +// ɾsposλɾlenַ +Status StrDelete(StringType* s, int pos, int len); + +// ַ +void StrPrint(StringType s); + +#endif diff --git a/Dev-C++/ExerciseBook/04.15-04.17/04.15-04.17.cpp b/Dev-C++/ExerciseBook/04.15-04.17/04.15-04.17.cpp new file mode 100644 index 0000000..0e74b14 --- /dev/null +++ b/Dev-C++/ExerciseBook/04.15-04.17/04.15-04.17.cpp @@ -0,0 +1,92 @@ +#include +#include "Status.h" //**01 **// +#include "SString.h" //**04 **// + +/* + * ʼStrAssign + * + *ע + * úSStringļж + */ +Status Algo_4_15(SString T, char* chars); + +/* + * ȽϣStrCompare + * + *ע + * úSStringļж + */ +int Algo_4_16(SString S, SString T); + +/* + * 滻Replace + * + *ע + * úSStringļж + */ +Status Algo_4_17(SString S, SString T, SString V); + + +int main(int argc, char* argv[]) { + char* t = "ab**c*de***fg"; + char* s = "ab**c*de***fh"; + SString T, S, M1, M2; + int i; + + printf(" 4.15 ֤...\n"); + Algo_4_15(T, t); + Algo_4_15(S, s); + printf("T = "); + StrPrint(T); + printf("S = "); + StrPrint(S); + + printf(" 4.16 ֤...\n"); + i = Algo_4_16(S, T); + if(i > 0) { + printf("S > T\n"); + } else if(i < 0) { + printf("S < T\n"); + } else { + printf("S == T\n"); + } + + printf(" 4.17 ֤...\n"); + Algo_4_15(M1, "**"); + Algo_4_15(M2, "^"); + Algo_4_17(S, M1, M2); + printf(" \"^\" 滻 \"**\" \nS = "); + StrPrint(S); + + return 0; +} + +/* + * ʼStrAssign + * + *ע + * úSStringļж + */ +Status Algo_4_15(SString T, char* chars) { + return StrAssign(T, chars); +} + +/* + * ȽϣStrCompare + * + *ע + * úSStringļж + */ +int Algo_4_16(SString S, SString T) { + return StrCompare(S, T); +} + +/* + * 滻Replace + * + *ע + * úSStringļж + */ +Status Algo_4_17(SString S, SString T, SString V) { + return Replace(S, T, V); +} diff --git a/Dev-C++/ExerciseBook/04.15-04.17/04.15-04.17.dev b/Dev-C++/ExerciseBook/04.15-04.17/04.15-04.17.dev new file mode 100644 index 0000000..a517d83 --- /dev/null +++ b/Dev-C++/ExerciseBook/04.15-04.17/04.15-04.17.dev @@ -0,0 +1,82 @@ +[Project] +FileName=04.15-04.17.dev +Name=04.15-04.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=04.15-04.17.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit2] +FileName=SString.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit3] +FileName=SString.h +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + diff --git a/Dev-C++/ExerciseBook/04.15-04.17/SString.cpp b/Dev-C++/ExerciseBook/04.15-04.17/SString.cpp new file mode 100644 index 0000000..fc4c757 --- /dev/null +++ b/Dev-C++/ExerciseBook/04.15-04.17/SString.cpp @@ -0,0 +1,406 @@ +/*============================= + * Ķ˳洢ʾ˳򴮣 + * + * 㷨: 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 DestroyString(SString S) { + 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; +} + +/* + * 㷨4.1 + * + * + * + * posʼģʽTS״γֵλãڣ򷵻0 + * ҳɹƥλá + * + *ע + * 1.ʵҪСӼ + * 2.ʵֱȽϵЧ + */ +int Index_1(SString S, SString T, int pos) { + int i, n, m; // ¼STij + SString sub; + + /* + * ʧǰ + * ̲д΢ͬ + */ + if(pos < 1 || pos > S[0] || StrEmpty(T)) { + return 0; + } + + n = StrLength(S); + m = StrLength(T); + i = pos; + + // ֤ȲԽ + while(i <= n - m + 1) { + // ȡS[i, i+m-1] + SubString(sub, S, i, m); + + // Ӵģʽƥ䣬Ҫƽ + if(StrCompare(sub, T) != 0) { + ++i; + } else { + return i; + } + } + + return 0; +} + +/* + * 㷨4.5 + * + * + * + * posʼģʽTS״γֵλãڣ򷵻0 + * ҳɹƥλá + * + *ע + * 1.ʵֲСӼ + * 2.ʵֱȽϵЧ + */ +int Index_2(SString S, SString T, int pos) { + int i = pos; + int j = 1; + + if(pos < 1 || pos > S[0] || StrEmpty(T)) { + return 0; + } + + while(i <= S[0] && j <= T[0]) { + // ַͬȽϺַ + if(S[i] == T[j]) { + i++; + j++; + + // ַͬαҪˣ±Ƚ + } else { + i = i - (j - 1) + 1; // j-1ͽ͵ǰj-1ԪأڵjԪϹһ + j = 1; // αjصTĵһλ + } + } + + // һT[0]>0ж + if(j > T[0] && T[0] > 0) { // TΪմ + return i - T[0]; // ƥɹ + } else { + return 0; + } +} + +/* + * + * + * T뵽Sposλô + */ +Status StrInsert(SString S, int pos, SString T) { + int i; + + if(pos < 1 || pos > S[0] + 1 || S[0] + T[0] > MAXSTRLEN) { + return ERROR; + } + + // ĴΪգǰ + if(StrEmpty(T)) { + return OK; + } + + // SڳλãΪT׼ + for(i = S[0]; i >= pos; i--) { + // ӺǰǰԪŲ + S[i + T[0]] = S[i]; + } + + // TSڳλ + for(i = pos; i <= pos + T[0] - 1; i++) { + S[i] = T[i - pos + 1]; + } + + // + S[0] += T[0]; + + 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; +} + +/* + * 滻 + * + * V滻SгֵTȵҲصӴ + * + *ע + * 1.òСӼ + * 2.ʵֱȽϵЧ + */ +Status Replace(SString S, SString T, SString V) { + int i; + + if(StrEmpty(S) || StrEmpty(T)) { + return ERROR; + } + + // SѰģʽTһγֵλ + i = Index_2(S, T, 1); + + // ƥַҿԱȫ滻滻 + while(i != 0 && S[0] - T[0] + V[0] <= MAXSTRLEN) { + StrDelete(S, i, StrLength(T)); // SɾT + StrInsert(S, i, V); // SвV + + i += StrLength(V); // iлһλ + + i = Index_2(S, T, i); // һƥַ + } + + if(i == 0) { // SеTȫ滻 + return OK; + } else { // STVѾ岻ȥ + return ERROR; + } +} + +/* + * 㷨4.2 + * + * + * + * S1S2洢TзءӺijֻδIJ֡ + * ֵʾӺĴǷ + * + *ע + * òСӼ + */ +Status Concat(SString T, SString S1, SString S2) { + int i; + int uncut; // ´Ƿ + + // ȫҪü + if(S1[0] + S2[0] <= MAXSTRLEN) { + // S1T + for(i = 1; i <= S1[0]; i++) { + T[i] = S1[i]; + } + + // S2T + for(i = S1[0] + 1; i <= S1[0] + S2[0]; i++) { + T[i] = S2[i - S1[0]]; + } + + // ³ + T[0] = S1[0] + S2[0]; + + // δü + uncut = TRUE; + + // ҪüS2 + } else if(S1[0] <= MAXSTRLEN) { + // S1T + for(i = 1; i <= S1[0]; i++) { + T[i] = S1[i]; + } + + // S2һָƵT + for(i = S1[0] + 1; i <= MAXSTRLEN; i++) { + T[i] = S2[i - S1[0]]; + } + + // ³ + T[0] = MAXSTRLEN; + + uncut = FALSE; + + // ֻҪS1һ + } else { + // ͬϢһ + for(i = 0; i <= MAXSTRLEN; i++) { + T[i] = S1[i]; + } + + uncut = FALSE; + } + + return uncut; +} + +// ӡַ +void StrPrint(SString S) { + int i; + + for(i = 1; i<=S[0] ; i++) { + printf("%c", S[i]); + } + + printf("\n"); +} diff --git a/Dev-C++/ExerciseBook/04.15-04.17/SString.h b/Dev-C++/ExerciseBook/04.15-04.17/SString.h new file mode 100644 index 0000000..386ffb8 --- /dev/null +++ b/Dev-C++/ExerciseBook/04.15-04.17/SString.h @@ -0,0 +1,179 @@ +/*============================= + * Ķ˳洢ʾ˳򴮣 + * + * 㷨: 4.14.24.34.5 + ==============================*/ + +#ifndef SSTRING_H +#define SSTRING_H + +#include +#include // ṩstrlenԭ +#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 DestroyString(SString S); + +/* + * + * + * 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); + +/* + * 㷨4.1 + * + * + * + * posʼģʽTS״γֵλãڣ򷵻0 + * ҳɹƥλá + * + *ע + * 1.ʵҪСӼ + * 2.ʵֱȽϵЧ + */ +int Index_1(SString S, SString T, int pos); + +/* + * 㷨4.5 + * + * + * + * posʼģʽTS״γֵλãڣ򷵻0 + * ҳɹƥλá + * + *ע + * 1.ʵֲСӼ + * 2.ʵֱȽϵЧ + */ +int Index_2(SString S, SString T, int pos); + +/* + * + * + * T뵽Sposλô + */ +Status StrInsert(SString S, int pos, SString T); + +/* + * ɾ + * + * ɾ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); + +/* + * 滻 + * + * V滻SгֵTȵҲصӴ + * + *ע + * òСӼЧʽϵ͡ + */ +Status Replace(SString S, SString T, SString V); + +/* + * 㷨4.2 + * + * + * + * S1S2洢TзءӺijֻδIJ֡ + * ֵʾӺĴǷ + * + *ע + * òСӼ + */ +Status Concat(SString T, SString S1, SString S2); + +// ӡַ +void StrPrint(SString S); + +#endif diff --git a/Dev-C++/ExerciseBook/04.18/04.18.cpp b/Dev-C++/ExerciseBook/04.18/04.18.cpp new file mode 100644 index 0000000..3e352c7 --- /dev/null +++ b/Dev-C++/ExerciseBook/04.18/04.18.cpp @@ -0,0 +1,62 @@ +#include +#include +#include "SString.h" //**04 **// + +/* + * ͳַSвַͬÿַĸͳƽ + */ +int* Algo_4_18(SString S); + + +int main(int argc, char* argv[]) { + char* s = "dbasydujhge638940[gptokljrsehgadcsbnmv,c.b'ng[p098437eywdghswqdecxvghju"; + SString S; + int* total; + int i; + + StrAssign(S, s); + printf("S = "); + StrPrint(S); + + total = Algo_4_18(S); + printf(" S вַͬ %d \n", total[0]); + for(i = 1; i <= 127; i++) { + if(total[i] != 0) { + printf("ַ \'%c\' %d .\n", i, total[i]); + } + } + printf("ͳ...\n"); + + return 0; +} + + +/* + * ͳַSвַͬÿַĸͳƽ + */ +int* Algo_4_18(SString S) { + int i; + int* total; + + /* + * totalΪ128 + * 0ŵԪ洢ַͬ + * Ԫ洢ֲַͬ + * + * עͳƿַ'\0' + */ + total = (int*) malloc(128 * sizeof(int)); + memset(total, 0, 128 * sizeof(int)); + + for(i = 1; i <= S[0]; i++) { + // ַͳƲַͬ + if(total[S[i]] == 0) { + total[0]++; + } + + // ͳַ + total[S[i]]++; + } + + return total; +} diff --git a/Dev-C++/ExerciseBook/04.18/04.18.dev b/Dev-C++/ExerciseBook/04.18/04.18.dev new file mode 100644 index 0000000..8178407 --- /dev/null +++ b/Dev-C++/ExerciseBook/04.18/04.18.dev @@ -0,0 +1,82 @@ +[Project] +FileName=04.18.dev +Name=04.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=SString.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit1] +FileName=04.18.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit3] +FileName=SString.h +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + diff --git a/Dev-C++/ExerciseBook/04.18/SString.cpp b/Dev-C++/ExerciseBook/04.18/SString.cpp new file mode 100644 index 0000000..fc4c757 --- /dev/null +++ b/Dev-C++/ExerciseBook/04.18/SString.cpp @@ -0,0 +1,406 @@ +/*============================= + * Ķ˳洢ʾ˳򴮣 + * + * 㷨: 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 DestroyString(SString S) { + 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; +} + +/* + * 㷨4.1 + * + * + * + * posʼģʽTS״γֵλãڣ򷵻0 + * ҳɹƥλá + * + *ע + * 1.ʵҪСӼ + * 2.ʵֱȽϵЧ + */ +int Index_1(SString S, SString T, int pos) { + int i, n, m; // ¼STij + SString sub; + + /* + * ʧǰ + * ̲д΢ͬ + */ + if(pos < 1 || pos > S[0] || StrEmpty(T)) { + return 0; + } + + n = StrLength(S); + m = StrLength(T); + i = pos; + + // ֤ȲԽ + while(i <= n - m + 1) { + // ȡS[i, i+m-1] + SubString(sub, S, i, m); + + // Ӵģʽƥ䣬Ҫƽ + if(StrCompare(sub, T) != 0) { + ++i; + } else { + return i; + } + } + + return 0; +} + +/* + * 㷨4.5 + * + * + * + * posʼģʽTS״γֵλãڣ򷵻0 + * ҳɹƥλá + * + *ע + * 1.ʵֲСӼ + * 2.ʵֱȽϵЧ + */ +int Index_2(SString S, SString T, int pos) { + int i = pos; + int j = 1; + + if(pos < 1 || pos > S[0] || StrEmpty(T)) { + return 0; + } + + while(i <= S[0] && j <= T[0]) { + // ַͬȽϺַ + if(S[i] == T[j]) { + i++; + j++; + + // ַͬαҪˣ±Ƚ + } else { + i = i - (j - 1) + 1; // j-1ͽ͵ǰj-1ԪأڵjԪϹһ + j = 1; // αjصTĵһλ + } + } + + // һT[0]>0ж + if(j > T[0] && T[0] > 0) { // TΪմ + return i - T[0]; // ƥɹ + } else { + return 0; + } +} + +/* + * + * + * T뵽Sposλô + */ +Status StrInsert(SString S, int pos, SString T) { + int i; + + if(pos < 1 || pos > S[0] + 1 || S[0] + T[0] > MAXSTRLEN) { + return ERROR; + } + + // ĴΪգǰ + if(StrEmpty(T)) { + return OK; + } + + // SڳλãΪT׼ + for(i = S[0]; i >= pos; i--) { + // ӺǰǰԪŲ + S[i + T[0]] = S[i]; + } + + // TSڳλ + for(i = pos; i <= pos + T[0] - 1; i++) { + S[i] = T[i - pos + 1]; + } + + // + S[0] += T[0]; + + 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; +} + +/* + * 滻 + * + * V滻SгֵTȵҲصӴ + * + *ע + * 1.òСӼ + * 2.ʵֱȽϵЧ + */ +Status Replace(SString S, SString T, SString V) { + int i; + + if(StrEmpty(S) || StrEmpty(T)) { + return ERROR; + } + + // SѰģʽTһγֵλ + i = Index_2(S, T, 1); + + // ƥַҿԱȫ滻滻 + while(i != 0 && S[0] - T[0] + V[0] <= MAXSTRLEN) { + StrDelete(S, i, StrLength(T)); // SɾT + StrInsert(S, i, V); // SвV + + i += StrLength(V); // iлһλ + + i = Index_2(S, T, i); // һƥַ + } + + if(i == 0) { // SеTȫ滻 + return OK; + } else { // STVѾ岻ȥ + return ERROR; + } +} + +/* + * 㷨4.2 + * + * + * + * S1S2洢TзءӺijֻδIJ֡ + * ֵʾӺĴǷ + * + *ע + * òСӼ + */ +Status Concat(SString T, SString S1, SString S2) { + int i; + int uncut; // ´Ƿ + + // ȫҪü + if(S1[0] + S2[0] <= MAXSTRLEN) { + // S1T + for(i = 1; i <= S1[0]; i++) { + T[i] = S1[i]; + } + + // S2T + for(i = S1[0] + 1; i <= S1[0] + S2[0]; i++) { + T[i] = S2[i - S1[0]]; + } + + // ³ + T[0] = S1[0] + S2[0]; + + // δü + uncut = TRUE; + + // ҪüS2 + } else if(S1[0] <= MAXSTRLEN) { + // S1T + for(i = 1; i <= S1[0]; i++) { + T[i] = S1[i]; + } + + // S2һָƵT + for(i = S1[0] + 1; i <= MAXSTRLEN; i++) { + T[i] = S2[i - S1[0]]; + } + + // ³ + T[0] = MAXSTRLEN; + + uncut = FALSE; + + // ֻҪS1һ + } else { + // ͬϢһ + for(i = 0; i <= MAXSTRLEN; i++) { + T[i] = S1[i]; + } + + uncut = FALSE; + } + + return uncut; +} + +// ӡַ +void StrPrint(SString S) { + int i; + + for(i = 1; i<=S[0] ; i++) { + printf("%c", S[i]); + } + + printf("\n"); +} diff --git a/Dev-C++/ExerciseBook/04.18/SString.h b/Dev-C++/ExerciseBook/04.18/SString.h new file mode 100644 index 0000000..386ffb8 --- /dev/null +++ b/Dev-C++/ExerciseBook/04.18/SString.h @@ -0,0 +1,179 @@ +/*============================= + * Ķ˳洢ʾ˳򴮣 + * + * 㷨: 4.14.24.34.5 + ==============================*/ + +#ifndef SSTRING_H +#define SSTRING_H + +#include +#include // ṩstrlenԭ +#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 DestroyString(SString S); + +/* + * + * + * 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); + +/* + * 㷨4.1 + * + * + * + * posʼģʽTS״γֵλãڣ򷵻0 + * ҳɹƥλá + * + *ע + * 1.ʵҪСӼ + * 2.ʵֱȽϵЧ + */ +int Index_1(SString S, SString T, int pos); + +/* + * 㷨4.5 + * + * + * + * posʼģʽTS״γֵλãڣ򷵻0 + * ҳɹƥλá + * + *ע + * 1.ʵֲСӼ + * 2.ʵֱȽϵЧ + */ +int Index_2(SString S, SString T, int pos); + +/* + * + * + * T뵽Sposλô + */ +Status StrInsert(SString S, int pos, SString T); + +/* + * ɾ + * + * ɾ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); + +/* + * 滻 + * + * V滻SгֵTȵҲصӴ + * + *ע + * òСӼЧʽϵ͡ + */ +Status Replace(SString S, SString T, SString V); + +/* + * 㷨4.2 + * + * + * + * S1S2洢TзءӺijֻδIJ֡ + * ֵʾӺĴǷ + * + *ע + * òСӼ + */ +Status Concat(SString T, SString S1, SString S2); + +// ӡַ +void StrPrint(SString S); + +#endif diff --git a/Dev-C++/ExerciseBook/04.19/04.19.cpp b/Dev-C++/ExerciseBook/04.19/04.19.cpp new file mode 100644 index 0000000..9a2dbf0 --- /dev/null +++ b/Dev-C++/ExerciseBook/04.19/04.19.cpp @@ -0,0 +1,77 @@ +#include +#include +#include "SString.h" //**04 **// + +/* + * R=S-STa洢RÿַSеһγֵλ + * + * עa0ŵԪ洢aԪصĸ + */ +void Algo_4_19(SString R, SString S, SString T, int** a); + + +int main(int argc, char* argv[]) { + char* s = "amdhcjgfdlpinbefcopgkqikeb"; + char* t = "mhjlpinopkqik"; + int* a; + SString T, S, R; + int i; + + printf("ʼST...\n"); + StrAssign(S, s); + StrAssign(T, t); + + printf("S = "); + StrPrint(S); + printf("T = "); + StrPrint(T); + + Algo_4_19(R, S, T, &a); + printf("R = "); + StrPrint(R); + printf("a = "); + for(i = 1; i <= a[0]; i++) { + printf("%d ", a[i]); + } + printf("\n"); + + return 0; +} + + +/* + * R=S-STa洢RÿַSеһγֵλ + * + * עa0ŵԪ洢aԪصĸ + */ +void Algo_4_19(SString R, SString S, SString T, int** a) { + int i, p; + SString ch; + + *a = (int*) malloc((StrLength(S) + 1) * sizeof(int)); + + StrAssign(R, ""); + + for(i = 1, (*a)[0] = 0; i <= StrLength(S); i++) { + // ȡַж + SubString(ch, S, i, 1); + + // ȡS[i]Tеλ + p = Index_2(T, ch, 1); + + // S[i]T + if(p == 0) { + // ȡS[i]Rеλ + p = Index_2(R, ch, 1); + } + + // S[i]ȲTУûRгֹ + if(p == 0) { + (*a)[0]++; + (*a)[(*a)[0]] = i; + + // RS[i] + StrInsert(R, (*a)[0], ch); + } + } +} diff --git a/Dev-C++/ExerciseBook/04.19/04.19.dev b/Dev-C++/ExerciseBook/04.19/04.19.dev new file mode 100644 index 0000000..ef0f901 --- /dev/null +++ b/Dev-C++/ExerciseBook/04.19/04.19.dev @@ -0,0 +1,82 @@ +[Project] +FileName=04.19.dev +Name=04.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 + +[Unit2] +FileName=SString.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit1] +FileName=04.19.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit3] +FileName=SString.h +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + diff --git a/Dev-C++/ExerciseBook/04.19/SString.cpp b/Dev-C++/ExerciseBook/04.19/SString.cpp new file mode 100644 index 0000000..fc4c757 --- /dev/null +++ b/Dev-C++/ExerciseBook/04.19/SString.cpp @@ -0,0 +1,406 @@ +/*============================= + * Ķ˳洢ʾ˳򴮣 + * + * 㷨: 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 DestroyString(SString S) { + 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; +} + +/* + * 㷨4.1 + * + * + * + * posʼģʽTS״γֵλãڣ򷵻0 + * ҳɹƥλá + * + *ע + * 1.ʵҪСӼ + * 2.ʵֱȽϵЧ + */ +int Index_1(SString S, SString T, int pos) { + int i, n, m; // ¼STij + SString sub; + + /* + * ʧǰ + * ̲д΢ͬ + */ + if(pos < 1 || pos > S[0] || StrEmpty(T)) { + return 0; + } + + n = StrLength(S); + m = StrLength(T); + i = pos; + + // ֤ȲԽ + while(i <= n - m + 1) { + // ȡS[i, i+m-1] + SubString(sub, S, i, m); + + // Ӵģʽƥ䣬Ҫƽ + if(StrCompare(sub, T) != 0) { + ++i; + } else { + return i; + } + } + + return 0; +} + +/* + * 㷨4.5 + * + * + * + * posʼģʽTS״γֵλãڣ򷵻0 + * ҳɹƥλá + * + *ע + * 1.ʵֲСӼ + * 2.ʵֱȽϵЧ + */ +int Index_2(SString S, SString T, int pos) { + int i = pos; + int j = 1; + + if(pos < 1 || pos > S[0] || StrEmpty(T)) { + return 0; + } + + while(i <= S[0] && j <= T[0]) { + // ַͬȽϺַ + if(S[i] == T[j]) { + i++; + j++; + + // ַͬαҪˣ±Ƚ + } else { + i = i - (j - 1) + 1; // j-1ͽ͵ǰj-1ԪأڵjԪϹһ + j = 1; // αjصTĵһλ + } + } + + // һT[0]>0ж + if(j > T[0] && T[0] > 0) { // TΪմ + return i - T[0]; // ƥɹ + } else { + return 0; + } +} + +/* + * + * + * T뵽Sposλô + */ +Status StrInsert(SString S, int pos, SString T) { + int i; + + if(pos < 1 || pos > S[0] + 1 || S[0] + T[0] > MAXSTRLEN) { + return ERROR; + } + + // ĴΪգǰ + if(StrEmpty(T)) { + return OK; + } + + // SڳλãΪT׼ + for(i = S[0]; i >= pos; i--) { + // ӺǰǰԪŲ + S[i + T[0]] = S[i]; + } + + // TSڳλ + for(i = pos; i <= pos + T[0] - 1; i++) { + S[i] = T[i - pos + 1]; + } + + // + S[0] += T[0]; + + 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; +} + +/* + * 滻 + * + * V滻SгֵTȵҲصӴ + * + *ע + * 1.òСӼ + * 2.ʵֱȽϵЧ + */ +Status Replace(SString S, SString T, SString V) { + int i; + + if(StrEmpty(S) || StrEmpty(T)) { + return ERROR; + } + + // SѰģʽTһγֵλ + i = Index_2(S, T, 1); + + // ƥַҿԱȫ滻滻 + while(i != 0 && S[0] - T[0] + V[0] <= MAXSTRLEN) { + StrDelete(S, i, StrLength(T)); // SɾT + StrInsert(S, i, V); // SвV + + i += StrLength(V); // iлһλ + + i = Index_2(S, T, i); // һƥַ + } + + if(i == 0) { // SеTȫ滻 + return OK; + } else { // STVѾ岻ȥ + return ERROR; + } +} + +/* + * 㷨4.2 + * + * + * + * S1S2洢TзءӺijֻδIJ֡ + * ֵʾӺĴǷ + * + *ע + * òСӼ + */ +Status Concat(SString T, SString S1, SString S2) { + int i; + int uncut; // ´Ƿ + + // ȫҪü + if(S1[0] + S2[0] <= MAXSTRLEN) { + // S1T + for(i = 1; i <= S1[0]; i++) { + T[i] = S1[i]; + } + + // S2T + for(i = S1[0] + 1; i <= S1[0] + S2[0]; i++) { + T[i] = S2[i - S1[0]]; + } + + // ³ + T[0] = S1[0] + S2[0]; + + // δü + uncut = TRUE; + + // ҪüS2 + } else if(S1[0] <= MAXSTRLEN) { + // S1T + for(i = 1; i <= S1[0]; i++) { + T[i] = S1[i]; + } + + // S2һָƵT + for(i = S1[0] + 1; i <= MAXSTRLEN; i++) { + T[i] = S2[i - S1[0]]; + } + + // ³ + T[0] = MAXSTRLEN; + + uncut = FALSE; + + // ֻҪS1һ + } else { + // ͬϢһ + for(i = 0; i <= MAXSTRLEN; i++) { + T[i] = S1[i]; + } + + uncut = FALSE; + } + + return uncut; +} + +// ӡַ +void StrPrint(SString S) { + int i; + + for(i = 1; i<=S[0] ; i++) { + printf("%c", S[i]); + } + + printf("\n"); +} diff --git a/Dev-C++/ExerciseBook/04.19/SString.h b/Dev-C++/ExerciseBook/04.19/SString.h new file mode 100644 index 0000000..386ffb8 --- /dev/null +++ b/Dev-C++/ExerciseBook/04.19/SString.h @@ -0,0 +1,179 @@ +/*============================= + * Ķ˳洢ʾ˳򴮣 + * + * 㷨: 4.14.24.34.5 + ==============================*/ + +#ifndef SSTRING_H +#define SSTRING_H + +#include +#include // ṩstrlenԭ +#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 DestroyString(SString S); + +/* + * + * + * 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); + +/* + * 㷨4.1 + * + * + * + * posʼģʽTS״γֵλãڣ򷵻0 + * ҳɹƥλá + * + *ע + * 1.ʵҪСӼ + * 2.ʵֱȽϵЧ + */ +int Index_1(SString S, SString T, int pos); + +/* + * 㷨4.5 + * + * + * + * posʼģʽTS״γֵλãڣ򷵻0 + * ҳɹƥλá + * + *ע + * 1.ʵֲСӼ + * 2.ʵֱȽϵЧ + */ +int Index_2(SString S, SString T, int pos); + +/* + * + * + * T뵽Sposλô + */ +Status StrInsert(SString S, int pos, SString T); + +/* + * ɾ + * + * ɾ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); + +/* + * 滻 + * + * V滻SгֵTȵҲصӴ + * + *ע + * òСӼЧʽϵ͡ + */ +Status Replace(SString S, SString T, SString V); + +/* + * 㷨4.2 + * + * + * + * S1S2洢TзءӺijֻδIJ֡ + * ֵʾӺĴǷ + * + *ע + * òСӼ + */ +Status Concat(SString T, SString S1, SString S2); + +// ӡַ +void StrPrint(SString S); + +#endif diff --git a/Dev-C++/ExerciseBook/04.20/04.20.cpp b/Dev-C++/ExerciseBook/04.20/04.20.cpp new file mode 100644 index 0000000..0a839aa --- /dev/null +++ b/Dev-C++/ExerciseBook/04.20/04.20.cpp @@ -0,0 +1,47 @@ +#include +#include "Status.h" //**01 **// +#include "SString.h" //**04 **// + +/* + * ɾSаT + */ +Status Algo_4_20(SString S, SString T); + + +int main(int argc, char* argv[]) { + char* s = "----***--*-**-****-*****-----"; + char* t = "**"; + SString T, S; + + printf("ɾǰ...\n"); + StrAssign(S, s); + StrAssign(T, t); + printf("S = "); + StrPrint(S); + printf("T = "); + StrPrint(T); + + printf("ɾ...\n"); + printf("S = "); + Algo_4_20(S, T); + StrPrint(S); + + return 0; +} + + +/* + * ɾSаT + */ +Status Algo_4_20(SString S, SString T) { + int i; + + // SвTҵɾ + while((i = Index_2(S, T, 1)) != 0) { + if(StrDelete(S, i, StrLength(T)) == ERROR) { + return ERROR; + } + } + + return OK; +} diff --git a/Dev-C++/ExerciseBook/04.20/04.20.dev b/Dev-C++/ExerciseBook/04.20/04.20.dev new file mode 100644 index 0000000..f480545 --- /dev/null +++ b/Dev-C++/ExerciseBook/04.20/04.20.dev @@ -0,0 +1,82 @@ +[Project] +FileName=04.20.dev +Name=04.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 + +[Unit2] +FileName=SString.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit1] +FileName=04.20.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit3] +FileName=SString.h +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + diff --git a/Dev-C++/ExerciseBook/04.20/SString.cpp b/Dev-C++/ExerciseBook/04.20/SString.cpp new file mode 100644 index 0000000..fc4c757 --- /dev/null +++ b/Dev-C++/ExerciseBook/04.20/SString.cpp @@ -0,0 +1,406 @@ +/*============================= + * Ķ˳洢ʾ˳򴮣 + * + * 㷨: 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 DestroyString(SString S) { + 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; +} + +/* + * 㷨4.1 + * + * + * + * posʼģʽTS״γֵλãڣ򷵻0 + * ҳɹƥλá + * + *ע + * 1.ʵҪСӼ + * 2.ʵֱȽϵЧ + */ +int Index_1(SString S, SString T, int pos) { + int i, n, m; // ¼STij + SString sub; + + /* + * ʧǰ + * ̲д΢ͬ + */ + if(pos < 1 || pos > S[0] || StrEmpty(T)) { + return 0; + } + + n = StrLength(S); + m = StrLength(T); + i = pos; + + // ֤ȲԽ + while(i <= n - m + 1) { + // ȡS[i, i+m-1] + SubString(sub, S, i, m); + + // Ӵģʽƥ䣬Ҫƽ + if(StrCompare(sub, T) != 0) { + ++i; + } else { + return i; + } + } + + return 0; +} + +/* + * 㷨4.5 + * + * + * + * posʼģʽTS״γֵλãڣ򷵻0 + * ҳɹƥλá + * + *ע + * 1.ʵֲСӼ + * 2.ʵֱȽϵЧ + */ +int Index_2(SString S, SString T, int pos) { + int i = pos; + int j = 1; + + if(pos < 1 || pos > S[0] || StrEmpty(T)) { + return 0; + } + + while(i <= S[0] && j <= T[0]) { + // ַͬȽϺַ + if(S[i] == T[j]) { + i++; + j++; + + // ַͬαҪˣ±Ƚ + } else { + i = i - (j - 1) + 1; // j-1ͽ͵ǰj-1ԪأڵjԪϹһ + j = 1; // αjصTĵһλ + } + } + + // һT[0]>0ж + if(j > T[0] && T[0] > 0) { // TΪմ + return i - T[0]; // ƥɹ + } else { + return 0; + } +} + +/* + * + * + * T뵽Sposλô + */ +Status StrInsert(SString S, int pos, SString T) { + int i; + + if(pos < 1 || pos > S[0] + 1 || S[0] + T[0] > MAXSTRLEN) { + return ERROR; + } + + // ĴΪգǰ + if(StrEmpty(T)) { + return OK; + } + + // SڳλãΪT׼ + for(i = S[0]; i >= pos; i--) { + // ӺǰǰԪŲ + S[i + T[0]] = S[i]; + } + + // TSڳλ + for(i = pos; i <= pos + T[0] - 1; i++) { + S[i] = T[i - pos + 1]; + } + + // + S[0] += T[0]; + + 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; +} + +/* + * 滻 + * + * V滻SгֵTȵҲصӴ + * + *ע + * 1.òСӼ + * 2.ʵֱȽϵЧ + */ +Status Replace(SString S, SString T, SString V) { + int i; + + if(StrEmpty(S) || StrEmpty(T)) { + return ERROR; + } + + // SѰģʽTһγֵλ + i = Index_2(S, T, 1); + + // ƥַҿԱȫ滻滻 + while(i != 0 && S[0] - T[0] + V[0] <= MAXSTRLEN) { + StrDelete(S, i, StrLength(T)); // SɾT + StrInsert(S, i, V); // SвV + + i += StrLength(V); // iлһλ + + i = Index_2(S, T, i); // һƥַ + } + + if(i == 0) { // SеTȫ滻 + return OK; + } else { // STVѾ岻ȥ + return ERROR; + } +} + +/* + * 㷨4.2 + * + * + * + * S1S2洢TзءӺijֻδIJ֡ + * ֵʾӺĴǷ + * + *ע + * òСӼ + */ +Status Concat(SString T, SString S1, SString S2) { + int i; + int uncut; // ´Ƿ + + // ȫҪü + if(S1[0] + S2[0] <= MAXSTRLEN) { + // S1T + for(i = 1; i <= S1[0]; i++) { + T[i] = S1[i]; + } + + // S2T + for(i = S1[0] + 1; i <= S1[0] + S2[0]; i++) { + T[i] = S2[i - S1[0]]; + } + + // ³ + T[0] = S1[0] + S2[0]; + + // δü + uncut = TRUE; + + // ҪüS2 + } else if(S1[0] <= MAXSTRLEN) { + // S1T + for(i = 1; i <= S1[0]; i++) { + T[i] = S1[i]; + } + + // S2һָƵT + for(i = S1[0] + 1; i <= MAXSTRLEN; i++) { + T[i] = S2[i - S1[0]]; + } + + // ³ + T[0] = MAXSTRLEN; + + uncut = FALSE; + + // ֻҪS1һ + } else { + // ͬϢһ + for(i = 0; i <= MAXSTRLEN; i++) { + T[i] = S1[i]; + } + + uncut = FALSE; + } + + return uncut; +} + +// ӡַ +void StrPrint(SString S) { + int i; + + for(i = 1; i<=S[0] ; i++) { + printf("%c", S[i]); + } + + printf("\n"); +} diff --git a/Dev-C++/ExerciseBook/04.20/SString.h b/Dev-C++/ExerciseBook/04.20/SString.h new file mode 100644 index 0000000..386ffb8 --- /dev/null +++ b/Dev-C++/ExerciseBook/04.20/SString.h @@ -0,0 +1,179 @@ +/*============================= + * Ķ˳洢ʾ˳򴮣 + * + * 㷨: 4.14.24.34.5 + ==============================*/ + +#ifndef SSTRING_H +#define SSTRING_H + +#include +#include // ṩstrlenԭ +#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 DestroyString(SString S); + +/* + * + * + * 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); + +/* + * 㷨4.1 + * + * + * + * posʼģʽTS״γֵλãڣ򷵻0 + * ҳɹƥλá + * + *ע + * 1.ʵҪСӼ + * 2.ʵֱȽϵЧ + */ +int Index_1(SString S, SString T, int pos); + +/* + * 㷨4.5 + * + * + * + * posʼģʽTS״γֵλãڣ򷵻0 + * ҳɹƥλá + * + *ע + * 1.ʵֲСӼ + * 2.ʵֱȽϵЧ + */ +int Index_2(SString S, SString T, int pos); + +/* + * + * + * T뵽Sposλô + */ +Status StrInsert(SString S, int pos, SString T); + +/* + * ɾ + * + * ɾ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); + +/* + * 滻 + * + * V滻SгֵTȵҲصӴ + * + *ע + * òСӼЧʽϵ͡ + */ +Status Replace(SString S, SString T, SString V); + +/* + * 㷨4.2 + * + * + * + * S1S2洢TзءӺijֻδIJ֡ + * ֵʾӺĴǷ + * + *ע + * òСӼ + */ +Status Concat(SString T, SString S1, SString S2); + +// ӡַ +void StrPrint(SString S); + +#endif diff --git a/Dev-C++/ExerciseBook/04.21/04.21.cpp b/Dev-C++/ExerciseBook/04.21/04.21.cpp new file mode 100644 index 0000000..c9a2ab7 --- /dev/null +++ b/Dev-C++/ExerciseBook/04.21/04.21.cpp @@ -0,0 +1,336 @@ +#include +#include // ṩ mallocreallocfreeexit ԭ +#include +#include "Status.h" //**01 **// + +/* + * ԪͶ + * + *ע + * ȻַԪȻintԭǣ + * 1.Ҫͷ洢intֱchar + * 2.charintݣԽȻintҲ洢char + */ +typedef int ElemType; + +/* + * ṹ + * + * עĵͷ + */ +typedef struct SNode { + ElemType data; // ݽ + struct SNode* next; // ָһָ +} SNode; + +// ָָ룬ַ +typedef SNode* String; + + +/* + * ʼ + * + * һֵΪcharsĴT + */ +Status StrAssign_4_21(String* S, char* chars); + +/* + * + * + * SƵT + */ +Status StrCopy_4_21(String* S, String T); + +/* + * Ƚ + * + * ȽϴSʹTرȽϽ + */ +int StrCompare_4_21(String S, String T); + +/* + * + * + * شSԪصĸ + */ +int StrLength_4_21(String S); + +/* + * + * + * S1S2洢TзءӺijֻδIJ֡ + * ֵʾӺĴǷ + */ +Status Concat_4_21(String* R, String S1, String S2); + +/* + * Ӵ + * + * SubS[pos, pos+len-1] + * ֵָʾǷȡɹ + */ +Status SubString_4_21(String* Sub, String S, int pos, int len); + +// ַ +void StrPrint_4_21(String S); + + +int main(int argc, char* argv[]) { + char* chars = "0123456789"; + String S, T; + int i; + + printf(" StrAssign \n"); + { + printf(" Ϊ˳ S ֵ...\n"); + StrAssign_4_21(&S, chars); + printf(" S = "); + StrPrint_4_21(S); + } + PressEnterToContinue(); + + printf(" StrLength \n"); + { + i = StrLength_4_21(S); + printf(" S ijΪ %d \n", i); + } + PressEnterToContinue(); + + printf(" StrCopy \n"); + { + printf(" S T ...\n"); + StrCopy_4_21(&T, S); + printf(" T = "); + StrPrint_4_21(T); + } + PressEnterToContinue(); + + printf(" StrCompare \n"); + { + printf(" Ƚַ S T ...\n"); + i = StrCompare_4_21(S, T); + i == 0 ? printf(" S==T\n") : (i < 0 ? printf(" ST\n")); + } + PressEnterToContinue(); + + printf(" SubString \n"); + { + String Sub; + + printf(" Sub S е 6 ַ 5 ַ...\n"); + SubString_4_21(&Sub, S, 6, 5); + printf(" Sub = "); + StrPrint_4_21(Sub); + } + PressEnterToContinue(); + + + printf(" Concat \n"); + { + String Tmp, S1, S2; + + StrAssign_4_21(&S1, "+++++"); + StrAssign_4_21(&S2, "-----"); + + printf(" \"+++++\" \"-----\" γ Tmp ...\n"); + Concat_4_21(&Tmp, S1, S2); + printf(" Tmp = "); + StrPrint_4_21(Tmp); + } + PressEnterToContinue(); + + return 0; +} + + +/* + * ʼ + * + * һֵΪcharsĴT + */ +Status StrAssign_4_21(String* S, char* chars) { + int i, len; + String p; + + if(S == NULL || chars == NULL) { + return ERROR; + } + + len = (int) strlen(chars); + + *S = (SNode*) malloc(sizeof(SNode)); + (*S)->data = len; + + p = *S; + + for(i = 0; i < len; i++) { + p->next = (SNode*) malloc(sizeof(SNode)); + p->next->data = chars[i]; + p = p->next; + } + + p->next = NULL; + + return OK; +} + +/* + * + * + * SƵT + */ +Status StrCopy_4_21(String* S, String T) { + String p, r, t; + + if(S == NULL || T == NULL) { + return ERROR; + } + + for(t = T; t != NULL; t = t->next) { + r = (SNode*) malloc(sizeof(SNode)); + r->data = t->data; + + if(t == T) { + *S = r; + p = r; + } else { + p->next = r; + p = p->next; + } + } + + p->next = NULL; + + return OK; +} + +/* + * Ƚ + * + * ȽϴSʹTرȽϽ + */ +int StrCompare_4_21(String S, String T) { + String s, t; + + if(S == NULL || T == NULL) { + return StrLength_4_21(S) - StrLength_4_21(T); + } + + s = S->next; + t = T->next; + + while(s != NULL && t != NULL) { + if(s->data != t->data) { + return s->data - t->data; + } + + s = s->next; + t = t->next; + } + + if(s == NULL && t != NULL) { + return -1; + } else if(s != NULL && t == NULL) { + return 1; + } else { + return 0; + } +} + +/* + * + * + * شSԪصĸ + */ +int StrLength_4_21(String S) { + return S == NULL ? 0 : S->data; +} + +/* + * + * + * S1S2洢TзءӺijֻδIJ֡ + * ֵʾӺĴǷ + */ +Status Concat_4_21(String* R, String S1, String S2) { + String r, s, p; + + if(R == NULL || S1 == NULL || S2 == NULL) { + return ERROR; + } + + *R = (SNode*) malloc(sizeof(SNode)); + (*R)->data = S1->data + S2->data; + + r = *R; + + for(s = S1->next; s != NULL; s = s->next) { + p = (SNode*) malloc(sizeof(SNode)); + p->data = s->data; + r->next = p; + r = r->next; + } + + for(s = S2->next; s != NULL; s = s->next) { + p = (SNode*) malloc(sizeof(SNode)); + p->data = s->data; + r->next = p; + r = r->next; + } + + r->next = NULL; + + return OK; +} + +/* + * Ӵ + * + * SubS[pos, pos+len-1] + * ֵָʾǷȡɹ + */ +Status SubString_4_21(String* Sub, String S, int pos, int len) { + int i, slen; + String sub, s, p; + + slen = StrLength_4_21(S); + + if(Sub == NULL || S == NULL || pos < 1 || pos > slen || len < 0 || pos + len - 1 > slen) { + return ERROR; + } + + *Sub = (SNode*) malloc(sizeof(SNode)); + (*Sub)->data = len; + + for(i = 0, s = S; i < pos; i++, s = s->next) { + // ҵpos㣬sָ + } + + sub = *Sub; + + for(i = 0; i < len; i++) { + sub->next = (SNode*) malloc(sizeof(SNode)); + sub->next->data = s->data; + sub = sub->next; + + s = s->next; + } + + sub->next = NULL; + + return OK; +} + +// ַ +void StrPrint_4_21(String S) { + String p; + + if(S == NULL) { + return; + } + + for(p = S->next; p != NULL; p = p->next) { + printf("%c", p->data); + } + printf("\n"); +} diff --git a/Dev-C++/ExerciseBook/04.21/04.21.dev b/Dev-C++/ExerciseBook/04.21/04.21.dev new file mode 100644 index 0000000..1237973 --- /dev/null +++ b/Dev-C++/ExerciseBook/04.21/04.21.dev @@ -0,0 +1,62 @@ +[Project] +FileName=04.21.dev +Name=04.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=1 + +[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=04.21.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + diff --git a/Dev-C++/ExerciseBook/04.22/04.22.cpp b/Dev-C++/ExerciseBook/04.22/04.22.cpp new file mode 100644 index 0000000..e493de2 --- /dev/null +++ b/Dev-C++/ExerciseBook/04.22/04.22.cpp @@ -0,0 +1,59 @@ +#include +#include "LString.h" //**04 **// + +/* + * S뵽Tеַc֮ + * жcS뵽ұTʱ׸c֮ + * TڲcS뵽Tĩβ + */ +void Algo_4_22(LString* T, char ch, LString S); + + +int main(int argc, char* argv[]) { + char* t = "----***--*-**-**^**-*****-----"; + char* s = "12345"; + char ch = '^'; + LString T, S; + + StrAssign(&T, t); + StrAssign(&S, s); + printf("T = "); + StrPrint(T); + printf("S = "); + StrPrint(S); + + Algo_4_22(&T, ch, S); + printf("T = "); + StrPrint(T); + + return 0; +} + + +/* + * S뵽Tеַc֮ + * жcS뵽ұTʱ׸c֮ + * TڲcS뵽Tĩβ + */ +void Algo_4_22(LString* T, char c, LString S) { + int i; + char tmp[2]; + LString Tmp; + + // Ŀ괮 + tmp[0] = c; + tmp[1] = '\0'; + StrAssign(&Tmp, tmp); + + // ѰַcTеλ + i = Index((*T), Tmp, 1); + + // ҵcS뵽ַc֮ + if(i != 0) { + StrInsert(T, i + 1, S); + + // ûҵcS뵽Tĩβ + } else { + StrInsert(T, (*T).curlen + 1, S); + } +} diff --git a/Dev-C++/ExerciseBook/04.22/04.22.dev b/Dev-C++/ExerciseBook/04.22/04.22.dev new file mode 100644 index 0000000..ed5a78a --- /dev/null +++ b/Dev-C++/ExerciseBook/04.22/04.22.dev @@ -0,0 +1,82 @@ +[Project] +FileName=04.22.dev +Name=04.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=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=LString.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit1] +FileName=04.22.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit3] +FileName=LString.h +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + diff --git a/Dev-C++/ExerciseBook/04.22/LString.cpp b/Dev-C++/ExerciseBook/04.22/LString.cpp new file mode 100644 index 0000000..954ac09 --- /dev/null +++ b/Dev-C++/ExerciseBook/04.22/LString.cpp @@ -0,0 +1,747 @@ +/*============================= + * Ŀ洢ʾ + ==============================*/ + +#include "LString.h" //**04 **// + +/* + * ʼ + * + * һֵΪcharsĴT + * + *ע + * òСӼ + */ +Status StrAssign(LString* T, const char* chars) { + int len; // charsij + int i, count; // ַcharsα + int m; // ܿ + int n; // δĿ飬洢ÿеЧԪ + Chunk* r; + + // charsij + len = (int) strlen(chars); + + // ûЧԪ + if(len == 0) { + (*T).head = NULL; + (*T).tail = NULL; + (*T).curlen = 0; + + return OK; + } + + m = len / CHUNKSIZE; // ȼҪĿ + n = len % CHUNKSIZE; // δĿ飬ÿЧԪ + if(n != 0) { + m++; // ܿ + } + + // 1.Ľṹ + for(i = 1; i <= m; i++) { + // ¿ + r = (Chunk*) malloc(sizeof(Chunk)); + if(r == NULL) { + exit(OVERFLOW); + } + r->next = NULL; + + // һ + if(i == 1) { + (*T).head = (*T).tail = r; + + // ӺĿ + } else { + (*T).tail->next = r; + (*T).tail = r; + } + } + + r = (*T).head; + i = 0; // Tα + count = 0; // ͳƱԪأ˳Ϊcharsα + + // 2.Ϊ + while(count < len) { + r->ch[i] = chars[count]; + + i = (i + 1) % CHUNKSIZE; + if(i == 0) { + r = r->next; // ָһ + } + + count++; + } + + // 3.δĿ + if(n != 0) { + // Ǵֵ('\0') + while(i < CHUNKSIZE) { + (*T).tail->ch[i] = '\0'; + i++; + } + } + + // 4.¼Ϣ + (*T).curlen = len; + + return OK; +} + +/* + * + * + *ע + * Ľṹ٣ٲ + */ +Status DestroyString(LString* S) { + return OK; +} + +/* + * + * + * Sա + */ +Status ClearString(LString* S) { + Chunk* p, * q; + + p = (*S).head; + + // ͷдռõĿռ + while(p != NULL) { + q = p->next; + free(p); + p = q; + } + + (*S).head = NULL; + (*S).tail = NULL; + (*S).curlen = 0; + + return OK; +} + +/* + * п + * + * жϴSǷЧݡ + * + * ֵ + * TRUE : SΪ + * FALSE: SΪ + */ +Status StrEmpty(LString S) { + return S.curlen == 0 ? TRUE : FALSE; +} + +/* + * + * + * شSԪصĸ + * + *ע + * òСӼ + */ +int StrLength(LString S) { + return S.curlen; +} + +/* + * Ӵ + * + * SubS[pos, pos+len-1] + * ֵָʾǷȡɹ + * + *ע + * òСӼ + */ +Status SubString(LString* Sub, LString S, int pos, int len) { + int m; // Subܿ + int n; // SubδĿ飬洢ÿеЧԪ + int i, j, count; + Chunk* r, * p; + + if(pos < 1 || pos > S.curlen || len < 0 || pos + len - 1 > S.curlen) { + return ERROR; + } + + // ǽȡ0ַҪռ + if(len == 0) { + (*Sub).head = NULL; + (*Sub).tail = NULL; + (*Sub).curlen = 0; + + return OK; + } + + m = len / CHUNKSIZE; // ȼҪĿ + n = len % CHUNKSIZE; // SubδĿ飬ÿЧԪ + if(n != 0) { + m++; // Subܿ + } + + // 1.SubĽṹ + for(i = 1; i <= m; i++) { + // ¿ + r = (Chunk*) malloc(sizeof(Chunk)); + if(r == NULL) { + exit(OVERFLOW); + } + r->next = NULL; + + // һ + if(i == 1) { + (*Sub).head = (*Sub).tail = r; + + // ӺĿ + } else { + (*Sub).tail->next = r; + (*Sub).tail = r; + } + } + + // SеposԪڵĿ飬ָpָ + for(count = 1, p = S.head; pos > count * CHUNKSIZE; count++, p = p->next) { + // ѭ + } + + r = (*Sub).head; // ָSubĿ + + i = 0; // Subα + j = (pos - 1) % CHUNKSIZE; // S α + count = 0; // ͳƱԪ + + // 2.ΪSub + while(count < len) { + r->ch[i] = p->ch[j]; + + i = (i + 1) % CHUNKSIZE; + if(i == 0) { + r = r->next; // ָSubһ + } + + j = (j + 1) % CHUNKSIZE; + if(j == 0) { + p = p->next; // ָSһ + } + + count++; + } + + // 3.δĿ + if(n != 0) { + // Ǵֵ('\0') + while(i < CHUNKSIZE) { + (*Sub).tail->ch[i] = '\0'; + i++; + } + } + + // 4.¼Ϣ + (*Sub).curlen = len; + + return OK; +} + +/* + * + * + * posʼģʽTS״γֵλãڣ򷵻0 + * ҳɹƥλá + * + *ע + * 1.ʵҪСӼ + * 2.ʵֱȽϵЧ + */ +int Index(LString S, LString T, int pos) { + int i, s, t; + LString sub; + + if(pos < 1 || pos > S.curlen || StrEmpty(T)) { + return 0; + } + + s = S.curlen; //S + t = T.curlen; //ģʽT + i = pos; + + while(i + t - 1 <= s) { + // ȡS[i, i+m-1] + SubString(&sub, S, i, t); + + // Ӵģʽƥ䣬Ҫƽ + if(StrCompare(sub, T) != 0) { + ++i; + } else { + return i; + } + } + + return 0; //Ҳƥ򷵻0 +} + +/* + * + * + * T뵽Sposλô + */ +Status StrInsert(LString* S, int pos, LString T) { + Chunk* pre, * p; // preָĿǰpָĿ + Chunk* h, * t; // ָĿͷβ + Chunk* r; + Chunk* s; + int i, j, count; + + if(pos < 1 || pos > (*S).curlen + 1) { + return ERROR; + } + + // ĴΪգǰ + if(StrEmpty(T)) { + return OK; + } + + // ¼ʼֹ + h = t = NULL; + + // TеĿ飨ֻƽṹ + for(r = T.head; r != NULL; r = r->next) { + s = (Chunk*) malloc(sizeof(Chunk)); + if(s == NULL) { + exit(OVERFLOW); + } + s->next = NULL; + + if(r == T.head) { + h = t = s; + } else { + t->next = s; + t = s; + } + } + + // SеposԪڵĿ飨עΪĿ飩ָpreָǰ + if(pos >= 1 && pos <= CHUNKSIZE) { + pre = NULL; // ˵posԪڿΪhead + p = (*S).head; + } else { + for(count = 1, pre = (*S).head; count < (pos - 1) / CHUNKSIZE; count++, pre = pre->next) { + // ѭ + } + p = pre->next; + } + + /* + * htΧĿ뵽posڵĿ֮ǰ + */ + + if(pre == NULL) { + t->next = (*S).head; + (*S).head = h; + } else { + pre->next = h; + t->next = p; + } + + if(pre == (*S).tail) { + (*S).tail = t; + } + + /* + * ƶ/Ԫ + */ + + j = 0; + + // 뵽ijġм䡱 + if((pos - 1) % CHUNKSIZE != 0) { + // ƶĿposλ֮ǰԪ + for(i = 1; i <= (pos - 1) % CHUNKSIZE; i++) { + h->ch[j++] = p->ch[i - 1]; + p->ch[i - 1] = '\0'; + } + } + + r = T.head; + i = 0; + + // TеԪصS + for(count = 1; count <= T.curlen; count++) { + h->ch[j] = r->ch[i]; + + j = (j + 1) % CHUNKSIZE; + i = (i + 1) % CHUNKSIZE; + + if(j == 0) { + h = h->next; + } + + if(i == 0) { + r = r->next; + } + } + + // Tһа'\0' + if(T.curlen % CHUNKSIZE != 0) { + r = p; // ָĿ + i = (pos - 1) % CHUNKSIZE; + + // ƶĿposλü֮Ԫ + for(count = pos; count <= (*S).curlen; count++) { + h->ch[j] = r->ch[i]; + r->ch[i] = '\0'; + + j = (j + 1) % CHUNKSIZE; + i = (i + 1) % CHUNKSIZE; + + if(j == 0) { + h = h->next; + } + + if(i == 0) { + r = r->next; + } + } + } + + (*S).curlen += T.curlen; + + return OK; +} + +/* + * ɾ + * + * ɾS[pos, pos+len-1] + */ +Status StrDelete(LString* S, int pos, int len) { + Chunk* pre; // ָԪS[pos]ڵĿǰ + Chunk* p; // ָԪS[pos]ڵĿ + Chunk* q; // ָԪS[pos+len]ڵĿ + Chunk* r; + int i, j, count, total; + + if(pos < 1 || pos > (*S).curlen || len < 0 || pos + len - 1 > (*S).curlen) { + return ERROR; + } + + // ɾijΪ0ǰ + if(len == 0) { + return OK; + } + + // S[pos]ڵĿ飬ָpreָǰ + if(pos >= 1 && pos <= CHUNKSIZE) { + pre = NULL; // ˵posԪڿΪhead + p = (*S).head; + } else { + for(count = 1, pre = (*S).head; count < (pos - 1) / CHUNKSIZE; count++, pre = pre->next) { + // ѭ + } + p = pre->next; + } + + // S[pos+len]ڵĿ + for(count = (pos - 1) / CHUNKSIZE, q = p; count < (pos + len - 1) / CHUNKSIZE; count++, q = q->next) { + // ѭ + } + + // ҪƶԪظ + total = (*S).curlen - (pos + len) + 1; + + // յijȶ + (*S).curlen -= len; + + i = (pos - 1) % CHUNKSIZE; + j = (pos + len - 1) % CHUNKSIZE; + + if(p != q) { + // ɾpq֮Ŀ + r = p->next; + while(r != q) { + p->next = r->next; + free(r); + r = p->next; + } + + if(q == NULL) { + (*S).tail = p; + } + + // Ҫɾpָ + if((pos - 1) % CHUNKSIZE == 0) { + // pѾָͷ + if(pre == NULL) { + (*S).head = q; + } else { + pre->next = q; + } + + free(p); + p = q; + + if(q == NULL) { + (*S).tail = pre; + } + } + } + + // Ѿλ + if(p == q && i == j) { + return OK; + } + + for(count = 1; count <= total; count++) { + // ƶԪ + p->ch[i] = q->ch[j]; + + i = (i + 1) % CHUNKSIZE; + j = (j + 1) % CHUNKSIZE; + + if(i == 0) { + pre = p; + p = p->next; + } + + if(j == 0) { + q = q->next; + } + } + + // ǡĿ + if(i == 0) { + (*S).tail = pre; + r = p; + } else { + (*S).tail = p; + + // ʣಿǴֵַ + while(i < CHUNKSIZE) { + p->ch[i++] = '\0'; + } + + r = p->next; + } + + // ͷŶĿռ + while(r != NULL) { + (*S).tail->next = r->next; + free(r); + r = (*S).tail->next; + } + + return OK; +} + +/* + * Ƚ + * + * ȽϴSʹTرȽϽ + * + *ע + * òСӼ + */ +int StrCompare(LString S, LString T) { + int i; + Chunk* s = S.head; + Chunk* t = T.head; + + while(s != NULL && t != NULL) { + for(i = 0; i < CHUNKSIZE; i++) { + if(s->ch[i] != t->ch[i]) { + return s->ch[i] - t->ch[i]; + } + } + + s = s->next; + t = t->next; + } + + if(s != NULL) { + return 1; + } else if(t != NULL) { + return -1; + } else { + return 0; + } +} + +/* + * + * + * SƵT + */ +Status StrCopy(LString* T, LString S) { + int i; + Chunk* s, * p; + + for(p = S.head; p; p = p->next) { + s = (Chunk*) malloc(sizeof(Chunk)); + if(s == NULL) { + exit(OVERFLOW); + } + s->next = NULL; + + if(p == S.head) { + (*T).head = (*T).tail = s; + } else { + (*T).tail->next = s; + (*T).tail = s; + } + + for(i = 0; i < CHUNKSIZE; i++) { + (*s).ch[i] = (*p).ch[i]; + } + } + + (*T).curlen = S.curlen; + + return OK; +} + +/* + * 滻 + * + * V滻SгֵTȵҲصӴ + * + *ע + * 1.òСӼ + * 2.ʵֱȽϵЧ + */ +Status Replace(LString* S, LString T, LString V) { + int i; + + if(StrEmpty(*S) || StrEmpty(T)) { + return ERROR; + } + + // SѰģʽTһγֵλ + i = Index(*S, T, 1); + + // ƥַ + while(i != 0) { + StrDelete(S, i, StrLength(T)); // SɾT + StrInsert(S, i, V); // SвV + + i += StrLength(V); // iлһλ + + i = Index(*S, T, i); // һƥַ + } + + return OK; +} + +/* + * + * + * S1S2洢TзءӺijֻδIJ֡ + * ֵʾӺĴǷ + * + *ע + * òСӼ + */ +Status Concat(LString* T, LString S1, LString S2) { + Chunk* p; // S1S2 + Chunk* r; // T + Chunk* s; + int i, j, count; + + // 㳤Ϣ + (*T).curlen = S1.curlen + S2.curlen; + + // Ҫٸ + count = (*T).curlen / CHUNKSIZE + ((*T).curlen % CHUNKSIZE == 0 ? 0 : 1); + + // S1Ľṹ + for(i = 1; i <= count; i++) { + s = (Chunk*) malloc(sizeof(Chunk)); + if(s == NULL) { + exit(OVERFLOW); + } + s->next = NULL; + + if(i == 1) { + (*T).head = (*T).tail = s; + } else { + (*T).tail->next = s; + (*T).tail = s; + } + } + + i = 0; + r = (*T).head; + + // S1е + j = 0; + p = S1.head; + for(count = 0; count < S1.curlen; count++) { + r->ch[i] = p->ch[j]; + + i = (i + 1) % CHUNKSIZE; + j = (j + 1) % CHUNKSIZE; + + if(i == 0) { + r = r->next; + } + + if(j == 0) { + p = p->next; + } + } + + // S2е + j = 0; + p = S2.head; + for(count = 0; count < S2.curlen; count++) { + r->ch[i] = p->ch[j]; + + i = (i + 1) % CHUNKSIZE; + j = (j + 1) % CHUNKSIZE; + + if(i == 0) { + r = r->next; + } + + if(j == 0) { + p = p->next; + } + } + + // ĿռǴֵַ + if(i != 0) { + while(i < CHUNKSIZE) { + r->ch[i] = '\0'; + i++; + } + } + + return OK; +} + +// Ժӡַ +void StrPrint(LString S) { + int i = 0; + Chunk* p = S.head; + + if(S.curlen == 0 || S.head == NULL || S.tail == NULL) { + return; + } + + while(p != NULL) { + // Ǵֵʱ + if(p->ch[i] == '\0') { + break; + } + + printf("%c", p->ch[i]); + + i = (i + 1) % CHUNKSIZE; + + if(i == 0) { + p = p->next; + } + } + + printf("\n"); +} diff --git a/Dev-C++/ExerciseBook/04.22/LString.h b/Dev-C++/ExerciseBook/04.22/LString.h new file mode 100644 index 0000000..e6f19d1 --- /dev/null +++ b/Dev-C++/ExerciseBook/04.22/LString.h @@ -0,0 +1,169 @@ +/*============================= + * Ŀ洢ʾ + ==============================*/ + +#ifndef LSTRING_H +#define LSTRING_H + +#include +#include // ṩmallocreallocfreeexitԭ +#include // ṩstrlenԭ +#include "Status.h" //**01 **// + +/* 궨 */ +#define CHUNKSIZE 3 // СԶ壩 + +/* Ŀ洢ṹ */ +typedef struct Chunk { + char ch[CHUNKSIZE]; // ǰе + struct Chunk* next; // ָһ +} Chunk; + +/* Ŀ洢Ͷ */ +typedef struct { + Chunk* head; //ͷָ + Chunk* tail; //βָ + int curlen; //ĵǰ +} LString; + + +/* + * ʾ + * + * ѭ̲ĵдϰߣposָʾַλ()1ʼ + */ + +/* + * ע + * + * 1.̲ʾʹ#ΪǴֵַʹCе\0ΪǴֵַ + * 2.ָ̲һУĩβ÷Ǵֵַġ + * СΪ4Ϊ14ĿΪ£ã -> ţƣǣ -> ɣʣˣ -> ͣ\0\0 + */ + + +/* + * ʼ + * + * һֵΪcharsĴT + * + *ע + * òСӼ + */ +Status StrAssign(LString* T, const char* chars); + +/* + * + * + * S١ + */ +Status DestroyString(LString* S); + +/* + * + * + * Sա + */ +Status ClearString(LString* S); + +/* + * п + * + * жϴSǷЧݡ + * + * ֵ + * TRUE : SΪ + * FALSE: SΪ + */ +Status StrEmpty(LString S); + +/* + * + * + * شSԪصĸ + * + *ע + * òСӼ + */ +int StrLength(LString S); + +/* + * Ӵ + * + * SubS[pos, pos+len-1] + * ֵָʾǷȡɹ + * + *ע + * òСӼ + */ +Status SubString(LString* Sub, LString S, int pos, int len); + +/* + * + * + * posʼģʽTS״γֵλãڣ򷵻0 + * ҳɹƥλá + * + *ע + * 1.ʵҪСӼ + * 2.ʵֱȽϵЧ + */ +int Index(LString S, LString T, int pos); + +/* + * + * + * T뵽Sposλô + */ +Status StrInsert(LString* S, int pos, LString T); + +/* + * ɾ + * + * ɾS[pos, pos+len-1] + */ +Status StrDelete(LString* S, int pos, int len); + +/* + * Ƚ + * + * ȽϴSʹTرȽϽ + * + *ע + * òСӼ + */ +Status StrCompare(LString S, LString T); + +/* + * + * + * SƵT + */ +Status StrCopy(LString* T, LString S); + +/* + * 滻 + * + * V滻SгֵTȵҲصӴ + * + *ע + * 1.òСӼ + * 2.ʵֱȽϵЧ + */ +Status Replace(LString* S, LString T, LString V); + +/* + * + * + * S1S2洢TзءӺijֻδIJ֡ + * ֵʾӺĴǷ + * + *ע + * òСӼ + */ +Status Concat(LString* T, LString S1, LString S2); + +// Ժӡַ +void StrPrint(LString S); + +#endif diff --git a/Dev-C++/ExerciseBook/04.23/04.23.cpp b/Dev-C++/ExerciseBook/04.23/04.23.cpp new file mode 100644 index 0000000..d310967 --- /dev/null +++ b/Dev-C++/ExerciseBook/04.23/04.23.cpp @@ -0,0 +1,107 @@ +#include +#include "LString.h" //**04 **// + +/* + * жϸĴǷԳơ + * մַĴᱻΪǶԳƵġ + */ +Status Algo_4_23(LString T); + + +int main(int argc, char* argv[]) { + char* t = "abcdefgfedcba"; + LString T; + + StrAssign(&T, t); + printf("T = "); + StrPrint(T); + + Algo_4_23(T) ? printf("TǶԳƴ\n") : printf("TǷǶԳƴ\n"); + + return 0; +} + + +/* + * жϸĴǷԳơ + * մַĴᱻΪǶԳƵġ + */ +Status Algo_4_23(LString T) { + int len; // Tij + + int a1, b1; // Tǰ벿ֱ߽ + int a2, b2; // Tĺ벿ֱ߽ + int k; // ƱTʱҪԪ + int i; // Tʱα + Chunk* t; + + char* stack; // ģջ + int top; // ջα + + char c; // Tȡַ + + len = StrLength(T); + + // մΪǶԳƵ + if(len == 0) { + return OK; + } + + // ijż + if(len % 2 == 0) { + a1 = 0; + b1 = len / 2 - 1; + a2 = len / 2; + b2 = len - 1; + // ij + } else { + a1 = 0; + b1 = len / 2 - 1; + a2 = len / 2 + 1; + b2 = len - 1; + } + + stack = (char*) malloc(len * sizeof(char)); + top = -1; + + i = 0; + t = T.head; + + // ڴǰ벿֣ջ + for(k = a1; k <= b1; k++) { + c = t->ch[i]; + i = (i + 1) % CHUNKSIZE; + if(i == 0) { + t = t->next; + } + + stack[++top] = c; + } + + // ΪҪһַ + if(len % 2 == 1) { + i = (i + 1) % CHUNKSIZE; + if(i == 0) { + t = t->next; + } + } + + for(k = a2; k <= b2; k++) { + c = t->ch[i]; + i = (i + 1) % CHUNKSIZE; + if(i == 0) { + t = t->next; + } + + // ˲ԳƵַ + if(stack[top--] != c) { + return ERROR; + } + } + + if(top == -1) { + return OK; + } else { + return ERROR; + } +} diff --git a/Dev-C++/ExerciseBook/04.23/04.23.dev b/Dev-C++/ExerciseBook/04.23/04.23.dev new file mode 100644 index 0000000..3ca19f6 --- /dev/null +++ b/Dev-C++/ExerciseBook/04.23/04.23.dev @@ -0,0 +1,82 @@ +[Project] +FileName=04.23.dev +Name=04.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=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=LString.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit1] +FileName=04.23.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit3] +FileName=LString.h +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + diff --git a/Dev-C++/ExerciseBook/04.23/LString.cpp b/Dev-C++/ExerciseBook/04.23/LString.cpp new file mode 100644 index 0000000..76b08fa --- /dev/null +++ b/Dev-C++/ExerciseBook/04.23/LString.cpp @@ -0,0 +1,748 @@ +/*============================= + * Ŀ洢ʾ + ==============================*/ + +#include "LString.h" //**04 **// + +/* + * ʼ + * + * һֵΪcharsĴT + * + *ע + * òСӼ + */ +Status StrAssign(LString* T, const char* chars) { + int len; // charsij + int i, count; // ַcharsα + int m; // ܿ + int n; // δĿ飬洢ÿеЧԪ + Chunk* r; + + // charsij + len = (int) strlen(chars); + + // ûЧԪ + if(len == 0) { + (*T).head = NULL; + (*T).tail = NULL; + (*T).curlen = 0; + + return OK; + } + + m = len / CHUNKSIZE; // ȼҪĿ + n = len % CHUNKSIZE; // δĿ飬ÿЧԪ + if(n != 0) { + m++; // ܿ + } + + // 1.Ľṹ + for(i = 1; i <= m; i++) { + // ¿ + r = (Chunk*) malloc(sizeof(Chunk)); + if(r == NULL) { + exit(OVERFLOW); + } + r->next = NULL; + + // һ + if(i == 1) { + (*T).head = (*T).tail = r; + + // ӺĿ + } else { + (*T).tail->next = r; + (*T).tail = r; + } + } + + r = (*T).head; + i = 0; // Tα + count = 0; // ͳƱԪأ˳Ϊcharsα + + // 2.Ϊ + while(count < len) { + r->ch[i] = chars[count]; + + i = (i + 1) % CHUNKSIZE; + if(i == 0) { + r = r->next; // ָһ + } + + count++; + } + + // 3.δĿ + if(n != 0) { + // Ǵֵ('\0') + while(i < CHUNKSIZE) { + (*T).tail->ch[i] = '\0'; + i++; + } + } + + // 4.¼Ϣ + (*T).curlen = len; + + return OK; +} + +/* + * + * + *ע + * Ľṹ٣ٲ + */ +Status DestroyString(LString* S) { + return OK; +} + +/* + * + * + * Sա + */ +Status ClearString(LString* S) { + Chunk* p, * q; + + p = (*S).head; + + // ͷдռõĿռ + while(p != NULL) { + q = p->next; + free(p); + p = q; + } + + (*S).head = NULL; + (*S).tail = NULL; + (*S).curlen = 0; + + return OK; +} + +/* + * п + * + * жϴSǷЧݡ + * + * ֵ + * TRUE : SΪ + * FALSE: SΪ + */ +Status StrEmpty(LString S) { + return S.curlen == 0 ? TRUE : FALSE; +} + +/* + * + * + * شSԪصĸ + * + *ע + * òСӼ + */ +int StrLength(LString S) { + return S.curlen; +} + +/* + * Ӵ + * + * SubS[pos, pos+len-1] + * ֵָʾǷȡɹ + * + *ע + * òСӼ + */ +Status SubString(LString* Sub, LString S, int pos, int len) { + int m; // Subܿ + int n; // SubδĿ飬洢ÿеЧԪ + int i, j, count; + Chunk* r, * p; + + if(pos < 1 || pos > S.curlen || len < 0 || pos + len - 1 > S.curlen) { + return ERROR; + } + + // ǽȡ0ַҪռ + if(len == 0) { + (*Sub).head = NULL; + (*Sub).tail = NULL; + (*Sub).curlen = 0; + + return OK; + } + + m = len / CHUNKSIZE; // ȼҪĿ + n = len % CHUNKSIZE; // SubδĿ飬ÿЧԪ + if(n != 0) { + m++; // Subܿ + } + + // 1.SubĽṹ + for(i = 1; i <= m; i++) { + // ¿ + r = (Chunk*) malloc(sizeof(Chunk)); + if(r == NULL) { + exit(OVERFLOW); + } + r->next = NULL; + + // һ + if(i == 1) { + (*Sub).head = (*Sub).tail = r; + + // ӺĿ + } else { + (*Sub).tail->next = r; + (*Sub).tail = r; + } + } + + // SеposԪڵĿ飬ָpָ + for(count = 1, p = S.head; pos > count * CHUNKSIZE; count++, p = p->next) { + // ѭ + } + + r = (*Sub).head; // ָSubĿ + + i = 0; // Subα + j = (pos - 1) % CHUNKSIZE; // S α + count = 0; // ͳƱԪ + + // 2.ΪSub + while(count < len) { + r->ch[i] = p->ch[j]; + + i = (i + 1) % CHUNKSIZE; + if(i == 0) { + r = r->next; // ָSubһ + } + + j = (j + 1) % CHUNKSIZE; + if(j == 0) { + p = p->next; // ָSһ + } + + count++; + } + + // 3.δĿ + if(n != 0) { + // Ǵֵ('\0') + while(i < CHUNKSIZE) { + (*Sub).tail->ch[i] = '\0'; + i++; + } + } + + // 4.¼Ϣ + (*Sub).curlen = len; + + return OK; +} + +/* + * + * + * posʼģʽTS״γֵλãڣ򷵻0 + * ҳɹƥλá + * + *ע + * 1.ʵҪСӼ + * 2.ʵֱȽϵЧ + */ +int Index(LString S, LString T, int pos) { + int i, s, t; + LString sub; + + if(pos < 1 || pos > S.curlen || StrEmpty(T)) { + return 0; + } + + s = S.curlen; //S + t = T.curlen; //ģʽT + i = pos; + + while(i + t - 1 <= s) { + // ȡS[i, i+m-1] + SubString(&sub, S, i, t); + + // Ӵģʽƥ䣬Ҫƽ + if(StrCompare(sub, T) != 0) { + ++i; + } else { + return i; + } + } + + return 0; //Ҳƥ򷵻0 +} + +/* + * + * + * T뵽Sposλô + */ +Status StrInsert(LString* S, int pos, LString T) { + Chunk* pre, * p; // preָĿǰpָĿ + Chunk* h, * t; // ָĿͷβ + Chunk* r; + Chunk* s; + int i, j, count; + + if(pos < 1 || pos > (*S).curlen + 1) { + return ERROR; + } + + // ĴΪգǰ + if(StrEmpty(T)) { + return OK; + } + + // ¼ʼֹ + h = t = NULL; + + // TеĿ飨ֻƽṹ + for(r = T.head; r != NULL; r = r->next) { + s = (Chunk*) malloc(sizeof(Chunk)); + if(s == NULL) { + exit(OVERFLOW); + } + s->next = NULL; + + if(r == T.head) { + h = t = s; + } else { + t->next = s; + t = s; + } + } + + // SеposԪڵĿ飨עΪĿ飩ָpreָǰ + if(pos >= 1 && pos <= CHUNKSIZE) { + pre = NULL; // ˵posԪڿΪhead + p = (*S).head; + } else { + for(count = 1, pre = (*S).head; count < (pos - 1) / CHUNKSIZE; count++, pre = pre->next) { + // ѭ + } + p = pre->next; + } + + /* + * htΧĿ뵽posڵĿ֮ǰ + */ + + if(pre == NULL) { + t->next = (*S).head; + (*S).head = h; + } else { + pre->next = h; + t->next = p; + } + + if(pre == (*S).tail) { + (*S).tail = t; + } + + /* + * ƶ/Ԫ + */ + + j = 0; + + // 뵽ijġм䡱 + if((pos - 1) % CHUNKSIZE != 0) { + // ƶĿposλ֮ǰԪ + for(i = 1; i <= (pos - 1) % CHUNKSIZE; i++) { + h->ch[j++] = p->ch[i - 1]; + p->ch[i - 1] = '\0'; + } + } + + r = T.head; + i = 0; + + // TеԪصS + for(count = 1; count <= T.curlen; count++) { + h->ch[j] = r->ch[i]; + + j = (j + 1) % CHUNKSIZE; + i = (i + 1) % CHUNKSIZE; + + if(j == 0) { + h = h->next; + } + + if(i == 0) { + r = r->next; + } + } + + // Tһа'\0' + if(T.curlen % CHUNKSIZE != 0) { + r = p; // ָĿ + i = (pos - 1) % CHUNKSIZE; + + // ƶĿposλü֮Ԫ + for(count = pos; count <= (*S).curlen; count++) { + h->ch[j] = r->ch[i]; + r->ch[i] = '\0'; + + j = (j + 1) % CHUNKSIZE; + i = (i + 1) % CHUNKSIZE; + + if(j == 0) { + h = h->next; + } + + if(i == 0) { + r = r->next; + } + } + } + + (*S).curlen += T.curlen; + + return OK; +} + +/* + * ɾ + * + * ɾS[pos, pos+len-1] + */ +Status StrDelete(LString* S, int pos, int len) { + Chunk* pre; // ָԪS[pos]ڵĿǰ + Chunk* p; // ָԪS[pos]ڵĿ + Chunk* q; // ָԪS[pos+len]ڵĿ + Chunk* r; + int i, j, count, total; + + if(pos < 1 || pos > (*S).curlen || len < 0 || pos + len - 1 > (*S).curlen) { + return ERROR; + } + + // ɾijΪ0ǰ + if(len == 0) { + return OK; + } + + // S[pos]ڵĿ飬ָpreָǰ + if(pos >= 1 && pos <= CHUNKSIZE) { + pre = NULL; // ˵posԪڿΪhead + p = (*S).head; + } else { + for(count = 1, pre = (*S).head; count < (pos - 1) / CHUNKSIZE; count++, pre = pre->next) { + // ѭ + } + p = pre->next; + } + + // S[pos+len]ڵĿ + for(count = (pos - 1) / CHUNKSIZE, q = p; count < (pos + len - 1) / CHUNKSIZE; count++, q = q->next) { + // ѭ + } + + // ҪƶԪظ + total = (*S).curlen - (pos + len) + 1; + + // յijȶ + (*S).curlen -= len; + + i = (pos - 1) % CHUNKSIZE; + j = (pos + len - 1) % CHUNKSIZE; + + if(p != q) { + // ɾpq֮Ŀ + r = p->next; + while(r != q) { + p->next = r->next; + free(r); + r = p->next; + } + + if(q == NULL) { + (*S).tail = p; + } + + // Ҫɾpָ + if((pos - 1) % CHUNKSIZE == 0) { + // pѾָͷ + if(pre == NULL) { + (*S).head = q; + } else { + pre->next = q; + } + + free(p); + p = q; + + if(q == NULL) { + (*S).tail = pre; + } + } + } + + // Ѿλ + if(p == q && i == j) { + return OK; + } + + for(count = 1; count <= total; count++) { + // ƶԪ + p->ch[i] = q->ch[j]; + + i = (i + 1) % CHUNKSIZE; + j = (j + 1) % CHUNKSIZE; + + if(i == 0) { + pre = p; + p = p->next; + } + + if(j == 0) { + q = q->next; + } + } + + // ǡĿ + if(i == 0) { + (*S).tail = pre; + r = p; + } else { + (*S).tail = p; + + // ʣಿǴֵַ + while(i < CHUNKSIZE) { + p->ch[i++] = '\0'; + } + + r = p->next; + } + + // ͷŶĿռ + while(r != NULL) { + (*S).tail->next = r->next; + free(r); + r = (*S).tail->next; + } + + return OK; +} + +/* + * Ƚ + * + * ȽϴSʹTرȽϽ + * + *ע + * òСӼ + */ +int StrCompare(LString S, LString T) { + int i; + Chunk* s = S.head; + Chunk* t = T.head; + + while(s != NULL && t != NULL) { + for(i = 0; i < CHUNKSIZE; i++) { + if(s->ch[i] != t->ch[i]) { + return s->ch[i] - t->ch[i]; + } + } + + s = s->next; + t = t->next; + } + + if(s != NULL) { + return 1; + } else if(t != NULL) { + return -1; + } else { + return 0; + } +} + +/* + * + * + * SƵT + */ +Status StrCopy(LString* T, LString S) { + int i; + Chunk* s, * p; + + for(p = S.head; p; p = p->next) { + s = (Chunk*) malloc(sizeof(Chunk)); + if(s == NULL) { + exit(OVERFLOW); + } + s->next = NULL; + + if(p == S.head) { + (*T).head = (*T).tail = s; + } else { + (*T).tail->next = s; + (*T).tail = s; + } + + for(i = 0; i < CHUNKSIZE; i++) { + (*s).ch[i] = (*p).ch[i]; + } + } + + (*T).curlen = S.curlen; + + return OK; +} + +/* + * 滻 + * + * V滻SгֵTȵҲصӴ + * + *ע + * 1.òСӼ + * 2.ʵֱȽϵЧ + */ +Status Replace(LString* S, LString T, LString V) { + int i; + + if(StrEmpty(*S) || StrEmpty(T)) { + return ERROR; + } + + // SѰģʽTһγֵλ + i = Index(*S, T, 1); + + // ƥַ + while(i != 0) { + StrDelete(S, i, StrLength(T)); // SɾT + StrInsert(S, i, V); // SвV + + i += StrLength(V); // iлһλ + + i = Index(*S, T, i); // һƥַ + } + + return OK; +} + +/* + * + * + * S1S2洢TзءӺijֻδIJ֡ + * ֵʾӺĴǷ + * + *ע + * òСӼ + */ +Status Concat(LString* T, LString S1, LString S2) { + Chunk* p; // S1S2 + Chunk* r; // T + Chunk* s; + int i, j, count; + + // 㳤Ϣ + (*T).curlen = S1.curlen + S2.curlen; + + // Ҫٸ + count = (*T).curlen / CHUNKSIZE + ((*T).curlen % CHUNKSIZE == 0 ? 0 : 1); + + // S1Ľṹ + for(i = 1; i <= count; i++) { + s = (Chunk*) malloc(sizeof(Chunk)); + if(s == NULL) { + exit(OVERFLOW); + } + s->next = NULL; + + if(i == 1) { + (*T).head = (*T).tail = s; + } else { + (*T).tail->next = s; + (*T).tail = s; + } + } + + i = 0; + r = (*T).head; + + // S1е + j = 0; + p = S1.head; + for(count = 0; count < S1.curlen; count++) { + r->ch[i] = p->ch[j]; + + i = (i + 1) % CHUNKSIZE; + j = (j + 1) % CHUNKSIZE; + + if(i == 0) { + r = r->next; + } + + if(j == 0) { + p = p->next; + } + } + + // S2е + j = 0; + p = S2.head; + for(count = 0; count < S2.curlen; count++) { + r->ch[i] = p->ch[j]; + + i = (i + 1) % CHUNKSIZE; + j = (j + 1) % CHUNKSIZE; + + if(i == 0) { + r = r->next; + } + + if(j == 0) { + p = p->next; + } + } + + // ĿռǴֵַ + if(i != 0) { + while(i < CHUNKSIZE) { + r->ch[i] = '\0'; + i++; + } + } + + return OK; +} + +// Ժӡַ +void StrPrint(LString S) { + int i = 0; + Chunk* p = S.head; + + if(S.curlen == 0 || S.head == NULL || S.tail == NULL) { + printf("\n"); + return; + } + + while(p != NULL) { + // Ǵֵʱ + if(p->ch[i] == '\0') { + break; + } + + printf("%c", p->ch[i]); + + i = (i + 1) % CHUNKSIZE; + + if(i == 0) { + p = p->next; + } + } + + printf("\n"); +} diff --git a/Dev-C++/ExerciseBook/04.23/LString.h b/Dev-C++/ExerciseBook/04.23/LString.h new file mode 100644 index 0000000..e6f19d1 --- /dev/null +++ b/Dev-C++/ExerciseBook/04.23/LString.h @@ -0,0 +1,169 @@ +/*============================= + * Ŀ洢ʾ + ==============================*/ + +#ifndef LSTRING_H +#define LSTRING_H + +#include +#include // ṩmallocreallocfreeexitԭ +#include // ṩstrlenԭ +#include "Status.h" //**01 **// + +/* 궨 */ +#define CHUNKSIZE 3 // СԶ壩 + +/* Ŀ洢ṹ */ +typedef struct Chunk { + char ch[CHUNKSIZE]; // ǰе + struct Chunk* next; // ָһ +} Chunk; + +/* Ŀ洢Ͷ */ +typedef struct { + Chunk* head; //ͷָ + Chunk* tail; //βָ + int curlen; //ĵǰ +} LString; + + +/* + * ʾ + * + * ѭ̲ĵдϰߣposָʾַλ()1ʼ + */ + +/* + * ע + * + * 1.̲ʾʹ#ΪǴֵַʹCе\0ΪǴֵַ + * 2.ָ̲һУĩβ÷Ǵֵַġ + * СΪ4Ϊ14ĿΪ£ã -> ţƣǣ -> ɣʣˣ -> ͣ\0\0 + */ + + +/* + * ʼ + * + * һֵΪcharsĴT + * + *ע + * òСӼ + */ +Status StrAssign(LString* T, const char* chars); + +/* + * + * + * S١ + */ +Status DestroyString(LString* S); + +/* + * + * + * Sա + */ +Status ClearString(LString* S); + +/* + * п + * + * жϴSǷЧݡ + * + * ֵ + * TRUE : SΪ + * FALSE: SΪ + */ +Status StrEmpty(LString S); + +/* + * + * + * شSԪصĸ + * + *ע + * òСӼ + */ +int StrLength(LString S); + +/* + * Ӵ + * + * SubS[pos, pos+len-1] + * ֵָʾǷȡɹ + * + *ע + * òСӼ + */ +Status SubString(LString* Sub, LString S, int pos, int len); + +/* + * + * + * posʼģʽTS״γֵλãڣ򷵻0 + * ҳɹƥλá + * + *ע + * 1.ʵҪСӼ + * 2.ʵֱȽϵЧ + */ +int Index(LString S, LString T, int pos); + +/* + * + * + * T뵽Sposλô + */ +Status StrInsert(LString* S, int pos, LString T); + +/* + * ɾ + * + * ɾS[pos, pos+len-1] + */ +Status StrDelete(LString* S, int pos, int len); + +/* + * Ƚ + * + * ȽϴSʹTرȽϽ + * + *ע + * òСӼ + */ +Status StrCompare(LString S, LString T); + +/* + * + * + * SƵT + */ +Status StrCopy(LString* T, LString S); + +/* + * 滻 + * + * V滻SгֵTȵҲصӴ + * + *ע + * 1.òСӼ + * 2.ʵֱȽϵЧ + */ +Status Replace(LString* S, LString T, LString V); + +/* + * + * + * S1S2洢TзءӺijֻδIJ֡ + * ֵʾӺĴǷ + * + *ע + * òСӼ + */ +Status Concat(LString* T, LString S1, LString S2); + +// Ժӡַ +void StrPrint(LString S); + +#endif diff --git a/Dev-C++/ExerciseBook/04.24-04.26/04.24-04.26.cpp b/Dev-C++/ExerciseBook/04.24-04.26/04.24-04.26.cpp new file mode 100644 index 0000000..e464ee6 --- /dev/null +++ b/Dev-C++/ExerciseBook/04.24-04.26/04.24-04.26.cpp @@ -0,0 +1,101 @@ +#include +#include "Status.h" //**01 **// +#include "HString.h" //**04 **// + +/* + * ӣConcat + * + *ע + * úHStringļж + */ +Status Algo_4_24(HString* T, HString S1, HString S2); + +/* + * 滻Replace + * + *ע + * úHStringļж + */ +Status Algo_4_25(HString* S, HString T, HString V); + +/* + * 룺StrInsert + * + *ע + * úHStringļж + */ +Status Algo_4_26(HString* S, int pos, HString T); + + +int main(int argc, char* argv[]) { + char* s = "---*^***^*^*^*---"; + char* s1 = "*"; + char* s2 = "^*"; + char* v = "*_*"; + HString S1, S2, T, V, S; + + StrAssign(&S1, s1); + StrAssign(&S2, s2); + StrAssign(&V, v); + StrAssign(&S, s); + + printf("S1 = "); + StrPrint(S1); + printf("S2 = "); + StrPrint(S2); + printf("V = "); + StrPrint(V); + printf("S = "); + StrPrint(S); + + printf(" 4.24 ֤...\n"); + printf("S1S2ΪT...\n"); + Algo_4_24(&T, S1, S2); + printf("T = "); + StrPrint(T); + + printf(" 4.25 ֤...\n"); + printf(" V 滻 S е T...\n"); + Algo_4_25(&S, T, V); + printf("S = "); + StrPrint(S); + + printf(" 4.26 ֤...\n"); + printf(" T 뵽 S ĵ 2 λ...\n"); + Algo_4_26(&S, 2, T); + printf("S = "); + StrPrint(S); + + return 0; +} + + +/* + * ӣConcat + * + *ע + * úHStringļж + */ +Status Algo_4_24(HString* T, HString S1, HString S2) { + return Concat(T, S1, S2); +} + +/* + * 滻Replace + * + *ע + * úHStringļж + */ +Status Algo_4_25(HString* S, HString T, HString V) { + return Replace(S, T, V); +} + +/* + * 룺StrInsert + * + *ע + * úHStringļж + */ +Status Algo_4_26(HString* S, int pos, HString T) { + return StrInsert(S, pos, T); +} diff --git a/Dev-C++/ExerciseBook/04.24-04.26/04.24-04.26.dev b/Dev-C++/ExerciseBook/04.24-04.26/04.24-04.26.dev new file mode 100644 index 0000000..5839e56 --- /dev/null +++ b/Dev-C++/ExerciseBook/04.24-04.26/04.24-04.26.dev @@ -0,0 +1,82 @@ +[Project] +FileName=04.24-04.26.dev +Name=04.24-04.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=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=04.24-04.26.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit2] +FileName=HString.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit3] +FileName=HString.h +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + diff --git a/Dev-C++/ExerciseBook/04.24-04.26/HString.cpp b/Dev-C++/ExerciseBook/04.24-04.26/HString.cpp new file mode 100644 index 0000000..4ed501a --- /dev/null +++ b/Dev-C++/ExerciseBook/04.24-04.26/HString.cpp @@ -0,0 +1,381 @@ +/*========================= + * Ķѷ洢ʾѴ + * + * 㷨: 4.4 + ==========================*/ + +#include "HString.h" //**04 **// + +/* + * ʼ + * + * һֵΪcharsĴT + * + *ע + * òСӼ + */ +Status StrAssign(HString* T, const char* chars) { + int i, j; + + // charsij + i = (int) strlen(chars); + + // ûЧԪ + if(i == 0) { + (*T).ch = NULL; + (*T).length = 0; + + return OK; + } + + // ЧԪʱҪ洢ռ + (*T).ch = (char*) malloc(i * sizeof(char)); + if(!((*T).ch)) { + exit(OVERFLOW); + } + + for(j = 0; j < i; j++) { + (*T).ch[j] = chars[j]; + } + + (*T).length = i; + + return OK; +} + +/* + * + * + * S١ + * + *ע + * ѴĽṹ٣ٲ + */ +Status DestroyString(HString* S) { + return OK; +} + +/* + * + * + * Sա + */ +Status ClearString(HString* S) { + // ûЧԪʱٶѴṹ + if((*S).ch != 0) { + free((*S).ch); + (*S).ch = NULL; + } + + (*S).length = 0; + + return OK; +} + +/* + * п + * + * жϴSǷЧݡ + * + * ֵ + * TRUE : SΪ + * FALSE: SΪ + */ +Status StrEmpty(HString S) { + return S.length == 0 ? TRUE : FALSE; +} + +/* + * + * + * شSԪصĸ + * + *ע + * òСӼ + */ +int StrLength(HString S) { + return S.length; +} + +/* + * Ӵ + * + * SubS[pos, pos+len-1] + * ֵָʾǷȡɹ + * + *ע + * òСӼ + */ +Status SubString(HString* Sub, HString S, int pos, int len) { + int i; + + if(pos < 1 || pos > S.length || len < 0 || pos + len - 1 > S.length) { + return ERROR; + } + + // ǽȡ0ַҪռ + if(len == 0) { + (*Sub).ch = NULL; + (*Sub).length = 0; + + return OK; + } + + (*Sub).ch = (char*) malloc(len * sizeof(char)); + if(!(*Sub).ch) { + exit(OVERFLOW); + } + + // Ԫ + for(i = 0; i < len; i++) { + (*Sub).ch[i] = S.ch[i + pos - 1]; + } + + // ȷ³ + (*Sub).length = len; + + return OK; +} + +/* + * + * + * posʼģʽTS״γֵλãڣ򷵻0 + * ҳɹƥλá + * + *ע + * 1.ʵҪСӼ + * 2.ʵֱȽϵЧ + */ +int Index(HString S, HString T, int pos) { + int i, s, t; + HString sub; + + if(pos < 1 || pos > S.length || StrEmpty(T)) { + return 0; + } + + s = S.length; + t = T.length; + i = pos; + + // ֤ȲԽ + while(i + t - 1 <= s) { + // ȡS[i, i+t-1] + SubString(&sub, S, i, t); + + // Ӵģʽƥ䣬Ҫƽ + if(StrCompare(sub, T) != 0) { + ++i; + } else { + return i; + } + } + + return 0; +} + +/* + * 㷨4.4 + * + * + * + * T뵽Sposλô + */ +Status StrInsert(HString* S, int pos, HString T) { + int i; + + if(pos < 1 || pos > (*S).length + 1) { + return ERROR; + } + + // ĴΪգǰ + if(StrEmpty(T)) { + return OK; + } + + // ¿ռ䣬ὫԪһƹȥ + (*S).ch = (char*) realloc((*S).ch, ((*S).length + T.length) * sizeof(char)); + if(!(*S).ch) { + exit(OVERFLOW); + } + + // SڳλãΪT׼ + for(i = (*S).length - 1; i >= pos - 1; i--) { + // ӺǰǰԪŲ + (*S).ch[i + T.length] = (*S).ch[i]; + } + + // TSڳλ + for(i = pos - 1; i <= pos + T.length - 2; i++) { + (*S).ch[i] = T.ch[i - pos + 1]; + } + + // + (*S).length += T.length; + + return OK; +} + +/* + * ɾ + * + * ɾS[pos, pos+len-1] + */ +Status StrDelete(HString* S, int pos, int len) { + int i; + + if(pos < 1 || pos + len - 1 > (*S).length || len < 0) { + return ERROR; + } + + // ɾijΪ0ǰ + if(len == 0) { + return OK; + } + + // ѺԪŲǰ棬ǵɾԪ + for(i = pos + len - 1; i <= (*S).length - 1; i++) { + (*S).ch[i - len] = (*S).ch[i]; + } + + // ȼ + (*S).length -= len; + + // Ŀռ䣨ȼΪ0᷵ؿָ룩 + (*S).ch = (char*) realloc((*S).ch, (*S).length * sizeof(char)); + + return OK; +} + +/* + * Ƚ + * + * ȽϴSʹTرȽϽ + * + *ע + * òСӼ + */ +Status StrCompare(HString S, HString T) { + int i; + + for(i = 0; i < S.length && i < T.length; i++) { + // ַͬʱȽС + if(S.ch[i] != T.ch[i]) { + return S.ch[i] - T.ch[i]; + } + } + + return S.length - T.length; +} + +/* + * + * + * SƵT + */ +Status StrCopy(HString* T, HString S) { + int i; + + if(StrEmpty(S)) { + (*T).ch = NULL; + (*T).length = 0; + } else { + // ռ + (*T).ch = (char*) malloc(S.length * sizeof(char)); + if(!(*T).ch) { + exit(OVERFLOW); + } + + // Ԫ + for(i = 0; i < S.length; i++) { + (*T).ch[i] = S.ch[i]; + } + + // ƳϢ + (*T).length = S.length; + } + + return OK; +} + +/* + * 滻 + * + * V滻SгֵTȵҲصӴ + * + *ע + * 1.òСӼ + * 2.ʵֱȽϵЧ + */ +Status Replace(HString* S, HString T, HString V) { + int i; + + if(StrEmpty(*S) || StrEmpty(T)) { + return ERROR; + } + + // SѰģʽTһγֵλ + i = Index(*S, T, 1); + + // ƥַ + while(i != 0) { + StrDelete(S, i, StrLength(T)); // SɾT + StrInsert(S, i, V); // SвV + + i += StrLength(V); // iлһλ + + i = Index(*S, T, i); // һƥַ + } + + return OK; +} + +/* + * + * + * S1S2洢TзءӺijֻδIJ֡ + * ֵʾӺĴǷ + * ѴĿռ䱻Ϊ޵ģǷTRUEָʾᱻü + * + *ע + * òСӼ + */ +Status Concat(HString* T, HString S1, HString S2) { + int i; + + // ȷ³ + (*T).length = S1.length + S2.length; + + // ռ + (*T).ch = (char*) malloc((*T).length * sizeof(char)); + if(!(*T).ch) { + exit(OVERFLOW); + } + + // ȰS1ݿ + for(i = 0; i < S1.length; i++) { + (*T).ch[i] = S1.ch[i]; + } + + // ٿS2 + for(i = 0; i < S2.length; i++) { + (*T).ch[S1.length + i] = S2.ch[i]; + } + + return TRUE; +} + +// ӡַ +void StrPrint(HString S) { + int i; + + if(S.length == 0) { + return; + } + + for(i = 0; i < S.length; i++) { + printf("%c", S.ch[i]); + } + printf("\n"); +} \ No newline at end of file diff --git a/Dev-C++/ExerciseBook/04.24-04.26/HString.h b/Dev-C++/ExerciseBook/04.24-04.26/HString.h new file mode 100644 index 0000000..3d13eaf --- /dev/null +++ b/Dev-C++/ExerciseBook/04.24-04.26/HString.h @@ -0,0 +1,159 @@ +/*========================= + * Ķѷ洢ʾѴ + * + * 㷨: 4.4 + ==========================*/ + +#ifndef HSTRING +#define HSTRING + +#include +#include // ṩmallocreallocfreeexitԭ +#include // ṩstrlenԭ +#include "Status.h" //**01 **// + +/* + * ĶѴ洢ʾ + * + * עЧԪشch0ŵԪʼ洢 + */ +typedef struct { + char* ch; // Ƿǿմ򰴴洢chΪNULL + int length; +} HString; + + +/* + * ʾ + * + * ѭ̲ĵдϰߣposָʾַλ()1ʼ + */ + + +/* + * ʼ + * + * һֵΪcharsĴT + * + *ע + * òСӼ + */ +Status StrAssign(HString* T, const char* chars); + +/* + * + * + * S١ + */ +Status DestroyString(HString* S); + +/* + * + * + * Sա + */ +Status ClearString(HString* S); + +/* + * п + * + * жϴSǷЧݡ + * + * ֵ + * TRUE : SΪ + * FALSE: SΪ + */ +Status StrEmpty(HString S); + +/* + * + * + * شSԪصĸ + * + *ע + * òСӼ + */ +int StrLength(HString S); + +/* + * Ӵ + * + * SubS[pos, pos+len-1] + * ֵָʾǷȡɹ + * + *ע + * òСӼ + */ +Status SubString(HString* Sub, HString S, int pos, int len); + +/* + * + * + * posʼģʽTS״γֵλãڣ򷵻0 + * ҳɹƥλá + * + *ע + * 1.ʵҪСӼ + * 2.ʵֱȽϵЧ + */ +int Index(HString S, HString T, int pos); + +/* + * 㷨4.4 + * + * + * + * T뵽Sposλô + */ +Status StrInsert(HString* S, int pos, HString T); + +/* + * ɾ + * + * ɾS[pos, pos+len-1] + */ +Status StrDelete(HString* S, int pos, int len); + +/* + * Ƚ + * + * ȽϴSʹTرȽϽ + * + *ע + * òСӼ + */ +Status StrCompare(HString S, HString T); + +/* + * + * + * SƵT + */ +Status StrCopy(HString* T, HString S); + +/* + * 滻 + * + * V滻SгֵTȵҲصӴ + * + *ע + * 1.òСӼ + * 2.ʵֱȽϵЧ + */ +Status Replace(HString* S, HString T, HString V); + +/* + * + * + * S1S2洢TзءӺijֻδIJ֡ + * ֵʾӺĴǷ + * + *ע + * òСӼ + */ +Status Concat(HString* T, HString S1, HString S2); + +// ӡַ +void StrPrint(HString S); + +#endif diff --git a/Dev-C++/ExerciseBook/04.27/04.27.cpp b/Dev-C++/ExerciseBook/04.27/04.27.cpp new file mode 100644 index 0000000..89fb62d --- /dev/null +++ b/Dev-C++/ExerciseBook/04.27/04.27.cpp @@ -0,0 +1,81 @@ +#include +#include "SString.h" //**04 **// + +/* ԭ */ +int Algo_4_27(SString S, SString T, int pos); + + +/* + * ңIndex + * + * posʼģʽTS״γֵλãڣ򷵻0 + * ҳɹƥλá + * + *ע + * 봫ͳIndexĽ֮ڻȱȽ׸ַĩβַ + * ǶƥʱŻȽʣµַ + */ +int main(int argc, char* argv[]) { + char* s = "aaaaaaaaaaaaaaab"; + char* t = "aaaab"; + SString S, T; + + StrAssign(S, s); + StrAssign(T, t); + printf("S = "); + StrPrint(S); + printf("T = "); + StrPrint(T); + + printf("TS״γֵλΪ"); + printf("%d\n", Algo_4_27(S, T, 1)); + + return 0; +} + + +/* + * ңIndex + * + * posʼģʽTS״γֵλãڣ򷵻0 + * ҳɹƥλá + * + *ע + * 봫ͳIndexĽ֮ڻȱȽ׸ַĩβַ + * ǶƥʱŻȽʣµַ + */ +int Algo_4_27(SString S, SString T, int pos) { + int i, j; + + if(pos < 1 || pos > S[0] || T[0] == 0) { + return 0; + } + + i = pos; + j = 1; + + while(i <= S[0] - T[0] + 1) { + // ȳԱȽ׸ַĩβַ + if(S[i] != T[j] || S[i + T[0] - 1] != T[T[0]]) { + i++; + continue; + } + + // jҪT[0]ΪT[0]Ѿ֤ + for(i++,j++; j MAXSTRLEN) { + return ERROR; + } + + T[0] = len; + for(i = 1; i <= len; i++) { + T[i] = chars[i - 1]; + } + + return OK; +} + +/* + * + * + * S١ + * + *ע + * ˳򴮵Ľṹ޷ + */ +Status DestroyString(SString S) { + 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; +} + +/* + * 㷨4.1 + * + * + * + * posʼģʽTS״γֵλãڣ򷵻0 + * ҳɹƥλá + * + *ע + * 1.ʵҪСӼ + * 2.ʵֱȽϵЧ + */ +int Index_1(SString S, SString T, int pos) { + int i, n, m; // ¼STij + SString sub; + + /* + * ʧǰ + * ̲д΢ͬ + */ + if(pos < 1 || pos > S[0] || StrEmpty(T)) { + return 0; + } + + n = StrLength(S); + m = StrLength(T); + i = pos; + + // ֤ȲԽ + while(i <= n - m + 1) { + // ȡS[i, i+m-1] + SubString(sub, S, i, m); + + // Ӵģʽƥ䣬Ҫƽ + if(StrCompare(sub, T) != 0) { + ++i; + } else { + return i; + } + } + + return 0; +} + +/* + * 㷨4.5 + * + * + * + * posʼģʽTS״γֵλãڣ򷵻0 + * ҳɹƥλá + * + *ע + * 1.ʵֲСӼ + * 2.ʵֱȽϵЧ + */ +int Index_2(SString S, SString T, int pos) { + int i = pos; + int j = 1; + + if(pos < 1 || pos > S[0] || StrEmpty(T)) { + return 0; + } + + while(i <= S[0] && j <= T[0]) { + // ַͬȽϺַ + if(S[i] == T[j]) { + i++; + j++; + + // ַͬαҪˣ±Ƚ + } else { + i = i - (j - 1) + 1; // j-1ͽ͵ǰj-1ԪأڵjԪϹһ + j = 1; // αjصTĵһλ + } + } + + // һT[0]>0ж + if(j > T[0] && T[0] > 0) { // TΪմ + return i - T[0]; // ƥɹ + } else { + return 0; + } +} + +/* + * + * + * T뵽Sposλô + */ +Status StrInsert(SString S, int pos, SString T) { + int i; + + if(pos < 1 || pos > S[0] + 1 || S[0] + T[0] > MAXSTRLEN) { + return ERROR; + } + + // ĴΪգǰ + if(StrEmpty(T)) { + return OK; + } + + // SڳλãΪT׼ + for(i = S[0]; i >= pos; i--) { + // ӺǰǰԪŲ + S[i + T[0]] = S[i]; + } + + // TSڳλ + for(i = pos; i <= pos + T[0] - 1; i++) { + S[i] = T[i - pos + 1]; + } + + // + S[0] += T[0]; + + 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; +} + +/* + * 滻 + * + * V滻SгֵTȵҲصӴ + * + *ע + * 1.òСӼ + * 2.ʵֱȽϵЧ + */ +Status Replace(SString S, SString T, SString V) { + int i; + + if(StrEmpty(S) || StrEmpty(T)) { + return ERROR; + } + + // SѰģʽTһγֵλ + i = Index_2(S, T, 1); + + // ƥַҿԱȫ滻滻 + while(i != 0 && S[0] - T[0] + V[0] <= MAXSTRLEN) { + StrDelete(S, i, StrLength(T)); // SɾT + StrInsert(S, i, V); // SвV + + i += StrLength(V); // iлһλ + + i = Index_2(S, T, i); // һƥַ + } + + if(i == 0) { // SеTȫ滻 + return OK; + } else { // STVѾ岻ȥ + return ERROR; + } +} + +/* + * 㷨4.2 + * + * + * + * S1S2洢TзءӺijֻδIJ֡ + * ֵʾӺĴǷ + * + *ע + * òСӼ + */ +Status Concat(SString T, SString S1, SString S2) { + int i; + int uncut; // ´Ƿ + + // ȫҪü + if(S1[0] + S2[0] <= MAXSTRLEN) { + // S1T + for(i = 1; i <= S1[0]; i++) { + T[i] = S1[i]; + } + + // S2T + for(i = S1[0] + 1; i <= S1[0] + S2[0]; i++) { + T[i] = S2[i - S1[0]]; + } + + // ³ + T[0] = S1[0] + S2[0]; + + // δü + uncut = TRUE; + + // ҪüS2 + } else if(S1[0] <= MAXSTRLEN) { + // S1T + for(i = 1; i <= S1[0]; i++) { + T[i] = S1[i]; + } + + // S2һָƵT + for(i = S1[0] + 1; i <= MAXSTRLEN; i++) { + T[i] = S2[i - S1[0]]; + } + + // ³ + T[0] = MAXSTRLEN; + + uncut = FALSE; + + // ֻҪS1һ + } else { + // ͬϢһ + for(i = 0; i <= MAXSTRLEN; i++) { + T[i] = S1[i]; + } + + uncut = FALSE; + } + + return uncut; +} + +// ӡַ +void StrPrint(SString S) { + int i; + + for(i = 1; i<=S[0] ; i++) { + printf("%c", S[i]); + } + + printf("\n"); +} diff --git a/Dev-C++/ExerciseBook/04.27/SString.h b/Dev-C++/ExerciseBook/04.27/SString.h new file mode 100644 index 0000000..386ffb8 --- /dev/null +++ b/Dev-C++/ExerciseBook/04.27/SString.h @@ -0,0 +1,179 @@ +/*============================= + * Ķ˳洢ʾ˳򴮣 + * + * 㷨: 4.14.24.34.5 + ==============================*/ + +#ifndef SSTRING_H +#define SSTRING_H + +#include +#include // ṩstrlenԭ +#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 DestroyString(SString S); + +/* + * + * + * 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); + +/* + * 㷨4.1 + * + * + * + * posʼģʽTS״γֵλãڣ򷵻0 + * ҳɹƥλá + * + *ע + * 1.ʵҪСӼ + * 2.ʵֱȽϵЧ + */ +int Index_1(SString S, SString T, int pos); + +/* + * 㷨4.5 + * + * + * + * posʼģʽTS״γֵλãڣ򷵻0 + * ҳɹƥλá + * + *ע + * 1.ʵֲСӼ + * 2.ʵֱȽϵЧ + */ +int Index_2(SString S, SString T, int pos); + +/* + * + * + * T뵽Sposλô + */ +Status StrInsert(SString S, int pos, SString T); + +/* + * ɾ + * + * ɾ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); + +/* + * 滻 + * + * V滻SгֵTȵҲصӴ + * + *ע + * òСӼЧʽϵ͡ + */ +Status Replace(SString S, SString T, SString V); + +/* + * 㷨4.2 + * + * + * + * S1S2洢TзءӺijֻδIJ֡ + * ֵʾӺĴǷ + * + *ע + * òСӼ + */ +Status Concat(SString T, SString S1, SString S2); + +// ӡַ +void StrPrint(SString S); + +#endif diff --git a/Dev-C++/ExerciseBook/04.28-04.29/04.28-04.29.cpp b/Dev-C++/ExerciseBook/04.28-04.29/04.28-04.29.cpp new file mode 100644 index 0000000..adca0c4 --- /dev/null +++ b/Dev-C++/ExerciseBook/04.28-04.29/04.28-04.29.cpp @@ -0,0 +1,211 @@ +#include +#include +#include +#include "Status.h" //**01 **// + +/* + * ԪͶ + * + *ע + * ȻַԪȻintԭǣ + * 1.Ҫͷ洢intֱchar + * 2.charintݣԽȻintҲ洢char + */ +typedef int ElemType; + +/* ַ */ +typedef struct SNode { + ElemType chdata; // ݽ + struct SNode* succ; // ָ̽ + struct SNode* next; // nextУָǰ㣬ģʽУָý㴦ʧʱӦȽϵһ +} SNode; + +// ַ +typedef SNode* String; + + +// ʼ +Status StrAssign_4_28(String* S, char* chars); + +// 󴮳 +int StrLength_4_28(String S); + +// ַ +void StrPrint_4_28(String S); + +/* + * ģʽnextֵĽ㷨 + * + * ൱KMP㷨µget_nextval + */ +Status Algo_4_28(String T); + +/* + * KMP㷨 + * + * ൱KMP㷨µIndex_KMP + */ +int Algo_4_29(String S, String T, int pos); + + +int main(int argc, char* argv[]) { + char* s = "abaaabaababaabcaabaabcacabaabcaabaabcac"; + char* t = "abaabcac"; + String S, T; + int pos, i; + + StrAssign_4_28(&S, s); // + StrAssign_4_28(&T, t); //ģʽ + + printf("S = "); + StrPrint_4_28(S); + printf("ģʽT = "); + StrPrint_4_28(T); + + printf(" 4.28 ֤...\n"); + Algo_4_28(T); + printf("next...\n"); + + printf(" 4.29 ֤...\n"); + pos = 18; + i = Algo_4_29(S, T, pos); + printf("ģʽ T S ĵ %d ַһƥɹλΪ %d\n", pos, i); + + return 0; +} + + +// ʼ +Status StrAssign_4_28(String* S, char* chars) { + int i, len; + String p; + + if(S == NULL || chars == NULL) { + return ERROR; + } + + len = (int) strlen(chars); + + // ͷ + *S = (String) malloc(sizeof(SNode)); + (*S)->chdata = len; // ¼ij + (*S)->next = NULL; // ͷǰ + + p = *S; + + for(i = 0; i < len; i++) { + p->succ = (String) malloc(sizeof(SNode)); + p->succ->chdata = chars[i]; + p->succ->next = p; // nextĬָǰһ + p = p->succ; + } + + // һĺΪNULL + p->succ = NULL; + + return OK; +} + +// 󴮳 +int StrLength_4_28(String S) { + return S == NULL ? 0 : S->chdata; +} + +// ַ +void StrPrint_4_28(String S) { + String p; + + if(S == NULL) { + printf("\n"); + return; + } + + for(p = S->succ; p != NULL; p = p->succ) { + printf("%c", p->chdata); + } + + printf("\n"); +} + +/* + * ģʽnextֵĽ㷨 + * + * ൱KMP㷨µget_nextval + */ +Status Algo_4_28(String T) { + SNode* i, * j; + + if(StrLength_4_28(T) == 0) { + return ERROR; + } + + i = T->succ; // ൱֮ǰi=1 + j = T; // ൱֮ǰj=0 + + // ģʽһַʧʱģʽҪͷȽϣҪǰһλñȽ + i->next = T; + + // ģʽϵַ + while(i->succ != NULL) { + if(j == T || i->chdata == j->chdata) { + i = i->succ; + j = j->succ; + + if(i->chdata != j->chdata) { + i->next = j; + } else { + i->next = j->next; + } + } else { + j = j->next; + } + } + + return OK; +} + +/* + * KMP㷨 + * + * ൱KMP㷨µIndex_KMP + */ +int Algo_4_29(String S, String T, int pos) { + int count; // ¼iλ + SNode* i, * j; // iSjT + + if(pos < 1 || StrLength_4_28(S) == 0 || StrLength_4_28(T) == 0) { + return 0; + } + + for(count = 1, i = S->succ; count < pos; count++, i = i->succ) { + // iָpos + } + + j = T->succ; + + // Ƚַ + while(i != NULL && j != NULL) { + /* + * Σ + * 1.ģʽĵһַʧ + * 2.ģʽַ + */ + if(j == T || i->chdata == j->chdata) { + i = i->succ; + j = j->succ; + + count++; // ¼iλ + } else { + // ʧʱصǰһʵλ + j = j->next; + } + } + + // ƥɹƥλ + if(j == NULL) { + return count-StrLength_4_28(T); + } else { + // ƥʧ + return 0; + } +} diff --git a/Dev-C++/ExerciseBook/04.28-04.29/04.28-04.29.dev b/Dev-C++/ExerciseBook/04.28-04.29/04.28-04.29.dev new file mode 100644 index 0000000..9228e85 --- /dev/null +++ b/Dev-C++/ExerciseBook/04.28-04.29/04.28-04.29.dev @@ -0,0 +1,62 @@ +[Project] +FileName=04.28-04.29.dev +Name=04.28-04.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=1 + +[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=04.28-04.29.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + diff --git a/Dev-C++/ExerciseBook/04.30/04.30.cpp b/Dev-C++/ExerciseBook/04.30/04.30.cpp new file mode 100644 index 0000000..eb772c7 --- /dev/null +++ b/Dev-C++/ExerciseBook/04.30/04.30.cpp @@ -0,0 +1,116 @@ +#include +#include "SString.h" //**04 **// + +/* + * ڴSв״γֵظӴλ + * Sub¼ظӴ + * pos¼Sгֵλ + * + * ˴ظӴº壺 + * 1.Ӵ + * 2.ӴظӴ׸ģ + * 3.ӴصȡabcabcaĽΪabca + * 4.ӴڿظȡaaaaĽΪaaa + */ +Status Algo_4_30(SString S, SString Sub, int* pos); + + +int main(int argc, char* argv[]) { + char* s = "abcdeabcabcbcdefbcdefefghefgh"; + SString Sub, S; + int pos; + + StrAssign(S, s); + printf("...\n"); + printf("S = "); + StrPrint(S); + + printf("׸ظӴ...\n"); + printf("Sub = "); + Algo_4_30(S, Sub, &pos); + StrPrint(Sub); + printf("Sub S ״γֵλΪ %d\n", pos); + + return 0; +} + + +/* + * ڴSв״γֵظӴλ + * Sub¼ظӴ + * pos¼Sгֵλ + * + * ˴ظӴº壺 + * 1.Ӵ + * 2.ӴظӴ׸ģ + * 3.ӴصȡabcabcaĽΪabca + * 4.ӴڿظȡaaaaĽΪaaa + */ +Status Algo_4_30(SString S, SString Sub, int* pos) { + int i, j, is, js; + int k, start; + int len, maxLen; + + // Ȳ2 + if(S[0] < 2) { + return ERROR; + } + + start = 0; + maxLen = 0; + + // пܵ + for(k = 1; k < S[0]; k++) { + is = k; // + js = k + 1; // Ӵ + + // ʣַ֪ظַٱȥ + if(S[0] - js + 1 <= maxLen) { + break; + } + + // isΪĴظĴ + while(TRUE) { + // ѰDZڵظӴ + while(js <= S[0] && S[is] != S[js]) { + js++; + } + + // ˵㴦ַΨһ + if(js > S[0]) { + break; + } + + // ʣַ֪ظַٱȥ + if(S[0] - js + 1 <= maxLen) { + break; + } + + len = 0; + i = is; + j = js; + + // ظij + while(j <= S[0] && S[i] == S[j]) { + i++; + j++; + len++; + } + + if(len > maxLen) { + start = k; + maxLen = len; + } + + // 鿴ûиظ + if(j < S[0]) { + js++; + } + } + } + + *pos = start; + SubString(Sub, S, start, maxLen); + + return OK; +} diff --git a/Dev-C++/ExerciseBook/04.30/04.30.dev b/Dev-C++/ExerciseBook/04.30/04.30.dev new file mode 100644 index 0000000..db37f3d --- /dev/null +++ b/Dev-C++/ExerciseBook/04.30/04.30.dev @@ -0,0 +1,82 @@ +[Project] +FileName=04.30.dev +Name=04.30 +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=SString.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit1] +FileName=04.30.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit3] +FileName=SString.h +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + diff --git a/Dev-C++/ExerciseBook/04.30/SString.cpp b/Dev-C++/ExerciseBook/04.30/SString.cpp new file mode 100644 index 0000000..fc4c757 --- /dev/null +++ b/Dev-C++/ExerciseBook/04.30/SString.cpp @@ -0,0 +1,406 @@ +/*============================= + * Ķ˳洢ʾ˳򴮣 + * + * 㷨: 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 DestroyString(SString S) { + 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; +} + +/* + * 㷨4.1 + * + * + * + * posʼģʽTS״γֵλãڣ򷵻0 + * ҳɹƥλá + * + *ע + * 1.ʵҪСӼ + * 2.ʵֱȽϵЧ + */ +int Index_1(SString S, SString T, int pos) { + int i, n, m; // ¼STij + SString sub; + + /* + * ʧǰ + * ̲д΢ͬ + */ + if(pos < 1 || pos > S[0] || StrEmpty(T)) { + return 0; + } + + n = StrLength(S); + m = StrLength(T); + i = pos; + + // ֤ȲԽ + while(i <= n - m + 1) { + // ȡS[i, i+m-1] + SubString(sub, S, i, m); + + // Ӵģʽƥ䣬Ҫƽ + if(StrCompare(sub, T) != 0) { + ++i; + } else { + return i; + } + } + + return 0; +} + +/* + * 㷨4.5 + * + * + * + * posʼģʽTS״γֵλãڣ򷵻0 + * ҳɹƥλá + * + *ע + * 1.ʵֲСӼ + * 2.ʵֱȽϵЧ + */ +int Index_2(SString S, SString T, int pos) { + int i = pos; + int j = 1; + + if(pos < 1 || pos > S[0] || StrEmpty(T)) { + return 0; + } + + while(i <= S[0] && j <= T[0]) { + // ַͬȽϺַ + if(S[i] == T[j]) { + i++; + j++; + + // ַͬαҪˣ±Ƚ + } else { + i = i - (j - 1) + 1; // j-1ͽ͵ǰj-1ԪأڵjԪϹһ + j = 1; // αjصTĵһλ + } + } + + // һT[0]>0ж + if(j > T[0] && T[0] > 0) { // TΪմ + return i - T[0]; // ƥɹ + } else { + return 0; + } +} + +/* + * + * + * T뵽Sposλô + */ +Status StrInsert(SString S, int pos, SString T) { + int i; + + if(pos < 1 || pos > S[0] + 1 || S[0] + T[0] > MAXSTRLEN) { + return ERROR; + } + + // ĴΪգǰ + if(StrEmpty(T)) { + return OK; + } + + // SڳλãΪT׼ + for(i = S[0]; i >= pos; i--) { + // ӺǰǰԪŲ + S[i + T[0]] = S[i]; + } + + // TSڳλ + for(i = pos; i <= pos + T[0] - 1; i++) { + S[i] = T[i - pos + 1]; + } + + // + S[0] += T[0]; + + 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; +} + +/* + * 滻 + * + * V滻SгֵTȵҲصӴ + * + *ע + * 1.òСӼ + * 2.ʵֱȽϵЧ + */ +Status Replace(SString S, SString T, SString V) { + int i; + + if(StrEmpty(S) || StrEmpty(T)) { + return ERROR; + } + + // SѰģʽTһγֵλ + i = Index_2(S, T, 1); + + // ƥַҿԱȫ滻滻 + while(i != 0 && S[0] - T[0] + V[0] <= MAXSTRLEN) { + StrDelete(S, i, StrLength(T)); // SɾT + StrInsert(S, i, V); // SвV + + i += StrLength(V); // iлһλ + + i = Index_2(S, T, i); // һƥַ + } + + if(i == 0) { // SеTȫ滻 + return OK; + } else { // STVѾ岻ȥ + return ERROR; + } +} + +/* + * 㷨4.2 + * + * + * + * S1S2洢TзءӺijֻδIJ֡ + * ֵʾӺĴǷ + * + *ע + * òСӼ + */ +Status Concat(SString T, SString S1, SString S2) { + int i; + int uncut; // ´Ƿ + + // ȫҪü + if(S1[0] + S2[0] <= MAXSTRLEN) { + // S1T + for(i = 1; i <= S1[0]; i++) { + T[i] = S1[i]; + } + + // S2T + for(i = S1[0] + 1; i <= S1[0] + S2[0]; i++) { + T[i] = S2[i - S1[0]]; + } + + // ³ + T[0] = S1[0] + S2[0]; + + // δü + uncut = TRUE; + + // ҪüS2 + } else if(S1[0] <= MAXSTRLEN) { + // S1T + for(i = 1; i <= S1[0]; i++) { + T[i] = S1[i]; + } + + // S2һָƵT + for(i = S1[0] + 1; i <= MAXSTRLEN; i++) { + T[i] = S2[i - S1[0]]; + } + + // ³ + T[0] = MAXSTRLEN; + + uncut = FALSE; + + // ֻҪS1һ + } else { + // ͬϢһ + for(i = 0; i <= MAXSTRLEN; i++) { + T[i] = S1[i]; + } + + uncut = FALSE; + } + + return uncut; +} + +// ӡַ +void StrPrint(SString S) { + int i; + + for(i = 1; i<=S[0] ; i++) { + printf("%c", S[i]); + } + + printf("\n"); +} diff --git a/Dev-C++/ExerciseBook/04.30/SString.h b/Dev-C++/ExerciseBook/04.30/SString.h new file mode 100644 index 0000000..386ffb8 --- /dev/null +++ b/Dev-C++/ExerciseBook/04.30/SString.h @@ -0,0 +1,179 @@ +/*============================= + * Ķ˳洢ʾ˳򴮣 + * + * 㷨: 4.14.24.34.5 + ==============================*/ + +#ifndef SSTRING_H +#define SSTRING_H + +#include +#include // ṩstrlenԭ +#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 DestroyString(SString S); + +/* + * + * + * 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); + +/* + * 㷨4.1 + * + * + * + * posʼģʽTS״γֵλãڣ򷵻0 + * ҳɹƥλá + * + *ע + * 1.ʵҪСӼ + * 2.ʵֱȽϵЧ + */ +int Index_1(SString S, SString T, int pos); + +/* + * 㷨4.5 + * + * + * + * posʼģʽTS״γֵλãڣ򷵻0 + * ҳɹƥλá + * + *ע + * 1.ʵֲСӼ + * 2.ʵֱȽϵЧ + */ +int Index_2(SString S, SString T, int pos); + +/* + * + * + * T뵽Sposλô + */ +Status StrInsert(SString S, int pos, SString T); + +/* + * ɾ + * + * ɾ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); + +/* + * 滻 + * + * V滻SгֵTȵҲصӴ + * + *ע + * òСӼЧʽϵ͡ + */ +Status Replace(SString S, SString T, SString V); + +/* + * 㷨4.2 + * + * + * + * S1S2洢TзءӺijֻδIJ֡ + * ֵʾӺĴǷ + * + *ע + * òСӼ + */ +Status Concat(SString T, SString S1, SString S2); + +// ӡַ +void StrPrint(SString S); + +#endif diff --git a/Dev-C++/ExerciseBook/04.31/04.31.cpp b/Dev-C++/ExerciseBook/04.31/04.31.cpp new file mode 100644 index 0000000..91ede0d --- /dev/null +++ b/Dev-C++/ExerciseBook/04.31/04.31.cpp @@ -0,0 +1,248 @@ +#include +#include +#include "Status.h" //**01 **// +#include "SString.h" //**04 **// + +/* + * ʾ + * + * һ̬滮⣬ϸ˼·μ㷨ۡ15.4ڡ + * + * ע㷨ۡе""ͳƲӴDZֻͳӴ + */ + + +/* Ӵ */ +typedef struct { + char dir; + int len; +} LCS; + +/* Ӵ */ +typedef struct { + int s; // ӴڴSеλ + int t; // ӴڴTеλ +} Pos; + +/* Ӵ */ +typedef struct { + int maxlen; // Ӵij + Pos* pos; // Ӵ + int count; // Ӵ +} Strs; + + +/* + * STеӴ + * + * УıΪ"һֵӴ" + */ +Status Algo_4_31(SString S, SString T); + +/* + * ȡӴϢ + */ +void LocationPos(SString S, SString T, Strs* strs); + +/* + * ӴȡӴijȡ + */ +Status BuildLCS(SString S, SString T, LCS*** lcs, int* maxLen); + +/* + * ӡӴѡ + */ +void PrintLCS(SString S, SString T, LCS** lcs); + + +int main(int argc, char* argv[]) { + char* s = "csajcu123456ewjfskhsdufasawx"; + char* t = "m123456vsadksjewjfshcdsdufassgcx"; + SString S, T; + + StrAssign(S, s); + StrAssign(T, t); + + Algo_4_31(S, T); + + return 0; +} + + +/* + * STеӴ + * + * УıΪ"һֵӴ" + */ +Status Algo_4_31(SString S, SString T) { + Strs strs; + SString sub; + int i; + + LocationPos(S, T, &strs); + + printf("ӴijΪ%d \n", strs.maxlen); + printf("Ӵ꣺\n"); + for(i=0; i=size) { + size += 10; + (*strs).pos = (Pos*) realloc((*strs).pos, size * sizeof(Pos)); + } + + (*strs).pos[(*strs).count].s = i-maxLen+1; + (*strs).pos[(*strs).count].t = j-maxLen+1; + (*strs).count++; + } + } +} + +/* + * ӴȡӴijȡ + */ +Status BuildLCS(SString S, SString T, LCS*** lcs, int* maxLen) { + int sLen, tLen; + int i, j; + int max; + LCS node; + + sLen = StrLength(S); + tLen = StrLength(T); + + if(sLen == 0 || tLen == 0) { + return ERROR; + } + + // ʼLCS + *lcs = (LCS**) malloc((sLen + 1) * sizeof(LCS*)); + for(i = 0; i <= sLen; i++) { + (*lcs)[i] = (LCS*) malloc((tLen + 1) * sizeof(LCS)); + } + + for(i = 0; i <= sLen; i++) { + (*lcs)[i][0].dir = ' '; + (*lcs)[i][0].len = 0; + } + + for(j = 0; j <= tLen; j++) { + (*lcs)[0][j].dir = ' '; + (*lcs)[0][j].len = 0; + } + + max = 0; + + for(i = 1; i <= sLen; i++) { + for(j = 1; j <= tLen; j++) { + // 롶㷨ۡеĽ΢ͬ˴ҪͳӴ + if(S[i] == T[j]) { + // ǰһַҲȣ˵ǸĹӴ + if(i > 1 && j > 1 && S[i - 1] == T[j - 1]) { + node.dir = '\\'; + node.len = (*lcs)[i - 1][j - 1].len + 1; + + // Ͽ + } else { + node.dir = ' '; + node.len = 1; + } + + if(node.len > max) { + max = node.len; + } + } else { + if((*lcs)[i - 1][j].len >= (*lcs)[i][j - 1].dir) { + node.dir = '^'; + node.len = (*lcs)[i - 1][j].len; + } else { + node.dir = '<'; + node.len = (*lcs)[i][j - 1].len; + } + } + + (*lcs)[i][j] = node; + } + } + + *maxLen = max; + + return ERROR; +} + +/* + * ӡӴѡ + */ +void PrintLCS(SString S, SString T, LCS** lcs) { + int sLen, tLen; + int i, j; + + sLen = StrLength(S); + tLen = StrLength(T); + + if(sLen == 0 || tLen == 0) { + return; + } + + // һ + printf(" "); + for(j = 1; j <= tLen; j++) { + printf(" %c ", T[j]); + } + printf("\n"); + + // ڶ + printf(" "); + for(j = 1; j <= tLen; j++) { + printf("--- "); + } + printf("\n"); + + for(i = 1; i <= sLen; i++) { + for(j = 1; j <= tLen; j++) { + // ÿһеĿʼ + if(j == 1) { + printf("%c |", S[i]); + } + + printf("%c%2d ", lcs[i][j].dir, lcs[i][j].len); + } + printf("\n"); + } + + printf("\n"); +} diff --git a/Dev-C++/ExerciseBook/04.31/04.31.dev b/Dev-C++/ExerciseBook/04.31/04.31.dev new file mode 100644 index 0000000..ba549f4 --- /dev/null +++ b/Dev-C++/ExerciseBook/04.31/04.31.dev @@ -0,0 +1,82 @@ +[Project] +FileName=04.31.dev +Name=04.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=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=SString.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit1] +FileName=04.31.cpp +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit3] +FileName=SString.h +CompileCpp=0 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + diff --git a/Dev-C++/ExerciseBook/04.31/SString.cpp b/Dev-C++/ExerciseBook/04.31/SString.cpp new file mode 100644 index 0000000..fc4c757 --- /dev/null +++ b/Dev-C++/ExerciseBook/04.31/SString.cpp @@ -0,0 +1,406 @@ +/*============================= + * Ķ˳洢ʾ˳򴮣 + * + * 㷨: 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 DestroyString(SString S) { + 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; +} + +/* + * 㷨4.1 + * + * + * + * posʼģʽTS״γֵλãڣ򷵻0 + * ҳɹƥλá + * + *ע + * 1.ʵҪСӼ + * 2.ʵֱȽϵЧ + */ +int Index_1(SString S, SString T, int pos) { + int i, n, m; // ¼STij + SString sub; + + /* + * ʧǰ + * ̲д΢ͬ + */ + if(pos < 1 || pos > S[0] || StrEmpty(T)) { + return 0; + } + + n = StrLength(S); + m = StrLength(T); + i = pos; + + // ֤ȲԽ + while(i <= n - m + 1) { + // ȡS[i, i+m-1] + SubString(sub, S, i, m); + + // Ӵģʽƥ䣬Ҫƽ + if(StrCompare(sub, T) != 0) { + ++i; + } else { + return i; + } + } + + return 0; +} + +/* + * 㷨4.5 + * + * + * + * posʼģʽTS״γֵλãڣ򷵻0 + * ҳɹƥλá + * + *ע + * 1.ʵֲСӼ + * 2.ʵֱȽϵЧ + */ +int Index_2(SString S, SString T, int pos) { + int i = pos; + int j = 1; + + if(pos < 1 || pos > S[0] || StrEmpty(T)) { + return 0; + } + + while(i <= S[0] && j <= T[0]) { + // ַͬȽϺַ + if(S[i] == T[j]) { + i++; + j++; + + // ַͬαҪˣ±Ƚ + } else { + i = i - (j - 1) + 1; // j-1ͽ͵ǰj-1ԪأڵjԪϹһ + j = 1; // αjصTĵһλ + } + } + + // һT[0]>0ж + if(j > T[0] && T[0] > 0) { // TΪմ + return i - T[0]; // ƥɹ + } else { + return 0; + } +} + +/* + * + * + * T뵽Sposλô + */ +Status StrInsert(SString S, int pos, SString T) { + int i; + + if(pos < 1 || pos > S[0] + 1 || S[0] + T[0] > MAXSTRLEN) { + return ERROR; + } + + // ĴΪգǰ + if(StrEmpty(T)) { + return OK; + } + + // SڳλãΪT׼ + for(i = S[0]; i >= pos; i--) { + // ӺǰǰԪŲ + S[i + T[0]] = S[i]; + } + + // TSڳλ + for(i = pos; i <= pos + T[0] - 1; i++) { + S[i] = T[i - pos + 1]; + } + + // + S[0] += T[0]; + + 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; +} + +/* + * 滻 + * + * V滻SгֵTȵҲصӴ + * + *ע + * 1.òСӼ + * 2.ʵֱȽϵЧ + */ +Status Replace(SString S, SString T, SString V) { + int i; + + if(StrEmpty(S) || StrEmpty(T)) { + return ERROR; + } + + // SѰģʽTһγֵλ + i = Index_2(S, T, 1); + + // ƥַҿԱȫ滻滻 + while(i != 0 && S[0] - T[0] + V[0] <= MAXSTRLEN) { + StrDelete(S, i, StrLength(T)); // SɾT + StrInsert(S, i, V); // SвV + + i += StrLength(V); // iлһλ + + i = Index_2(S, T, i); // һƥַ + } + + if(i == 0) { // SеTȫ滻 + return OK; + } else { // STVѾ岻ȥ + return ERROR; + } +} + +/* + * 㷨4.2 + * + * + * + * S1S2洢TзءӺijֻδIJ֡ + * ֵʾӺĴǷ + * + *ע + * òСӼ + */ +Status Concat(SString T, SString S1, SString S2) { + int i; + int uncut; // ´Ƿ + + // ȫҪü + if(S1[0] + S2[0] <= MAXSTRLEN) { + // S1T + for(i = 1; i <= S1[0]; i++) { + T[i] = S1[i]; + } + + // S2T + for(i = S1[0] + 1; i <= S1[0] + S2[0]; i++) { + T[i] = S2[i - S1[0]]; + } + + // ³ + T[0] = S1[0] + S2[0]; + + // δü + uncut = TRUE; + + // ҪüS2 + } else if(S1[0] <= MAXSTRLEN) { + // S1T + for(i = 1; i <= S1[0]; i++) { + T[i] = S1[i]; + } + + // S2һָƵT + for(i = S1[0] + 1; i <= MAXSTRLEN; i++) { + T[i] = S2[i - S1[0]]; + } + + // ³ + T[0] = MAXSTRLEN; + + uncut = FALSE; + + // ֻҪS1һ + } else { + // ͬϢһ + for(i = 0; i <= MAXSTRLEN; i++) { + T[i] = S1[i]; + } + + uncut = FALSE; + } + + return uncut; +} + +// ӡַ +void StrPrint(SString S) { + int i; + + for(i = 1; i<=S[0] ; i++) { + printf("%c", S[i]); + } + + printf("\n"); +} diff --git a/Dev-C++/ExerciseBook/04.31/SString.h b/Dev-C++/ExerciseBook/04.31/SString.h new file mode 100644 index 0000000..386ffb8 --- /dev/null +++ b/Dev-C++/ExerciseBook/04.31/SString.h @@ -0,0 +1,179 @@ +/*============================= + * Ķ˳洢ʾ˳򴮣 + * + * 㷨: 4.14.24.34.5 + ==============================*/ + +#ifndef SSTRING_H +#define SSTRING_H + +#include +#include // ṩstrlenԭ +#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 DestroyString(SString S); + +/* + * + * + * 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); + +/* + * 㷨4.1 + * + * + * + * posʼģʽTS״γֵλãڣ򷵻0 + * ҳɹƥλá + * + *ע + * 1.ʵҪСӼ + * 2.ʵֱȽϵЧ + */ +int Index_1(SString S, SString T, int pos); + +/* + * 㷨4.5 + * + * + * + * posʼģʽTS״γֵλãڣ򷵻0 + * ҳɹƥλá + * + *ע + * 1.ʵֲСӼ + * 2.ʵֱȽϵЧ + */ +int Index_2(SString S, SString T, int pos); + +/* + * + * + * T뵽Sposλô + */ +Status StrInsert(SString S, int pos, SString T); + +/* + * ɾ + * + * ɾ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); + +/* + * 滻 + * + * V滻SгֵTȵҲصӴ + * + *ע + * òСӼЧʽϵ͡ + */ +Status Replace(SString S, SString T, SString V); + +/* + * 㷨4.2 + * + * + * + * S1S2洢TзءӺijֻδIJ֡ + * ֵʾӺĴǷ + * + *ע + * òСӼ + */ +Status Concat(SString T, SString S1, SString S2); + +// ӡַ +void StrPrint(SString S); + +#endif diff --git a/VisualC++/ExerciseBook/04.10/04.10.c b/VisualC++/ExerciseBook/04.10/04.10.c new file mode 100644 index 0000000..5a98ea3 --- /dev/null +++ b/VisualC++/ExerciseBook/04.10/04.10.c @@ -0,0 +1,35 @@ +#include +#include "String.h" //**ַ**// + +/* + * ַãTΪR + */ +StringType Algo_4_10(StringType T) { + int i; + StringType R = "", Sub; + + // Ӻǰȡַ + for(i = StrLength(T); i >= 1; i--) { + Sub = SubString(T, i, 1); + R = Concat(R, Sub); + } + + return R; +} + + +int main(int argc, char* argv[]) { + char* s = "0123456789"; + StringType T, R; + + printf("ǰT = "); + StrAssign(&T, s); + StrPrint(T); + + printf("úR = "); + R = Algo_4_10(T); + StrPrint(R); + + return 0; +} + diff --git a/VisualC++/ExerciseBook/04.10/04.10.vcxproj b/VisualC++/ExerciseBook/04.10/04.10.vcxproj new file mode 100644 index 0000000..12e09b5 --- /dev/null +++ b/VisualC++/ExerciseBook/04.10/04.10.vcxproj @@ -0,0 +1,76 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {84E5A31E-0EC6-4747-8B3D-BAFF28320A58} + My0410 + + + + 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/04.10/04.10.vcxproj.filters b/VisualC++/ExerciseBook/04.10/04.10.vcxproj.filters new file mode 100644 index 0000000..5e9d56e --- /dev/null +++ b/VisualC++/ExerciseBook/04.10/04.10.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/04.10/04.10.vcxproj.user b/VisualC++/ExerciseBook/04.10/04.10.vcxproj.user new file mode 100644 index 0000000..ace9a86 --- /dev/null +++ b/VisualC++/ExerciseBook/04.10/04.10.vcxproj.user @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/04.10/String.c b/VisualC++/ExerciseBook/04.10/String.c new file mode 100644 index 0000000..41df51c --- /dev/null +++ b/VisualC++/ExerciseBook/04.10/String.c @@ -0,0 +1,151 @@ +/*=========================== + * ϰ4.10~4.14ʹõַ + ============================*/ + +#include "String.h" + +// ʼһֵΪsĴt +void StrAssign(StringType* t, const char* s) { + if(s == NULL) { + *t = ""; + } + + *t = (char*) malloc((strlen(s) + 1) * sizeof(char)); + + strcpy(*t, s); +} + +// ȽϣstĴССһ£0 +int StrCompare(StringType s, StringType t) { + return strcmp(s, t); +} + +// ַsij +int StrLength(StringType s) { + return (int) strlen(s); +} + +// ӣstӺĴ +StringType Concat(StringType s, StringType t) { + StringType r; + + if(s == NULL) { + s = ""; + } + + if(t == NULL) { + t = ""; + } + + r = (char*) malloc((strlen(s) + strlen(t) + 1) * sizeof(char)); + r[0] = '\0'; + + strcat(r, s); + strcat(r, t); + + return r; +} + +// Ӵsstartλ𣬽ȡlenַ󷵻 +StringType SubString(StringType s, int start, int len) { + int n; + char* sub; + + n = (int) strlen(s); + + if(start < 1 || start > n || start + len - 1 > n || len < 0) { + return ""; + } + + sub = (char*) malloc((len + 1) * sizeof(char)); + strncpy(sub, s + start - 1, len); + sub[len] = '\0'; + + return sub; +} + +// ңsposλtҵλ +int Index(StringType s, StringType t, int pos) { + int m, n, i; + StringType sub; + + // ʧǰ + if(pos < 1 || pos > StrLength(s) || StrLength(t) == 0) { + return 0; + } + + n = StrLength(s); + m = StrLength(t); + i = pos; + + // ֤ȲԽ + while(i <= n - m + 1) { + // ȡS[i, i+m-1] + sub = SubString(s, i, m); + + // Ӵģʽƥ䣬Ҫƽ + if(StrCompare(sub, t) != 0) { + ++i; + } else { + return i; + } + } + + return 0; +} + +// 룺spost +Status StrInsert(StringType* s, int pos, StringType t) { + StringType r; + StringType s1, s2; + + if(pos < 1 || pos > StrLength(*s) + 1) { + return ERROR; + } + + r = (StringType) malloc((strlen(*s) + strlen(t) + 1) * sizeof(char)); + r[0] = '\0'; + + // ĴΪգǰ + if(StrLength(t) == 0) { + return OK; + } + + s1 = SubString(*s, 1, pos - 1); + s2 = SubString(*s, pos, (int) strlen(*s) - pos + 1); + + strcat(r, s1); + strcat(r, t); + strcat(r, s2); + + *s = r; + + return OK; +} + +// ɾsposλɾlenַ +Status StrDelete(StringType* s, int pos, int len) { + StringType r; + + if(pos < 1 || pos + len - 1 > StrLength(*s) || len < 0) { + return ERROR; + } + + // ɾijΪ0ǰ + if(len == 0) { + return OK; + } + + r = (StringType) malloc((StrLength(*s) - len + 1) * sizeof(char)); + strncpy(r, *s, pos - 1); + strcpy(r + pos - 1, *s + pos + len - 1); + + *s = r; + + return OK; +} + +// ַ +void StrPrint(StringType s) { + printf("%s\n", s); +} diff --git a/VisualC++/ExerciseBook/04.10/String.h b/VisualC++/ExerciseBook/04.10/String.h new file mode 100644 index 0000000..9d984af --- /dev/null +++ b/VisualC++/ExerciseBook/04.10/String.h @@ -0,0 +1,43 @@ +/*=========================== + * ϰ4.10~4.14ʹõַ + ============================*/ + +#ifndef STRING_H +#define STRING_H + +#include +#include // ṩ strlen ԭ +#include "Status.h" //**01 **// + +/* ַ */ +typedef char* StringType; + + +// ʼһֵΪsĴt +void StrAssign(StringType* t, const char* s); + +// ȽϣstĴССһ£0 +int StrCompare(StringType s, StringType t); + +// ַsij +int StrLength(StringType s); + +// ӣstӺĴ +StringType Concat(StringType s, StringType t); + +// Ӵsstartλ𣬽ȡlenַ󷵻 +StringType SubString(StringType s, int start, int len); + +// ңsposλtҵλ +int Index(StringType s, StringType t, int pos); + +// 룺spost +Status StrInsert(StringType* s, int pos, StringType t); + +// ɾsposλɾlenַ +Status StrDelete(StringType* s, int pos, int len); + +// ַ +void StrPrint(StringType s); + +#endif diff --git a/VisualC++/ExerciseBook/04.11/04.11.c b/VisualC++/ExerciseBook/04.11/04.11.c new file mode 100644 index 0000000..7dd1b18 --- /dev/null +++ b/VisualC++/ExerciseBook/04.11/04.11.c @@ -0,0 +1,69 @@ +#include +#include +#include "String.h" //**ַ**// + +/* + * R=S-STa洢RÿַSеһγֵλ + * + * עa0ŵԪ洢aԪصĸ + */ +void Algo_4_11(StringType* R, StringType S, StringType T, int** a) { + int i, p; + StringType ch; + + *a = (int*) malloc((StrLength(S) + 1) * sizeof(int)); + + StrAssign(R, ""); + + for(i = 1, (*a)[0] = 0; i <= StrLength(S); i++) { + // ȡַж + ch = SubString(S, i, 1); + + // ȡS[i]Tеλ + p = Index(T, ch, 1); + + // S[i]T + if(p == 0) { + // ȡS[i]Rеλ + p = Index(*R, ch, 1); + } + + // S[i]ȲTУûRгֹ + if(p == 0) { + (*a)[0]++; + (*a)[(*a)[0]] = i; + + // RS[i] + StrInsert(R, (*a)[0], ch); + } + } +} + + +int main(int argc, char* argv[]) { + char* s = "amdhcjgfdlpinbefcopgkqikeb"; + char* t = "mhjlpinopkqik"; + int* a; + StringType T, S, R; + int i; + + printf("ʼST...\n"); + StrAssign(&S, s); + StrAssign(&T, t); + printf("S = "); + StrPrint(S); + printf("T = "); + StrPrint(T); + + Algo_4_11(&R, S, T, &a); + printf("R = "); + StrPrint(R); + + printf("a = "); + for(i = 1; i <= a[0]; i++) { + printf("%d ", a[i]); + } + printf("\n"); + + return 0; +} diff --git a/VisualC++/ExerciseBook/04.11/04.11.vcxproj b/VisualC++/ExerciseBook/04.11/04.11.vcxproj new file mode 100644 index 0000000..e7df4b3 --- /dev/null +++ b/VisualC++/ExerciseBook/04.11/04.11.vcxproj @@ -0,0 +1,76 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {403165BF-098D-4F09-87F3-9B2599D663A5} + My0411 + + + + 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/04.11/04.11.vcxproj.filters b/VisualC++/ExerciseBook/04.11/04.11.vcxproj.filters new file mode 100644 index 0000000..ac9f872 --- /dev/null +++ b/VisualC++/ExerciseBook/04.11/04.11.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/04.11/04.11.vcxproj.user b/VisualC++/ExerciseBook/04.11/04.11.vcxproj.user new file mode 100644 index 0000000..ace9a86 --- /dev/null +++ b/VisualC++/ExerciseBook/04.11/04.11.vcxproj.user @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/04.11/String.c b/VisualC++/ExerciseBook/04.11/String.c new file mode 100644 index 0000000..41df51c --- /dev/null +++ b/VisualC++/ExerciseBook/04.11/String.c @@ -0,0 +1,151 @@ +/*=========================== + * ϰ4.10~4.14ʹõַ + ============================*/ + +#include "String.h" + +// ʼһֵΪsĴt +void StrAssign(StringType* t, const char* s) { + if(s == NULL) { + *t = ""; + } + + *t = (char*) malloc((strlen(s) + 1) * sizeof(char)); + + strcpy(*t, s); +} + +// ȽϣstĴССһ£0 +int StrCompare(StringType s, StringType t) { + return strcmp(s, t); +} + +// ַsij +int StrLength(StringType s) { + return (int) strlen(s); +} + +// ӣstӺĴ +StringType Concat(StringType s, StringType t) { + StringType r; + + if(s == NULL) { + s = ""; + } + + if(t == NULL) { + t = ""; + } + + r = (char*) malloc((strlen(s) + strlen(t) + 1) * sizeof(char)); + r[0] = '\0'; + + strcat(r, s); + strcat(r, t); + + return r; +} + +// Ӵsstartλ𣬽ȡlenַ󷵻 +StringType SubString(StringType s, int start, int len) { + int n; + char* sub; + + n = (int) strlen(s); + + if(start < 1 || start > n || start + len - 1 > n || len < 0) { + return ""; + } + + sub = (char*) malloc((len + 1) * sizeof(char)); + strncpy(sub, s + start - 1, len); + sub[len] = '\0'; + + return sub; +} + +// ңsposλtҵλ +int Index(StringType s, StringType t, int pos) { + int m, n, i; + StringType sub; + + // ʧǰ + if(pos < 1 || pos > StrLength(s) || StrLength(t) == 0) { + return 0; + } + + n = StrLength(s); + m = StrLength(t); + i = pos; + + // ֤ȲԽ + while(i <= n - m + 1) { + // ȡS[i, i+m-1] + sub = SubString(s, i, m); + + // Ӵģʽƥ䣬Ҫƽ + if(StrCompare(sub, t) != 0) { + ++i; + } else { + return i; + } + } + + return 0; +} + +// 룺spost +Status StrInsert(StringType* s, int pos, StringType t) { + StringType r; + StringType s1, s2; + + if(pos < 1 || pos > StrLength(*s) + 1) { + return ERROR; + } + + r = (StringType) malloc((strlen(*s) + strlen(t) + 1) * sizeof(char)); + r[0] = '\0'; + + // ĴΪգǰ + if(StrLength(t) == 0) { + return OK; + } + + s1 = SubString(*s, 1, pos - 1); + s2 = SubString(*s, pos, (int) strlen(*s) - pos + 1); + + strcat(r, s1); + strcat(r, t); + strcat(r, s2); + + *s = r; + + return OK; +} + +// ɾsposλɾlenַ +Status StrDelete(StringType* s, int pos, int len) { + StringType r; + + if(pos < 1 || pos + len - 1 > StrLength(*s) || len < 0) { + return ERROR; + } + + // ɾijΪ0ǰ + if(len == 0) { + return OK; + } + + r = (StringType) malloc((StrLength(*s) - len + 1) * sizeof(char)); + strncpy(r, *s, pos - 1); + strcpy(r + pos - 1, *s + pos + len - 1); + + *s = r; + + return OK; +} + +// ַ +void StrPrint(StringType s) { + printf("%s\n", s); +} diff --git a/VisualC++/ExerciseBook/04.11/String.h b/VisualC++/ExerciseBook/04.11/String.h new file mode 100644 index 0000000..9d984af --- /dev/null +++ b/VisualC++/ExerciseBook/04.11/String.h @@ -0,0 +1,43 @@ +/*=========================== + * ϰ4.10~4.14ʹõַ + ============================*/ + +#ifndef STRING_H +#define STRING_H + +#include +#include // ṩ strlen ԭ +#include "Status.h" //**01 **// + +/* ַ */ +typedef char* StringType; + + +// ʼһֵΪsĴt +void StrAssign(StringType* t, const char* s); + +// ȽϣstĴССһ£0 +int StrCompare(StringType s, StringType t); + +// ַsij +int StrLength(StringType s); + +// ӣstӺĴ +StringType Concat(StringType s, StringType t); + +// Ӵsstartλ𣬽ȡlenַ󷵻 +StringType SubString(StringType s, int start, int len); + +// ңsposλtҵλ +int Index(StringType s, StringType t, int pos); + +// 룺spost +Status StrInsert(StringType* s, int pos, StringType t); + +// ɾsposλɾlenַ +Status StrDelete(StringType* s, int pos, int len); + +// ַ +void StrPrint(StringType s); + +#endif diff --git a/VisualC++/ExerciseBook/04.12/04.12.c b/VisualC++/ExerciseBook/04.12/04.12.c new file mode 100644 index 0000000..fe34fd9 --- /dev/null +++ b/VisualC++/ExerciseBook/04.12/04.12.c @@ -0,0 +1,56 @@ +#include +#include "Status.h" //**01 **// +#include "String.h" //**ַ**// + +/* + * 滻Replace + * + * V滻SгֵTȵҲصӴ + */ +Status Algo_4_12(StringType* S, StringType T, StringType V) { + int i; + + if(StrLength(*S) == 0 || StrLength(T) == 0) { + return ERROR; + } + + i = 1; + + // SѰģʽTһγֵλ + while((i = Index(*S, T, i)) != 0) { + StrDelete(S, i, StrLength(T)); // SɾT + StrInsert(S, i, V); // SвV + + i += StrLength(V); // iлһλ + } + + return OK; +} + + +int main(int argc, char* argv[]) { + char* s = "----***--*-**-****-*****-----"; + char* t = "**"; + char* v = "^^"; + StringType T, S, V; + + printf("滻ǰ...\n"); + + StrAssign(&S, s); + StrAssign(&T, t); + StrAssign(&V, v); + + printf("S = "); + StrPrint(S); + printf("T = "); + StrPrint(T); + printf("V = "); + StrPrint(V); + + printf("滻...\n"); + printf("S = "); + Algo_4_12(&S, T, V); + StrPrint(S); + + return 0; +} diff --git a/VisualC++/ExerciseBook/04.12/04.12.vcxproj b/VisualC++/ExerciseBook/04.12/04.12.vcxproj new file mode 100644 index 0000000..055e690 --- /dev/null +++ b/VisualC++/ExerciseBook/04.12/04.12.vcxproj @@ -0,0 +1,76 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {4E3B30A1-A3C8-47B9-B2EA-0831F3F9C852} + My0412 + + + + 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/04.12/04.12.vcxproj.filters b/VisualC++/ExerciseBook/04.12/04.12.vcxproj.filters new file mode 100644 index 0000000..42bbc39 --- /dev/null +++ b/VisualC++/ExerciseBook/04.12/04.12.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/04.12/04.12.vcxproj.user b/VisualC++/ExerciseBook/04.12/04.12.vcxproj.user new file mode 100644 index 0000000..ace9a86 --- /dev/null +++ b/VisualC++/ExerciseBook/04.12/04.12.vcxproj.user @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/04.12/String.c b/VisualC++/ExerciseBook/04.12/String.c new file mode 100644 index 0000000..41df51c --- /dev/null +++ b/VisualC++/ExerciseBook/04.12/String.c @@ -0,0 +1,151 @@ +/*=========================== + * ϰ4.10~4.14ʹõַ + ============================*/ + +#include "String.h" + +// ʼһֵΪsĴt +void StrAssign(StringType* t, const char* s) { + if(s == NULL) { + *t = ""; + } + + *t = (char*) malloc((strlen(s) + 1) * sizeof(char)); + + strcpy(*t, s); +} + +// ȽϣstĴССһ£0 +int StrCompare(StringType s, StringType t) { + return strcmp(s, t); +} + +// ַsij +int StrLength(StringType s) { + return (int) strlen(s); +} + +// ӣstӺĴ +StringType Concat(StringType s, StringType t) { + StringType r; + + if(s == NULL) { + s = ""; + } + + if(t == NULL) { + t = ""; + } + + r = (char*) malloc((strlen(s) + strlen(t) + 1) * sizeof(char)); + r[0] = '\0'; + + strcat(r, s); + strcat(r, t); + + return r; +} + +// Ӵsstartλ𣬽ȡlenַ󷵻 +StringType SubString(StringType s, int start, int len) { + int n; + char* sub; + + n = (int) strlen(s); + + if(start < 1 || start > n || start + len - 1 > n || len < 0) { + return ""; + } + + sub = (char*) malloc((len + 1) * sizeof(char)); + strncpy(sub, s + start - 1, len); + sub[len] = '\0'; + + return sub; +} + +// ңsposλtҵλ +int Index(StringType s, StringType t, int pos) { + int m, n, i; + StringType sub; + + // ʧǰ + if(pos < 1 || pos > StrLength(s) || StrLength(t) == 0) { + return 0; + } + + n = StrLength(s); + m = StrLength(t); + i = pos; + + // ֤ȲԽ + while(i <= n - m + 1) { + // ȡS[i, i+m-1] + sub = SubString(s, i, m); + + // Ӵģʽƥ䣬Ҫƽ + if(StrCompare(sub, t) != 0) { + ++i; + } else { + return i; + } + } + + return 0; +} + +// 룺spost +Status StrInsert(StringType* s, int pos, StringType t) { + StringType r; + StringType s1, s2; + + if(pos < 1 || pos > StrLength(*s) + 1) { + return ERROR; + } + + r = (StringType) malloc((strlen(*s) + strlen(t) + 1) * sizeof(char)); + r[0] = '\0'; + + // ĴΪգǰ + if(StrLength(t) == 0) { + return OK; + } + + s1 = SubString(*s, 1, pos - 1); + s2 = SubString(*s, pos, (int) strlen(*s) - pos + 1); + + strcat(r, s1); + strcat(r, t); + strcat(r, s2); + + *s = r; + + return OK; +} + +// ɾsposλɾlenַ +Status StrDelete(StringType* s, int pos, int len) { + StringType r; + + if(pos < 1 || pos + len - 1 > StrLength(*s) || len < 0) { + return ERROR; + } + + // ɾijΪ0ǰ + if(len == 0) { + return OK; + } + + r = (StringType) malloc((StrLength(*s) - len + 1) * sizeof(char)); + strncpy(r, *s, pos - 1); + strcpy(r + pos - 1, *s + pos + len - 1); + + *s = r; + + return OK; +} + +// ַ +void StrPrint(StringType s) { + printf("%s\n", s); +} diff --git a/VisualC++/ExerciseBook/04.12/String.h b/VisualC++/ExerciseBook/04.12/String.h new file mode 100644 index 0000000..9d984af --- /dev/null +++ b/VisualC++/ExerciseBook/04.12/String.h @@ -0,0 +1,43 @@ +/*=========================== + * ϰ4.10~4.14ʹõַ + ============================*/ + +#ifndef STRING_H +#define STRING_H + +#include +#include // ṩ strlen ԭ +#include "Status.h" //**01 **// + +/* ַ */ +typedef char* StringType; + + +// ʼһֵΪsĴt +void StrAssign(StringType* t, const char* s); + +// ȽϣstĴССһ£0 +int StrCompare(StringType s, StringType t); + +// ַsij +int StrLength(StringType s); + +// ӣstӺĴ +StringType Concat(StringType s, StringType t); + +// Ӵsstartλ𣬽ȡlenַ󷵻 +StringType SubString(StringType s, int start, int len); + +// ңsposλtҵλ +int Index(StringType s, StringType t, int pos); + +// 룺spost +Status StrInsert(StringType* s, int pos, StringType t); + +// ɾsposλɾlenַ +Status StrDelete(StringType* s, int pos, int len); + +// ַ +void StrPrint(StringType s); + +#endif diff --git a/VisualC++/ExerciseBook/04.13/04.13.c b/VisualC++/ExerciseBook/04.13/04.13.c new file mode 100644 index 0000000..1478bf4 --- /dev/null +++ b/VisualC++/ExerciseBook/04.13/04.13.c @@ -0,0 +1,41 @@ +#include +#include "String.h" //**ַ**// + +/* + * ɾSаT + */ +Status Algo_4_13(StringType* S, StringType T) { + int i; + + // SвTҵɾ + while((i = Index(*S, T, 1)) != 0) { + if(StrDelete(S, i, StrLength(T)) == ERROR) { + return ERROR; + } + } + + return OK; +} + + +int main(int argc, char* argv[]) { + char* s = "----***--*-**-****-*****-----"; + char* t = "**"; + StringType T, S; + + printf("ɾǰ...\n"); + StrAssign(&S, s); + StrAssign(&T, t); + + printf("S = "); + StrPrint(S); + printf("T = "); + StrPrint(T); + + printf("ɾ...\n"); + printf("S = "); + Algo_4_13(&S, T); + StrPrint(S); + + return 0; +} diff --git a/VisualC++/ExerciseBook/04.13/04.13.vcxproj b/VisualC++/ExerciseBook/04.13/04.13.vcxproj new file mode 100644 index 0000000..310e314 --- /dev/null +++ b/VisualC++/ExerciseBook/04.13/04.13.vcxproj @@ -0,0 +1,76 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {63E38EBF-7C63-4D2F-BBFD-A39D28CA3C50} + My0413 + + + + 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/04.13/04.13.vcxproj.filters b/VisualC++/ExerciseBook/04.13/04.13.vcxproj.filters new file mode 100644 index 0000000..1c10f86 --- /dev/null +++ b/VisualC++/ExerciseBook/04.13/04.13.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/04.13/04.13.vcxproj.user b/VisualC++/ExerciseBook/04.13/04.13.vcxproj.user new file mode 100644 index 0000000..ace9a86 --- /dev/null +++ b/VisualC++/ExerciseBook/04.13/04.13.vcxproj.user @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/04.13/String.c b/VisualC++/ExerciseBook/04.13/String.c new file mode 100644 index 0000000..41df51c --- /dev/null +++ b/VisualC++/ExerciseBook/04.13/String.c @@ -0,0 +1,151 @@ +/*=========================== + * ϰ4.10~4.14ʹõַ + ============================*/ + +#include "String.h" + +// ʼһֵΪsĴt +void StrAssign(StringType* t, const char* s) { + if(s == NULL) { + *t = ""; + } + + *t = (char*) malloc((strlen(s) + 1) * sizeof(char)); + + strcpy(*t, s); +} + +// ȽϣstĴССһ£0 +int StrCompare(StringType s, StringType t) { + return strcmp(s, t); +} + +// ַsij +int StrLength(StringType s) { + return (int) strlen(s); +} + +// ӣstӺĴ +StringType Concat(StringType s, StringType t) { + StringType r; + + if(s == NULL) { + s = ""; + } + + if(t == NULL) { + t = ""; + } + + r = (char*) malloc((strlen(s) + strlen(t) + 1) * sizeof(char)); + r[0] = '\0'; + + strcat(r, s); + strcat(r, t); + + return r; +} + +// Ӵsstartλ𣬽ȡlenַ󷵻 +StringType SubString(StringType s, int start, int len) { + int n; + char* sub; + + n = (int) strlen(s); + + if(start < 1 || start > n || start + len - 1 > n || len < 0) { + return ""; + } + + sub = (char*) malloc((len + 1) * sizeof(char)); + strncpy(sub, s + start - 1, len); + sub[len] = '\0'; + + return sub; +} + +// ңsposλtҵλ +int Index(StringType s, StringType t, int pos) { + int m, n, i; + StringType sub; + + // ʧǰ + if(pos < 1 || pos > StrLength(s) || StrLength(t) == 0) { + return 0; + } + + n = StrLength(s); + m = StrLength(t); + i = pos; + + // ֤ȲԽ + while(i <= n - m + 1) { + // ȡS[i, i+m-1] + sub = SubString(s, i, m); + + // Ӵģʽƥ䣬Ҫƽ + if(StrCompare(sub, t) != 0) { + ++i; + } else { + return i; + } + } + + return 0; +} + +// 룺spost +Status StrInsert(StringType* s, int pos, StringType t) { + StringType r; + StringType s1, s2; + + if(pos < 1 || pos > StrLength(*s) + 1) { + return ERROR; + } + + r = (StringType) malloc((strlen(*s) + strlen(t) + 1) * sizeof(char)); + r[0] = '\0'; + + // ĴΪգǰ + if(StrLength(t) == 0) { + return OK; + } + + s1 = SubString(*s, 1, pos - 1); + s2 = SubString(*s, pos, (int) strlen(*s) - pos + 1); + + strcat(r, s1); + strcat(r, t); + strcat(r, s2); + + *s = r; + + return OK; +} + +// ɾsposλɾlenַ +Status StrDelete(StringType* s, int pos, int len) { + StringType r; + + if(pos < 1 || pos + len - 1 > StrLength(*s) || len < 0) { + return ERROR; + } + + // ɾijΪ0ǰ + if(len == 0) { + return OK; + } + + r = (StringType) malloc((StrLength(*s) - len + 1) * sizeof(char)); + strncpy(r, *s, pos - 1); + strcpy(r + pos - 1, *s + pos + len - 1); + + *s = r; + + return OK; +} + +// ַ +void StrPrint(StringType s) { + printf("%s\n", s); +} diff --git a/VisualC++/ExerciseBook/04.13/String.h b/VisualC++/ExerciseBook/04.13/String.h new file mode 100644 index 0000000..9d984af --- /dev/null +++ b/VisualC++/ExerciseBook/04.13/String.h @@ -0,0 +1,43 @@ +/*=========================== + * ϰ4.10~4.14ʹõַ + ============================*/ + +#ifndef STRING_H +#define STRING_H + +#include +#include // ṩ strlen ԭ +#include "Status.h" //**01 **// + +/* ַ */ +typedef char* StringType; + + +// ʼһֵΪsĴt +void StrAssign(StringType* t, const char* s); + +// ȽϣstĴССһ£0 +int StrCompare(StringType s, StringType t); + +// ַsij +int StrLength(StringType s); + +// ӣstӺĴ +StringType Concat(StringType s, StringType t); + +// Ӵsstartλ𣬽ȡlenַ󷵻 +StringType SubString(StringType s, int start, int len); + +// ңsposλtҵλ +int Index(StringType s, StringType t, int pos); + +// 룺spost +Status StrInsert(StringType* s, int pos, StringType t); + +// ɾsposλɾlenַ +Status StrDelete(StringType* s, int pos, int len); + +// ַ +void StrPrint(StringType s); + +#endif diff --git a/VisualC++/ExerciseBook/04.14/04.14.c b/VisualC++/ExerciseBook/04.14/04.14.c new file mode 100644 index 0000000..b996927 --- /dev/null +++ b/VisualC++/ExerciseBook/04.14/04.14.c @@ -0,0 +1,92 @@ +#include +#include +#include "SqStack.h" //**03 ջͶ**// +#include "String.h" //**ַ**// + +/* + * ǰ׺ʽprefixתΪ׺ʽ + * + *ע + * δǰ׺ʽȷԽ֤ + */ +Status Algo_4_14(const char* prefix, char** suffix) { + StringType P, S; + StringType Operator; // + SqStack stack; // ʽջ + StringType e; // ջԪ + StringType o; // ջ + int i, len; + int readStr; // ǷҪȡַ + + len = (int) strlen(prefix); + + if(len == 0) { + *suffix = NULL; + return ERROR; + } + + // Ͳ + StrAssign(&Operator, "+-*/"); + + // ǰ׺ʽ + StrAssign(&P, prefix); + + // ׺ʽջ + InitStack(&stack); + + readStr = 1; + i = 1; + + // ǰ׺ʽȡԪ + while(TRUE) { + if(readStr == 1) { + S = SubString(P, i++, 1); + } + + // ֱջ + if(Index(Operator, S, 1) != 0) { + Push(&stack, S); + readStr = 1; + + // ˲ + } else { + // ȡջԪأջѾΪգSд洢˺׺ʽ + if(GetTop(stack, &e) == ERROR) { + break; + } + + // ջԪ򽫲ֱջ + if(Index(Operator, e, 1) != 0) { + Push(&stack, S); + readStr = 1; + + // ջҲDzҪм + } else { + Pop(&stack, &e); // ջ + Pop(&stack, &o); // ջ + + S = Concat(e, S); + S = Concat(S, o); + + // ²ҪȡַҪжϸոռSub + readStr = 0; + } + } + } + + // ȡ׺ʽ + *suffix = S; + + return OK; +} + + +int main(int argc, char* argv[]) { + char* prefix = "-+a*bc/de"; // ׺ʽΪabc*+de/- + char* suffix; + + Algo_4_14(prefix, &suffix); + + printf("ǰ׺ʽ%s\n", prefix); + printf("׺ʽ%s\n", suffix); +} diff --git a/VisualC++/ExerciseBook/04.14/04.14.vcxproj b/VisualC++/ExerciseBook/04.14/04.14.vcxproj new file mode 100644 index 0000000..26aaa59 --- /dev/null +++ b/VisualC++/ExerciseBook/04.14/04.14.vcxproj @@ -0,0 +1,78 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {C6EBA21E-2309-4331-92D3-8644F769F2FC} + My0414 + + + + 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/04.14/04.14.vcxproj.filters b/VisualC++/ExerciseBook/04.14/04.14.vcxproj.filters new file mode 100644 index 0000000..c1df734 --- /dev/null +++ b/VisualC++/ExerciseBook/04.14/04.14.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/04.14/04.14.vcxproj.user b/VisualC++/ExerciseBook/04.14/04.14.vcxproj.user new file mode 100644 index 0000000..ace9a86 --- /dev/null +++ b/VisualC++/ExerciseBook/04.14/04.14.vcxproj.user @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/04.14/SqStack.c b/VisualC++/ExerciseBook/04.14/SqStack.c new file mode 100644 index 0000000..70e35c0 --- /dev/null +++ b/VisualC++/ExerciseBook/04.14/SqStack.c @@ -0,0 +1,89 @@ +/*========================= + * ջ˳洢ṹ˳ջ + ==========================*/ + +#include "SqStack.h" //**03 ջͶ**// + +/* + * ʼ + * + * һջʼɹ򷵻OK򷵻ERROR + */ +Status InitStack(SqStack* S) { + if(S == NULL) { + return ERROR; + } + + (*S).base = (SElemType*) malloc(STACK_INIT_SIZE * sizeof(SElemType)); + if((*S).base == NULL) { + exit(OVERFLOW); + } + + (*S).top = (*S).base; + (*S).stacksize = STACK_INIT_SIZE; + + return OK; +} + +/* + * ȡֵ + * + * ջԪأeա + */ +Status GetTop(SqStack S, SElemType* e) { + if(S.base == NULL || S.top == S.base) { + return ERROR; + } + + // ıջԪ + *e = *(S.top - 1); + + return OK; +} + +/* + * ջ + * + * Ԫeѹ뵽ջ + */ +Status Push(SqStack* S, SElemType e) { + if(S == NULL || (*S).base == NULL) { + return ERROR; + } + + // ջʱ׷Ӵ洢ռ + if((*S).top - (*S).base >= (*S).stacksize) { + (*S).base = (SElemType*) realloc((*S).base, ((*S).stacksize + STACKINCREMENT) * sizeof(SElemType)); + if((*S).base == NULL) { + exit(OVERFLOW); // 洢ʧ + } + + (*S).top = (*S).base + (*S).stacksize; + (*S).stacksize += STACKINCREMENT; + } + + // ջȸֵջָ + *(S->top++) = e; + + return OK; +} + +/* + * ջ + * + * ջԪصeա + */ +Status Pop(SqStack* S, SElemType* e) { + if(S == NULL || (*S).base == NULL) { + return ERROR; + } + + if((*S).top == (*S).base) { + return ERROR; + } + + // ջջָȵݼٸֵ + *e = *(--(*S).top); + + return OK; +} diff --git a/VisualC++/ExerciseBook/04.14/SqStack.h b/VisualC++/ExerciseBook/04.14/SqStack.h new file mode 100644 index 0000000..db29792 --- /dev/null +++ b/VisualC++/ExerciseBook/04.14/SqStack.h @@ -0,0 +1,61 @@ +/*========================= + * ջ˳洢ṹ˳ջ + ==========================*/ + +#ifndef SQSTACK_H +#define SQSTACK_H + +#include +#include // ṩmallocreallocfreeexitԭ +#include "Status.h" //**01 **// +#include "String.h" //**04 **// + +/* 궨 */ +#define STACK_INIT_SIZE 100 // ˳ջ洢ռijʼ +#define STACKINCREMENT 10 // ˳ջ洢ռķ + +/* + * ˳ջԪͶ + * + *ע + * ԪΪַ + */ +typedef StringType SElemType; + +// ˳ջԪؽṹ +typedef struct { + SElemType* base; // ջָ + SElemType* top; // ջָ + int stacksize; // ǰѷĴ洢ռ䣬ԪΪλ +} SqStack; + + +/* + * ʼ + * + * һջʼɹ򷵻OK򷵻ERROR + */ +Status InitStack(SqStack* S); + +/* + * ȡֵ + * + * ջԪأeա + */ +Status GetTop(SqStack S, SElemType* e); + +/* + * ջ + * + * Ԫeѹ뵽ջ + */ +Status Push(SqStack* S, SElemType e); + +/* + * ջ + * + * ջԪصeա + */ +Status Pop(SqStack* S, SElemType* e); + +#endif diff --git a/VisualC++/ExerciseBook/04.14/String.c b/VisualC++/ExerciseBook/04.14/String.c new file mode 100644 index 0000000..41df51c --- /dev/null +++ b/VisualC++/ExerciseBook/04.14/String.c @@ -0,0 +1,151 @@ +/*=========================== + * ϰ4.10~4.14ʹõַ + ============================*/ + +#include "String.h" + +// ʼһֵΪsĴt +void StrAssign(StringType* t, const char* s) { + if(s == NULL) { + *t = ""; + } + + *t = (char*) malloc((strlen(s) + 1) * sizeof(char)); + + strcpy(*t, s); +} + +// ȽϣstĴССһ£0 +int StrCompare(StringType s, StringType t) { + return strcmp(s, t); +} + +// ַsij +int StrLength(StringType s) { + return (int) strlen(s); +} + +// ӣstӺĴ +StringType Concat(StringType s, StringType t) { + StringType r; + + if(s == NULL) { + s = ""; + } + + if(t == NULL) { + t = ""; + } + + r = (char*) malloc((strlen(s) + strlen(t) + 1) * sizeof(char)); + r[0] = '\0'; + + strcat(r, s); + strcat(r, t); + + return r; +} + +// Ӵsstartλ𣬽ȡlenַ󷵻 +StringType SubString(StringType s, int start, int len) { + int n; + char* sub; + + n = (int) strlen(s); + + if(start < 1 || start > n || start + len - 1 > n || len < 0) { + return ""; + } + + sub = (char*) malloc((len + 1) * sizeof(char)); + strncpy(sub, s + start - 1, len); + sub[len] = '\0'; + + return sub; +} + +// ңsposλtҵλ +int Index(StringType s, StringType t, int pos) { + int m, n, i; + StringType sub; + + // ʧǰ + if(pos < 1 || pos > StrLength(s) || StrLength(t) == 0) { + return 0; + } + + n = StrLength(s); + m = StrLength(t); + i = pos; + + // ֤ȲԽ + while(i <= n - m + 1) { + // ȡS[i, i+m-1] + sub = SubString(s, i, m); + + // Ӵģʽƥ䣬Ҫƽ + if(StrCompare(sub, t) != 0) { + ++i; + } else { + return i; + } + } + + return 0; +} + +// 룺spost +Status StrInsert(StringType* s, int pos, StringType t) { + StringType r; + StringType s1, s2; + + if(pos < 1 || pos > StrLength(*s) + 1) { + return ERROR; + } + + r = (StringType) malloc((strlen(*s) + strlen(t) + 1) * sizeof(char)); + r[0] = '\0'; + + // ĴΪգǰ + if(StrLength(t) == 0) { + return OK; + } + + s1 = SubString(*s, 1, pos - 1); + s2 = SubString(*s, pos, (int) strlen(*s) - pos + 1); + + strcat(r, s1); + strcat(r, t); + strcat(r, s2); + + *s = r; + + return OK; +} + +// ɾsposλɾlenַ +Status StrDelete(StringType* s, int pos, int len) { + StringType r; + + if(pos < 1 || pos + len - 1 > StrLength(*s) || len < 0) { + return ERROR; + } + + // ɾijΪ0ǰ + if(len == 0) { + return OK; + } + + r = (StringType) malloc((StrLength(*s) - len + 1) * sizeof(char)); + strncpy(r, *s, pos - 1); + strcpy(r + pos - 1, *s + pos + len - 1); + + *s = r; + + return OK; +} + +// ַ +void StrPrint(StringType s) { + printf("%s\n", s); +} diff --git a/VisualC++/ExerciseBook/04.14/String.h b/VisualC++/ExerciseBook/04.14/String.h new file mode 100644 index 0000000..9d984af --- /dev/null +++ b/VisualC++/ExerciseBook/04.14/String.h @@ -0,0 +1,43 @@ +/*=========================== + * ϰ4.10~4.14ʹõַ + ============================*/ + +#ifndef STRING_H +#define STRING_H + +#include +#include // ṩ strlen ԭ +#include "Status.h" //**01 **// + +/* ַ */ +typedef char* StringType; + + +// ʼһֵΪsĴt +void StrAssign(StringType* t, const char* s); + +// ȽϣstĴССһ£0 +int StrCompare(StringType s, StringType t); + +// ַsij +int StrLength(StringType s); + +// ӣstӺĴ +StringType Concat(StringType s, StringType t); + +// Ӵsstartλ𣬽ȡlenַ󷵻 +StringType SubString(StringType s, int start, int len); + +// ңsposλtҵλ +int Index(StringType s, StringType t, int pos); + +// 룺spost +Status StrInsert(StringType* s, int pos, StringType t); + +// ɾsposλɾlenַ +Status StrDelete(StringType* s, int pos, int len); + +// ַ +void StrPrint(StringType s); + +#endif diff --git a/VisualC++/ExerciseBook/04.15-04.17/04.15-04.17.c b/VisualC++/ExerciseBook/04.15-04.17/04.15-04.17.c new file mode 100644 index 0000000..0e74b14 --- /dev/null +++ b/VisualC++/ExerciseBook/04.15-04.17/04.15-04.17.c @@ -0,0 +1,92 @@ +#include +#include "Status.h" //**01 **// +#include "SString.h" //**04 **// + +/* + * ʼStrAssign + * + *ע + * úSStringļж + */ +Status Algo_4_15(SString T, char* chars); + +/* + * ȽϣStrCompare + * + *ע + * úSStringļж + */ +int Algo_4_16(SString S, SString T); + +/* + * 滻Replace + * + *ע + * úSStringļж + */ +Status Algo_4_17(SString S, SString T, SString V); + + +int main(int argc, char* argv[]) { + char* t = "ab**c*de***fg"; + char* s = "ab**c*de***fh"; + SString T, S, M1, M2; + int i; + + printf(" 4.15 ֤...\n"); + Algo_4_15(T, t); + Algo_4_15(S, s); + printf("T = "); + StrPrint(T); + printf("S = "); + StrPrint(S); + + printf(" 4.16 ֤...\n"); + i = Algo_4_16(S, T); + if(i > 0) { + printf("S > T\n"); + } else if(i < 0) { + printf("S < T\n"); + } else { + printf("S == T\n"); + } + + printf(" 4.17 ֤...\n"); + Algo_4_15(M1, "**"); + Algo_4_15(M2, "^"); + Algo_4_17(S, M1, M2); + printf(" \"^\" 滻 \"**\" \nS = "); + StrPrint(S); + + return 0; +} + +/* + * ʼStrAssign + * + *ע + * úSStringļж + */ +Status Algo_4_15(SString T, char* chars) { + return StrAssign(T, chars); +} + +/* + * ȽϣStrCompare + * + *ע + * úSStringļж + */ +int Algo_4_16(SString S, SString T) { + return StrCompare(S, T); +} + +/* + * 滻Replace + * + *ע + * úSStringļж + */ +Status Algo_4_17(SString S, SString T, SString V) { + return Replace(S, T, V); +} diff --git a/VisualC++/ExerciseBook/04.15-04.17/04.15-04.17.vcxproj b/VisualC++/ExerciseBook/04.15-04.17/04.15-04.17.vcxproj new file mode 100644 index 0000000..c188984 --- /dev/null +++ b/VisualC++/ExerciseBook/04.15-04.17/04.15-04.17.vcxproj @@ -0,0 +1,76 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {DA014C3E-5124-41C7-B53F-53AE0B96AE99} + My04150417 + + + + 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/04.15-04.17/04.15-04.17.vcxproj.filters b/VisualC++/ExerciseBook/04.15-04.17/04.15-04.17.vcxproj.filters new file mode 100644 index 0000000..696b55c --- /dev/null +++ b/VisualC++/ExerciseBook/04.15-04.17/04.15-04.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/04.15-04.17/04.15-04.17.vcxproj.user b/VisualC++/ExerciseBook/04.15-04.17/04.15-04.17.vcxproj.user new file mode 100644 index 0000000..ace9a86 --- /dev/null +++ b/VisualC++/ExerciseBook/04.15-04.17/04.15-04.17.vcxproj.user @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/04.15-04.17/SString.c b/VisualC++/ExerciseBook/04.15-04.17/SString.c new file mode 100644 index 0000000..fc4c757 --- /dev/null +++ b/VisualC++/ExerciseBook/04.15-04.17/SString.c @@ -0,0 +1,406 @@ +/*============================= + * Ķ˳洢ʾ˳򴮣 + * + * 㷨: 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 DestroyString(SString S) { + 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; +} + +/* + * 㷨4.1 + * + * + * + * posʼģʽTS״γֵλãڣ򷵻0 + * ҳɹƥλá + * + *ע + * 1.ʵҪСӼ + * 2.ʵֱȽϵЧ + */ +int Index_1(SString S, SString T, int pos) { + int i, n, m; // ¼STij + SString sub; + + /* + * ʧǰ + * ̲д΢ͬ + */ + if(pos < 1 || pos > S[0] || StrEmpty(T)) { + return 0; + } + + n = StrLength(S); + m = StrLength(T); + i = pos; + + // ֤ȲԽ + while(i <= n - m + 1) { + // ȡS[i, i+m-1] + SubString(sub, S, i, m); + + // Ӵģʽƥ䣬Ҫƽ + if(StrCompare(sub, T) != 0) { + ++i; + } else { + return i; + } + } + + return 0; +} + +/* + * 㷨4.5 + * + * + * + * posʼģʽTS״γֵλãڣ򷵻0 + * ҳɹƥλá + * + *ע + * 1.ʵֲСӼ + * 2.ʵֱȽϵЧ + */ +int Index_2(SString S, SString T, int pos) { + int i = pos; + int j = 1; + + if(pos < 1 || pos > S[0] || StrEmpty(T)) { + return 0; + } + + while(i <= S[0] && j <= T[0]) { + // ַͬȽϺַ + if(S[i] == T[j]) { + i++; + j++; + + // ַͬαҪˣ±Ƚ + } else { + i = i - (j - 1) + 1; // j-1ͽ͵ǰj-1ԪأڵjԪϹһ + j = 1; // αjصTĵһλ + } + } + + // һT[0]>0ж + if(j > T[0] && T[0] > 0) { // TΪմ + return i - T[0]; // ƥɹ + } else { + return 0; + } +} + +/* + * + * + * T뵽Sposλô + */ +Status StrInsert(SString S, int pos, SString T) { + int i; + + if(pos < 1 || pos > S[0] + 1 || S[0] + T[0] > MAXSTRLEN) { + return ERROR; + } + + // ĴΪգǰ + if(StrEmpty(T)) { + return OK; + } + + // SڳλãΪT׼ + for(i = S[0]; i >= pos; i--) { + // ӺǰǰԪŲ + S[i + T[0]] = S[i]; + } + + // TSڳλ + for(i = pos; i <= pos + T[0] - 1; i++) { + S[i] = T[i - pos + 1]; + } + + // + S[0] += T[0]; + + 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; +} + +/* + * 滻 + * + * V滻SгֵTȵҲصӴ + * + *ע + * 1.òСӼ + * 2.ʵֱȽϵЧ + */ +Status Replace(SString S, SString T, SString V) { + int i; + + if(StrEmpty(S) || StrEmpty(T)) { + return ERROR; + } + + // SѰģʽTһγֵλ + i = Index_2(S, T, 1); + + // ƥַҿԱȫ滻滻 + while(i != 0 && S[0] - T[0] + V[0] <= MAXSTRLEN) { + StrDelete(S, i, StrLength(T)); // SɾT + StrInsert(S, i, V); // SвV + + i += StrLength(V); // iлһλ + + i = Index_2(S, T, i); // һƥַ + } + + if(i == 0) { // SеTȫ滻 + return OK; + } else { // STVѾ岻ȥ + return ERROR; + } +} + +/* + * 㷨4.2 + * + * + * + * S1S2洢TзءӺijֻδIJ֡ + * ֵʾӺĴǷ + * + *ע + * òСӼ + */ +Status Concat(SString T, SString S1, SString S2) { + int i; + int uncut; // ´Ƿ + + // ȫҪü + if(S1[0] + S2[0] <= MAXSTRLEN) { + // S1T + for(i = 1; i <= S1[0]; i++) { + T[i] = S1[i]; + } + + // S2T + for(i = S1[0] + 1; i <= S1[0] + S2[0]; i++) { + T[i] = S2[i - S1[0]]; + } + + // ³ + T[0] = S1[0] + S2[0]; + + // δü + uncut = TRUE; + + // ҪüS2 + } else if(S1[0] <= MAXSTRLEN) { + // S1T + for(i = 1; i <= S1[0]; i++) { + T[i] = S1[i]; + } + + // S2һָƵT + for(i = S1[0] + 1; i <= MAXSTRLEN; i++) { + T[i] = S2[i - S1[0]]; + } + + // ³ + T[0] = MAXSTRLEN; + + uncut = FALSE; + + // ֻҪS1һ + } else { + // ͬϢһ + for(i = 0; i <= MAXSTRLEN; i++) { + T[i] = S1[i]; + } + + uncut = FALSE; + } + + return uncut; +} + +// ӡַ +void StrPrint(SString S) { + int i; + + for(i = 1; i<=S[0] ; i++) { + printf("%c", S[i]); + } + + printf("\n"); +} diff --git a/VisualC++/ExerciseBook/04.15-04.17/SString.h b/VisualC++/ExerciseBook/04.15-04.17/SString.h new file mode 100644 index 0000000..386ffb8 --- /dev/null +++ b/VisualC++/ExerciseBook/04.15-04.17/SString.h @@ -0,0 +1,179 @@ +/*============================= + * Ķ˳洢ʾ˳򴮣 + * + * 㷨: 4.14.24.34.5 + ==============================*/ + +#ifndef SSTRING_H +#define SSTRING_H + +#include +#include // ṩstrlenԭ +#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 DestroyString(SString S); + +/* + * + * + * 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); + +/* + * 㷨4.1 + * + * + * + * posʼģʽTS״γֵλãڣ򷵻0 + * ҳɹƥλá + * + *ע + * 1.ʵҪСӼ + * 2.ʵֱȽϵЧ + */ +int Index_1(SString S, SString T, int pos); + +/* + * 㷨4.5 + * + * + * + * posʼģʽTS״γֵλãڣ򷵻0 + * ҳɹƥλá + * + *ע + * 1.ʵֲСӼ + * 2.ʵֱȽϵЧ + */ +int Index_2(SString S, SString T, int pos); + +/* + * + * + * T뵽Sposλô + */ +Status StrInsert(SString S, int pos, SString T); + +/* + * ɾ + * + * ɾ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); + +/* + * 滻 + * + * V滻SгֵTȵҲصӴ + * + *ע + * òСӼЧʽϵ͡ + */ +Status Replace(SString S, SString T, SString V); + +/* + * 㷨4.2 + * + * + * + * S1S2洢TзءӺijֻδIJ֡ + * ֵʾӺĴǷ + * + *ע + * òСӼ + */ +Status Concat(SString T, SString S1, SString S2); + +// ӡַ +void StrPrint(SString S); + +#endif diff --git a/VisualC++/ExerciseBook/04.18/04.18.c b/VisualC++/ExerciseBook/04.18/04.18.c new file mode 100644 index 0000000..3e352c7 --- /dev/null +++ b/VisualC++/ExerciseBook/04.18/04.18.c @@ -0,0 +1,62 @@ +#include +#include +#include "SString.h" //**04 **// + +/* + * ͳַSвַͬÿַĸͳƽ + */ +int* Algo_4_18(SString S); + + +int main(int argc, char* argv[]) { + char* s = "dbasydujhge638940[gptokljrsehgadcsbnmv,c.b'ng[p098437eywdghswqdecxvghju"; + SString S; + int* total; + int i; + + StrAssign(S, s); + printf("S = "); + StrPrint(S); + + total = Algo_4_18(S); + printf(" S вַͬ %d \n", total[0]); + for(i = 1; i <= 127; i++) { + if(total[i] != 0) { + printf("ַ \'%c\' %d .\n", i, total[i]); + } + } + printf("ͳ...\n"); + + return 0; +} + + +/* + * ͳַSвַͬÿַĸͳƽ + */ +int* Algo_4_18(SString S) { + int i; + int* total; + + /* + * totalΪ128 + * 0ŵԪ洢ַͬ + * Ԫ洢ֲַͬ + * + * עͳƿַ'\0' + */ + total = (int*) malloc(128 * sizeof(int)); + memset(total, 0, 128 * sizeof(int)); + + for(i = 1; i <= S[0]; i++) { + // ַͳƲַͬ + if(total[S[i]] == 0) { + total[0]++; + } + + // ͳַ + total[S[i]]++; + } + + return total; +} diff --git a/VisualC++/ExerciseBook/04.18/04.18.vcxproj b/VisualC++/ExerciseBook/04.18/04.18.vcxproj new file mode 100644 index 0000000..4dc7a49 --- /dev/null +++ b/VisualC++/ExerciseBook/04.18/04.18.vcxproj @@ -0,0 +1,76 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {19006CCD-C88C-44C5-9812-6F4276CDA60B} + My0418 + + + + 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/04.18/04.18.vcxproj.filters b/VisualC++/ExerciseBook/04.18/04.18.vcxproj.filters new file mode 100644 index 0000000..dc4cebf --- /dev/null +++ b/VisualC++/ExerciseBook/04.18/04.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/04.18/04.18.vcxproj.user b/VisualC++/ExerciseBook/04.18/04.18.vcxproj.user new file mode 100644 index 0000000..ace9a86 --- /dev/null +++ b/VisualC++/ExerciseBook/04.18/04.18.vcxproj.user @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/04.18/SString.c b/VisualC++/ExerciseBook/04.18/SString.c new file mode 100644 index 0000000..fc4c757 --- /dev/null +++ b/VisualC++/ExerciseBook/04.18/SString.c @@ -0,0 +1,406 @@ +/*============================= + * Ķ˳洢ʾ˳򴮣 + * + * 㷨: 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 DestroyString(SString S) { + 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; +} + +/* + * 㷨4.1 + * + * + * + * posʼģʽTS״γֵλãڣ򷵻0 + * ҳɹƥλá + * + *ע + * 1.ʵҪСӼ + * 2.ʵֱȽϵЧ + */ +int Index_1(SString S, SString T, int pos) { + int i, n, m; // ¼STij + SString sub; + + /* + * ʧǰ + * ̲д΢ͬ + */ + if(pos < 1 || pos > S[0] || StrEmpty(T)) { + return 0; + } + + n = StrLength(S); + m = StrLength(T); + i = pos; + + // ֤ȲԽ + while(i <= n - m + 1) { + // ȡS[i, i+m-1] + SubString(sub, S, i, m); + + // Ӵģʽƥ䣬Ҫƽ + if(StrCompare(sub, T) != 0) { + ++i; + } else { + return i; + } + } + + return 0; +} + +/* + * 㷨4.5 + * + * + * + * posʼģʽTS״γֵλãڣ򷵻0 + * ҳɹƥλá + * + *ע + * 1.ʵֲСӼ + * 2.ʵֱȽϵЧ + */ +int Index_2(SString S, SString T, int pos) { + int i = pos; + int j = 1; + + if(pos < 1 || pos > S[0] || StrEmpty(T)) { + return 0; + } + + while(i <= S[0] && j <= T[0]) { + // ַͬȽϺַ + if(S[i] == T[j]) { + i++; + j++; + + // ַͬαҪˣ±Ƚ + } else { + i = i - (j - 1) + 1; // j-1ͽ͵ǰj-1ԪأڵjԪϹһ + j = 1; // αjصTĵһλ + } + } + + // һT[0]>0ж + if(j > T[0] && T[0] > 0) { // TΪմ + return i - T[0]; // ƥɹ + } else { + return 0; + } +} + +/* + * + * + * T뵽Sposλô + */ +Status StrInsert(SString S, int pos, SString T) { + int i; + + if(pos < 1 || pos > S[0] + 1 || S[0] + T[0] > MAXSTRLEN) { + return ERROR; + } + + // ĴΪգǰ + if(StrEmpty(T)) { + return OK; + } + + // SڳλãΪT׼ + for(i = S[0]; i >= pos; i--) { + // ӺǰǰԪŲ + S[i + T[0]] = S[i]; + } + + // TSڳλ + for(i = pos; i <= pos + T[0] - 1; i++) { + S[i] = T[i - pos + 1]; + } + + // + S[0] += T[0]; + + 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; +} + +/* + * 滻 + * + * V滻SгֵTȵҲصӴ + * + *ע + * 1.òСӼ + * 2.ʵֱȽϵЧ + */ +Status Replace(SString S, SString T, SString V) { + int i; + + if(StrEmpty(S) || StrEmpty(T)) { + return ERROR; + } + + // SѰģʽTһγֵλ + i = Index_2(S, T, 1); + + // ƥַҿԱȫ滻滻 + while(i != 0 && S[0] - T[0] + V[0] <= MAXSTRLEN) { + StrDelete(S, i, StrLength(T)); // SɾT + StrInsert(S, i, V); // SвV + + i += StrLength(V); // iлһλ + + i = Index_2(S, T, i); // һƥַ + } + + if(i == 0) { // SеTȫ滻 + return OK; + } else { // STVѾ岻ȥ + return ERROR; + } +} + +/* + * 㷨4.2 + * + * + * + * S1S2洢TзءӺijֻδIJ֡ + * ֵʾӺĴǷ + * + *ע + * òСӼ + */ +Status Concat(SString T, SString S1, SString S2) { + int i; + int uncut; // ´Ƿ + + // ȫҪü + if(S1[0] + S2[0] <= MAXSTRLEN) { + // S1T + for(i = 1; i <= S1[0]; i++) { + T[i] = S1[i]; + } + + // S2T + for(i = S1[0] + 1; i <= S1[0] + S2[0]; i++) { + T[i] = S2[i - S1[0]]; + } + + // ³ + T[0] = S1[0] + S2[0]; + + // δü + uncut = TRUE; + + // ҪüS2 + } else if(S1[0] <= MAXSTRLEN) { + // S1T + for(i = 1; i <= S1[0]; i++) { + T[i] = S1[i]; + } + + // S2һָƵT + for(i = S1[0] + 1; i <= MAXSTRLEN; i++) { + T[i] = S2[i - S1[0]]; + } + + // ³ + T[0] = MAXSTRLEN; + + uncut = FALSE; + + // ֻҪS1һ + } else { + // ͬϢһ + for(i = 0; i <= MAXSTRLEN; i++) { + T[i] = S1[i]; + } + + uncut = FALSE; + } + + return uncut; +} + +// ӡַ +void StrPrint(SString S) { + int i; + + for(i = 1; i<=S[0] ; i++) { + printf("%c", S[i]); + } + + printf("\n"); +} diff --git a/VisualC++/ExerciseBook/04.18/SString.h b/VisualC++/ExerciseBook/04.18/SString.h new file mode 100644 index 0000000..386ffb8 --- /dev/null +++ b/VisualC++/ExerciseBook/04.18/SString.h @@ -0,0 +1,179 @@ +/*============================= + * Ķ˳洢ʾ˳򴮣 + * + * 㷨: 4.14.24.34.5 + ==============================*/ + +#ifndef SSTRING_H +#define SSTRING_H + +#include +#include // ṩstrlenԭ +#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 DestroyString(SString S); + +/* + * + * + * 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); + +/* + * 㷨4.1 + * + * + * + * posʼģʽTS״γֵλãڣ򷵻0 + * ҳɹƥλá + * + *ע + * 1.ʵҪСӼ + * 2.ʵֱȽϵЧ + */ +int Index_1(SString S, SString T, int pos); + +/* + * 㷨4.5 + * + * + * + * posʼģʽTS״γֵλãڣ򷵻0 + * ҳɹƥλá + * + *ע + * 1.ʵֲСӼ + * 2.ʵֱȽϵЧ + */ +int Index_2(SString S, SString T, int pos); + +/* + * + * + * T뵽Sposλô + */ +Status StrInsert(SString S, int pos, SString T); + +/* + * ɾ + * + * ɾ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); + +/* + * 滻 + * + * V滻SгֵTȵҲصӴ + * + *ע + * òСӼЧʽϵ͡ + */ +Status Replace(SString S, SString T, SString V); + +/* + * 㷨4.2 + * + * + * + * S1S2洢TзءӺijֻδIJ֡ + * ֵʾӺĴǷ + * + *ע + * òСӼ + */ +Status Concat(SString T, SString S1, SString S2); + +// ӡַ +void StrPrint(SString S); + +#endif diff --git a/VisualC++/ExerciseBook/04.19/04.19.c b/VisualC++/ExerciseBook/04.19/04.19.c new file mode 100644 index 0000000..9a2dbf0 --- /dev/null +++ b/VisualC++/ExerciseBook/04.19/04.19.c @@ -0,0 +1,77 @@ +#include +#include +#include "SString.h" //**04 **// + +/* + * R=S-STa洢RÿַSеһγֵλ + * + * עa0ŵԪ洢aԪصĸ + */ +void Algo_4_19(SString R, SString S, SString T, int** a); + + +int main(int argc, char* argv[]) { + char* s = "amdhcjgfdlpinbefcopgkqikeb"; + char* t = "mhjlpinopkqik"; + int* a; + SString T, S, R; + int i; + + printf("ʼST...\n"); + StrAssign(S, s); + StrAssign(T, t); + + printf("S = "); + StrPrint(S); + printf("T = "); + StrPrint(T); + + Algo_4_19(R, S, T, &a); + printf("R = "); + StrPrint(R); + printf("a = "); + for(i = 1; i <= a[0]; i++) { + printf("%d ", a[i]); + } + printf("\n"); + + return 0; +} + + +/* + * R=S-STa洢RÿַSеһγֵλ + * + * עa0ŵԪ洢aԪصĸ + */ +void Algo_4_19(SString R, SString S, SString T, int** a) { + int i, p; + SString ch; + + *a = (int*) malloc((StrLength(S) + 1) * sizeof(int)); + + StrAssign(R, ""); + + for(i = 1, (*a)[0] = 0; i <= StrLength(S); i++) { + // ȡַж + SubString(ch, S, i, 1); + + // ȡS[i]Tеλ + p = Index_2(T, ch, 1); + + // S[i]T + if(p == 0) { + // ȡS[i]Rеλ + p = Index_2(R, ch, 1); + } + + // S[i]ȲTУûRгֹ + if(p == 0) { + (*a)[0]++; + (*a)[(*a)[0]] = i; + + // RS[i] + StrInsert(R, (*a)[0], ch); + } + } +} diff --git a/VisualC++/ExerciseBook/04.19/04.19.vcxproj b/VisualC++/ExerciseBook/04.19/04.19.vcxproj new file mode 100644 index 0000000..aae0150 --- /dev/null +++ b/VisualC++/ExerciseBook/04.19/04.19.vcxproj @@ -0,0 +1,76 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {294751C9-0DB7-400C-8603-E1C194170B6C} + My0419 + + + + 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/04.19/04.19.vcxproj.filters b/VisualC++/ExerciseBook/04.19/04.19.vcxproj.filters new file mode 100644 index 0000000..cae42f2 --- /dev/null +++ b/VisualC++/ExerciseBook/04.19/04.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/04.19/04.19.vcxproj.user b/VisualC++/ExerciseBook/04.19/04.19.vcxproj.user new file mode 100644 index 0000000..ace9a86 --- /dev/null +++ b/VisualC++/ExerciseBook/04.19/04.19.vcxproj.user @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/04.19/SString.c b/VisualC++/ExerciseBook/04.19/SString.c new file mode 100644 index 0000000..fc4c757 --- /dev/null +++ b/VisualC++/ExerciseBook/04.19/SString.c @@ -0,0 +1,406 @@ +/*============================= + * Ķ˳洢ʾ˳򴮣 + * + * 㷨: 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 DestroyString(SString S) { + 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; +} + +/* + * 㷨4.1 + * + * + * + * posʼģʽTS״γֵλãڣ򷵻0 + * ҳɹƥλá + * + *ע + * 1.ʵҪСӼ + * 2.ʵֱȽϵЧ + */ +int Index_1(SString S, SString T, int pos) { + int i, n, m; // ¼STij + SString sub; + + /* + * ʧǰ + * ̲д΢ͬ + */ + if(pos < 1 || pos > S[0] || StrEmpty(T)) { + return 0; + } + + n = StrLength(S); + m = StrLength(T); + i = pos; + + // ֤ȲԽ + while(i <= n - m + 1) { + // ȡS[i, i+m-1] + SubString(sub, S, i, m); + + // Ӵģʽƥ䣬Ҫƽ + if(StrCompare(sub, T) != 0) { + ++i; + } else { + return i; + } + } + + return 0; +} + +/* + * 㷨4.5 + * + * + * + * posʼģʽTS״γֵλãڣ򷵻0 + * ҳɹƥλá + * + *ע + * 1.ʵֲСӼ + * 2.ʵֱȽϵЧ + */ +int Index_2(SString S, SString T, int pos) { + int i = pos; + int j = 1; + + if(pos < 1 || pos > S[0] || StrEmpty(T)) { + return 0; + } + + while(i <= S[0] && j <= T[0]) { + // ַͬȽϺַ + if(S[i] == T[j]) { + i++; + j++; + + // ַͬαҪˣ±Ƚ + } else { + i = i - (j - 1) + 1; // j-1ͽ͵ǰj-1ԪأڵjԪϹһ + j = 1; // αjصTĵһλ + } + } + + // һT[0]>0ж + if(j > T[0] && T[0] > 0) { // TΪմ + return i - T[0]; // ƥɹ + } else { + return 0; + } +} + +/* + * + * + * T뵽Sposλô + */ +Status StrInsert(SString S, int pos, SString T) { + int i; + + if(pos < 1 || pos > S[0] + 1 || S[0] + T[0] > MAXSTRLEN) { + return ERROR; + } + + // ĴΪգǰ + if(StrEmpty(T)) { + return OK; + } + + // SڳλãΪT׼ + for(i = S[0]; i >= pos; i--) { + // ӺǰǰԪŲ + S[i + T[0]] = S[i]; + } + + // TSڳλ + for(i = pos; i <= pos + T[0] - 1; i++) { + S[i] = T[i - pos + 1]; + } + + // + S[0] += T[0]; + + 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; +} + +/* + * 滻 + * + * V滻SгֵTȵҲصӴ + * + *ע + * 1.òСӼ + * 2.ʵֱȽϵЧ + */ +Status Replace(SString S, SString T, SString V) { + int i; + + if(StrEmpty(S) || StrEmpty(T)) { + return ERROR; + } + + // SѰģʽTһγֵλ + i = Index_2(S, T, 1); + + // ƥַҿԱȫ滻滻 + while(i != 0 && S[0] - T[0] + V[0] <= MAXSTRLEN) { + StrDelete(S, i, StrLength(T)); // SɾT + StrInsert(S, i, V); // SвV + + i += StrLength(V); // iлһλ + + i = Index_2(S, T, i); // һƥַ + } + + if(i == 0) { // SеTȫ滻 + return OK; + } else { // STVѾ岻ȥ + return ERROR; + } +} + +/* + * 㷨4.2 + * + * + * + * S1S2洢TзءӺijֻδIJ֡ + * ֵʾӺĴǷ + * + *ע + * òСӼ + */ +Status Concat(SString T, SString S1, SString S2) { + int i; + int uncut; // ´Ƿ + + // ȫҪü + if(S1[0] + S2[0] <= MAXSTRLEN) { + // S1T + for(i = 1; i <= S1[0]; i++) { + T[i] = S1[i]; + } + + // S2T + for(i = S1[0] + 1; i <= S1[0] + S2[0]; i++) { + T[i] = S2[i - S1[0]]; + } + + // ³ + T[0] = S1[0] + S2[0]; + + // δü + uncut = TRUE; + + // ҪüS2 + } else if(S1[0] <= MAXSTRLEN) { + // S1T + for(i = 1; i <= S1[0]; i++) { + T[i] = S1[i]; + } + + // S2һָƵT + for(i = S1[0] + 1; i <= MAXSTRLEN; i++) { + T[i] = S2[i - S1[0]]; + } + + // ³ + T[0] = MAXSTRLEN; + + uncut = FALSE; + + // ֻҪS1һ + } else { + // ͬϢһ + for(i = 0; i <= MAXSTRLEN; i++) { + T[i] = S1[i]; + } + + uncut = FALSE; + } + + return uncut; +} + +// ӡַ +void StrPrint(SString S) { + int i; + + for(i = 1; i<=S[0] ; i++) { + printf("%c", S[i]); + } + + printf("\n"); +} diff --git a/VisualC++/ExerciseBook/04.19/SString.h b/VisualC++/ExerciseBook/04.19/SString.h new file mode 100644 index 0000000..386ffb8 --- /dev/null +++ b/VisualC++/ExerciseBook/04.19/SString.h @@ -0,0 +1,179 @@ +/*============================= + * Ķ˳洢ʾ˳򴮣 + * + * 㷨: 4.14.24.34.5 + ==============================*/ + +#ifndef SSTRING_H +#define SSTRING_H + +#include +#include // ṩstrlenԭ +#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 DestroyString(SString S); + +/* + * + * + * 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); + +/* + * 㷨4.1 + * + * + * + * posʼģʽTS״γֵλãڣ򷵻0 + * ҳɹƥλá + * + *ע + * 1.ʵҪСӼ + * 2.ʵֱȽϵЧ + */ +int Index_1(SString S, SString T, int pos); + +/* + * 㷨4.5 + * + * + * + * posʼģʽTS״γֵλãڣ򷵻0 + * ҳɹƥλá + * + *ע + * 1.ʵֲСӼ + * 2.ʵֱȽϵЧ + */ +int Index_2(SString S, SString T, int pos); + +/* + * + * + * T뵽Sposλô + */ +Status StrInsert(SString S, int pos, SString T); + +/* + * ɾ + * + * ɾ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); + +/* + * 滻 + * + * V滻SгֵTȵҲصӴ + * + *ע + * òСӼЧʽϵ͡ + */ +Status Replace(SString S, SString T, SString V); + +/* + * 㷨4.2 + * + * + * + * S1S2洢TзءӺijֻδIJ֡ + * ֵʾӺĴǷ + * + *ע + * òСӼ + */ +Status Concat(SString T, SString S1, SString S2); + +// ӡַ +void StrPrint(SString S); + +#endif diff --git a/VisualC++/ExerciseBook/04.20/04.20.c b/VisualC++/ExerciseBook/04.20/04.20.c new file mode 100644 index 0000000..0a839aa --- /dev/null +++ b/VisualC++/ExerciseBook/04.20/04.20.c @@ -0,0 +1,47 @@ +#include +#include "Status.h" //**01 **// +#include "SString.h" //**04 **// + +/* + * ɾSаT + */ +Status Algo_4_20(SString S, SString T); + + +int main(int argc, char* argv[]) { + char* s = "----***--*-**-****-*****-----"; + char* t = "**"; + SString T, S; + + printf("ɾǰ...\n"); + StrAssign(S, s); + StrAssign(T, t); + printf("S = "); + StrPrint(S); + printf("T = "); + StrPrint(T); + + printf("ɾ...\n"); + printf("S = "); + Algo_4_20(S, T); + StrPrint(S); + + return 0; +} + + +/* + * ɾSаT + */ +Status Algo_4_20(SString S, SString T) { + int i; + + // SвTҵɾ + while((i = Index_2(S, T, 1)) != 0) { + if(StrDelete(S, i, StrLength(T)) == ERROR) { + return ERROR; + } + } + + return OK; +} diff --git a/VisualC++/ExerciseBook/04.20/04.20.vcxproj b/VisualC++/ExerciseBook/04.20/04.20.vcxproj new file mode 100644 index 0000000..afb395f --- /dev/null +++ b/VisualC++/ExerciseBook/04.20/04.20.vcxproj @@ -0,0 +1,76 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {96C98B39-7FA9-434A-BAB4-DCA6EBD5E0BA} + My0420 + + + + 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/04.20/04.20.vcxproj.filters b/VisualC++/ExerciseBook/04.20/04.20.vcxproj.filters new file mode 100644 index 0000000..327c1b0 --- /dev/null +++ b/VisualC++/ExerciseBook/04.20/04.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/04.20/04.20.vcxproj.user b/VisualC++/ExerciseBook/04.20/04.20.vcxproj.user new file mode 100644 index 0000000..ace9a86 --- /dev/null +++ b/VisualC++/ExerciseBook/04.20/04.20.vcxproj.user @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/04.20/SString.c b/VisualC++/ExerciseBook/04.20/SString.c new file mode 100644 index 0000000..fc4c757 --- /dev/null +++ b/VisualC++/ExerciseBook/04.20/SString.c @@ -0,0 +1,406 @@ +/*============================= + * Ķ˳洢ʾ˳򴮣 + * + * 㷨: 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 DestroyString(SString S) { + 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; +} + +/* + * 㷨4.1 + * + * + * + * posʼģʽTS״γֵλãڣ򷵻0 + * ҳɹƥλá + * + *ע + * 1.ʵҪСӼ + * 2.ʵֱȽϵЧ + */ +int Index_1(SString S, SString T, int pos) { + int i, n, m; // ¼STij + SString sub; + + /* + * ʧǰ + * ̲д΢ͬ + */ + if(pos < 1 || pos > S[0] || StrEmpty(T)) { + return 0; + } + + n = StrLength(S); + m = StrLength(T); + i = pos; + + // ֤ȲԽ + while(i <= n - m + 1) { + // ȡS[i, i+m-1] + SubString(sub, S, i, m); + + // Ӵģʽƥ䣬Ҫƽ + if(StrCompare(sub, T) != 0) { + ++i; + } else { + return i; + } + } + + return 0; +} + +/* + * 㷨4.5 + * + * + * + * posʼģʽTS״γֵλãڣ򷵻0 + * ҳɹƥλá + * + *ע + * 1.ʵֲСӼ + * 2.ʵֱȽϵЧ + */ +int Index_2(SString S, SString T, int pos) { + int i = pos; + int j = 1; + + if(pos < 1 || pos > S[0] || StrEmpty(T)) { + return 0; + } + + while(i <= S[0] && j <= T[0]) { + // ַͬȽϺַ + if(S[i] == T[j]) { + i++; + j++; + + // ַͬαҪˣ±Ƚ + } else { + i = i - (j - 1) + 1; // j-1ͽ͵ǰj-1ԪأڵjԪϹһ + j = 1; // αjصTĵһλ + } + } + + // һT[0]>0ж + if(j > T[0] && T[0] > 0) { // TΪմ + return i - T[0]; // ƥɹ + } else { + return 0; + } +} + +/* + * + * + * T뵽Sposλô + */ +Status StrInsert(SString S, int pos, SString T) { + int i; + + if(pos < 1 || pos > S[0] + 1 || S[0] + T[0] > MAXSTRLEN) { + return ERROR; + } + + // ĴΪգǰ + if(StrEmpty(T)) { + return OK; + } + + // SڳλãΪT׼ + for(i = S[0]; i >= pos; i--) { + // ӺǰǰԪŲ + S[i + T[0]] = S[i]; + } + + // TSڳλ + for(i = pos; i <= pos + T[0] - 1; i++) { + S[i] = T[i - pos + 1]; + } + + // + S[0] += T[0]; + + 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; +} + +/* + * 滻 + * + * V滻SгֵTȵҲصӴ + * + *ע + * 1.òСӼ + * 2.ʵֱȽϵЧ + */ +Status Replace(SString S, SString T, SString V) { + int i; + + if(StrEmpty(S) || StrEmpty(T)) { + return ERROR; + } + + // SѰģʽTһγֵλ + i = Index_2(S, T, 1); + + // ƥַҿԱȫ滻滻 + while(i != 0 && S[0] - T[0] + V[0] <= MAXSTRLEN) { + StrDelete(S, i, StrLength(T)); // SɾT + StrInsert(S, i, V); // SвV + + i += StrLength(V); // iлһλ + + i = Index_2(S, T, i); // һƥַ + } + + if(i == 0) { // SеTȫ滻 + return OK; + } else { // STVѾ岻ȥ + return ERROR; + } +} + +/* + * 㷨4.2 + * + * + * + * S1S2洢TзءӺijֻδIJ֡ + * ֵʾӺĴǷ + * + *ע + * òСӼ + */ +Status Concat(SString T, SString S1, SString S2) { + int i; + int uncut; // ´Ƿ + + // ȫҪü + if(S1[0] + S2[0] <= MAXSTRLEN) { + // S1T + for(i = 1; i <= S1[0]; i++) { + T[i] = S1[i]; + } + + // S2T + for(i = S1[0] + 1; i <= S1[0] + S2[0]; i++) { + T[i] = S2[i - S1[0]]; + } + + // ³ + T[0] = S1[0] + S2[0]; + + // δü + uncut = TRUE; + + // ҪüS2 + } else if(S1[0] <= MAXSTRLEN) { + // S1T + for(i = 1; i <= S1[0]; i++) { + T[i] = S1[i]; + } + + // S2һָƵT + for(i = S1[0] + 1; i <= MAXSTRLEN; i++) { + T[i] = S2[i - S1[0]]; + } + + // ³ + T[0] = MAXSTRLEN; + + uncut = FALSE; + + // ֻҪS1һ + } else { + // ͬϢһ + for(i = 0; i <= MAXSTRLEN; i++) { + T[i] = S1[i]; + } + + uncut = FALSE; + } + + return uncut; +} + +// ӡַ +void StrPrint(SString S) { + int i; + + for(i = 1; i<=S[0] ; i++) { + printf("%c", S[i]); + } + + printf("\n"); +} diff --git a/VisualC++/ExerciseBook/04.20/SString.h b/VisualC++/ExerciseBook/04.20/SString.h new file mode 100644 index 0000000..386ffb8 --- /dev/null +++ b/VisualC++/ExerciseBook/04.20/SString.h @@ -0,0 +1,179 @@ +/*============================= + * Ķ˳洢ʾ˳򴮣 + * + * 㷨: 4.14.24.34.5 + ==============================*/ + +#ifndef SSTRING_H +#define SSTRING_H + +#include +#include // ṩstrlenԭ +#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 DestroyString(SString S); + +/* + * + * + * 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); + +/* + * 㷨4.1 + * + * + * + * posʼģʽTS״γֵλãڣ򷵻0 + * ҳɹƥλá + * + *ע + * 1.ʵҪСӼ + * 2.ʵֱȽϵЧ + */ +int Index_1(SString S, SString T, int pos); + +/* + * 㷨4.5 + * + * + * + * posʼģʽTS״γֵλãڣ򷵻0 + * ҳɹƥλá + * + *ע + * 1.ʵֲСӼ + * 2.ʵֱȽϵЧ + */ +int Index_2(SString S, SString T, int pos); + +/* + * + * + * T뵽Sposλô + */ +Status StrInsert(SString S, int pos, SString T); + +/* + * ɾ + * + * ɾ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); + +/* + * 滻 + * + * V滻SгֵTȵҲصӴ + * + *ע + * òСӼЧʽϵ͡ + */ +Status Replace(SString S, SString T, SString V); + +/* + * 㷨4.2 + * + * + * + * S1S2洢TзءӺijֻδIJ֡ + * ֵʾӺĴǷ + * + *ע + * òСӼ + */ +Status Concat(SString T, SString S1, SString S2); + +// ӡַ +void StrPrint(SString S); + +#endif diff --git a/VisualC++/ExerciseBook/04.21/04.21.c b/VisualC++/ExerciseBook/04.21/04.21.c new file mode 100644 index 0000000..c9a2ab7 --- /dev/null +++ b/VisualC++/ExerciseBook/04.21/04.21.c @@ -0,0 +1,336 @@ +#include +#include // ṩ mallocreallocfreeexit ԭ +#include +#include "Status.h" //**01 **// + +/* + * ԪͶ + * + *ע + * ȻַԪȻintԭǣ + * 1.Ҫͷ洢intֱchar + * 2.charintݣԽȻintҲ洢char + */ +typedef int ElemType; + +/* + * ṹ + * + * עĵͷ + */ +typedef struct SNode { + ElemType data; // ݽ + struct SNode* next; // ָһָ +} SNode; + +// ָָ룬ַ +typedef SNode* String; + + +/* + * ʼ + * + * һֵΪcharsĴT + */ +Status StrAssign_4_21(String* S, char* chars); + +/* + * + * + * SƵT + */ +Status StrCopy_4_21(String* S, String T); + +/* + * Ƚ + * + * ȽϴSʹTرȽϽ + */ +int StrCompare_4_21(String S, String T); + +/* + * + * + * شSԪصĸ + */ +int StrLength_4_21(String S); + +/* + * + * + * S1S2洢TзءӺijֻδIJ֡ + * ֵʾӺĴǷ + */ +Status Concat_4_21(String* R, String S1, String S2); + +/* + * Ӵ + * + * SubS[pos, pos+len-1] + * ֵָʾǷȡɹ + */ +Status SubString_4_21(String* Sub, String S, int pos, int len); + +// ַ +void StrPrint_4_21(String S); + + +int main(int argc, char* argv[]) { + char* chars = "0123456789"; + String S, T; + int i; + + printf(" StrAssign \n"); + { + printf(" Ϊ˳ S ֵ...\n"); + StrAssign_4_21(&S, chars); + printf(" S = "); + StrPrint_4_21(S); + } + PressEnterToContinue(); + + printf(" StrLength \n"); + { + i = StrLength_4_21(S); + printf(" S ijΪ %d \n", i); + } + PressEnterToContinue(); + + printf(" StrCopy \n"); + { + printf(" S T ...\n"); + StrCopy_4_21(&T, S); + printf(" T = "); + StrPrint_4_21(T); + } + PressEnterToContinue(); + + printf(" StrCompare \n"); + { + printf(" Ƚַ S T ...\n"); + i = StrCompare_4_21(S, T); + i == 0 ? printf(" S==T\n") : (i < 0 ? printf(" ST\n")); + } + PressEnterToContinue(); + + printf(" SubString \n"); + { + String Sub; + + printf(" Sub S е 6 ַ 5 ַ...\n"); + SubString_4_21(&Sub, S, 6, 5); + printf(" Sub = "); + StrPrint_4_21(Sub); + } + PressEnterToContinue(); + + + printf(" Concat \n"); + { + String Tmp, S1, S2; + + StrAssign_4_21(&S1, "+++++"); + StrAssign_4_21(&S2, "-----"); + + printf(" \"+++++\" \"-----\" γ Tmp ...\n"); + Concat_4_21(&Tmp, S1, S2); + printf(" Tmp = "); + StrPrint_4_21(Tmp); + } + PressEnterToContinue(); + + return 0; +} + + +/* + * ʼ + * + * һֵΪcharsĴT + */ +Status StrAssign_4_21(String* S, char* chars) { + int i, len; + String p; + + if(S == NULL || chars == NULL) { + return ERROR; + } + + len = (int) strlen(chars); + + *S = (SNode*) malloc(sizeof(SNode)); + (*S)->data = len; + + p = *S; + + for(i = 0; i < len; i++) { + p->next = (SNode*) malloc(sizeof(SNode)); + p->next->data = chars[i]; + p = p->next; + } + + p->next = NULL; + + return OK; +} + +/* + * + * + * SƵT + */ +Status StrCopy_4_21(String* S, String T) { + String p, r, t; + + if(S == NULL || T == NULL) { + return ERROR; + } + + for(t = T; t != NULL; t = t->next) { + r = (SNode*) malloc(sizeof(SNode)); + r->data = t->data; + + if(t == T) { + *S = r; + p = r; + } else { + p->next = r; + p = p->next; + } + } + + p->next = NULL; + + return OK; +} + +/* + * Ƚ + * + * ȽϴSʹTرȽϽ + */ +int StrCompare_4_21(String S, String T) { + String s, t; + + if(S == NULL || T == NULL) { + return StrLength_4_21(S) - StrLength_4_21(T); + } + + s = S->next; + t = T->next; + + while(s != NULL && t != NULL) { + if(s->data != t->data) { + return s->data - t->data; + } + + s = s->next; + t = t->next; + } + + if(s == NULL && t != NULL) { + return -1; + } else if(s != NULL && t == NULL) { + return 1; + } else { + return 0; + } +} + +/* + * + * + * شSԪصĸ + */ +int StrLength_4_21(String S) { + return S == NULL ? 0 : S->data; +} + +/* + * + * + * S1S2洢TзءӺijֻδIJ֡ + * ֵʾӺĴǷ + */ +Status Concat_4_21(String* R, String S1, String S2) { + String r, s, p; + + if(R == NULL || S1 == NULL || S2 == NULL) { + return ERROR; + } + + *R = (SNode*) malloc(sizeof(SNode)); + (*R)->data = S1->data + S2->data; + + r = *R; + + for(s = S1->next; s != NULL; s = s->next) { + p = (SNode*) malloc(sizeof(SNode)); + p->data = s->data; + r->next = p; + r = r->next; + } + + for(s = S2->next; s != NULL; s = s->next) { + p = (SNode*) malloc(sizeof(SNode)); + p->data = s->data; + r->next = p; + r = r->next; + } + + r->next = NULL; + + return OK; +} + +/* + * Ӵ + * + * SubS[pos, pos+len-1] + * ֵָʾǷȡɹ + */ +Status SubString_4_21(String* Sub, String S, int pos, int len) { + int i, slen; + String sub, s, p; + + slen = StrLength_4_21(S); + + if(Sub == NULL || S == NULL || pos < 1 || pos > slen || len < 0 || pos + len - 1 > slen) { + return ERROR; + } + + *Sub = (SNode*) malloc(sizeof(SNode)); + (*Sub)->data = len; + + for(i = 0, s = S; i < pos; i++, s = s->next) { + // ҵpos㣬sָ + } + + sub = *Sub; + + for(i = 0; i < len; i++) { + sub->next = (SNode*) malloc(sizeof(SNode)); + sub->next->data = s->data; + sub = sub->next; + + s = s->next; + } + + sub->next = NULL; + + return OK; +} + +// ַ +void StrPrint_4_21(String S) { + String p; + + if(S == NULL) { + return; + } + + for(p = S->next; p != NULL; p = p->next) { + printf("%c", p->data); + } + printf("\n"); +} diff --git a/VisualC++/ExerciseBook/04.21/04.21.vcxproj b/VisualC++/ExerciseBook/04.21/04.21.vcxproj new file mode 100644 index 0000000..c644bca --- /dev/null +++ b/VisualC++/ExerciseBook/04.21/04.21.vcxproj @@ -0,0 +1,72 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {6D3C3AC9-1F42-4212-A16F-AB6A20ED95EF} + My0421 + + + + 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/04.21/04.21.vcxproj.filters b/VisualC++/ExerciseBook/04.21/04.21.vcxproj.filters new file mode 100644 index 0000000..f4aedd9 --- /dev/null +++ b/VisualC++/ExerciseBook/04.21/04.21.vcxproj.filters @@ -0,0 +1,22 @@ + + + + + {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/04.21/04.21.vcxproj.user b/VisualC++/ExerciseBook/04.21/04.21.vcxproj.user new file mode 100644 index 0000000..ace9a86 --- /dev/null +++ b/VisualC++/ExerciseBook/04.21/04.21.vcxproj.user @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/04.22/04.22.c b/VisualC++/ExerciseBook/04.22/04.22.c new file mode 100644 index 0000000..e493de2 --- /dev/null +++ b/VisualC++/ExerciseBook/04.22/04.22.c @@ -0,0 +1,59 @@ +#include +#include "LString.h" //**04 **// + +/* + * S뵽Tеַc֮ + * жcS뵽ұTʱ׸c֮ + * TڲcS뵽Tĩβ + */ +void Algo_4_22(LString* T, char ch, LString S); + + +int main(int argc, char* argv[]) { + char* t = "----***--*-**-**^**-*****-----"; + char* s = "12345"; + char ch = '^'; + LString T, S; + + StrAssign(&T, t); + StrAssign(&S, s); + printf("T = "); + StrPrint(T); + printf("S = "); + StrPrint(S); + + Algo_4_22(&T, ch, S); + printf("T = "); + StrPrint(T); + + return 0; +} + + +/* + * S뵽Tеַc֮ + * жcS뵽ұTʱ׸c֮ + * TڲcS뵽Tĩβ + */ +void Algo_4_22(LString* T, char c, LString S) { + int i; + char tmp[2]; + LString Tmp; + + // Ŀ괮 + tmp[0] = c; + tmp[1] = '\0'; + StrAssign(&Tmp, tmp); + + // ѰַcTеλ + i = Index((*T), Tmp, 1); + + // ҵcS뵽ַc֮ + if(i != 0) { + StrInsert(T, i + 1, S); + + // ûҵcS뵽Tĩβ + } else { + StrInsert(T, (*T).curlen + 1, S); + } +} diff --git a/VisualC++/ExerciseBook/04.22/04.22.vcxproj b/VisualC++/ExerciseBook/04.22/04.22.vcxproj new file mode 100644 index 0000000..431e953 --- /dev/null +++ b/VisualC++/ExerciseBook/04.22/04.22.vcxproj @@ -0,0 +1,76 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {A8758334-BC63-451B-8CA2-AA69E86B4BAC} + My0422 + + + + 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/04.22/04.22.vcxproj.filters b/VisualC++/ExerciseBook/04.22/04.22.vcxproj.filters new file mode 100644 index 0000000..11edce2 --- /dev/null +++ b/VisualC++/ExerciseBook/04.22/04.22.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/04.22/04.22.vcxproj.user b/VisualC++/ExerciseBook/04.22/04.22.vcxproj.user new file mode 100644 index 0000000..ace9a86 --- /dev/null +++ b/VisualC++/ExerciseBook/04.22/04.22.vcxproj.user @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/04.22/LString.c b/VisualC++/ExerciseBook/04.22/LString.c new file mode 100644 index 0000000..954ac09 --- /dev/null +++ b/VisualC++/ExerciseBook/04.22/LString.c @@ -0,0 +1,747 @@ +/*============================= + * Ŀ洢ʾ + ==============================*/ + +#include "LString.h" //**04 **// + +/* + * ʼ + * + * һֵΪcharsĴT + * + *ע + * òСӼ + */ +Status StrAssign(LString* T, const char* chars) { + int len; // charsij + int i, count; // ַcharsα + int m; // ܿ + int n; // δĿ飬洢ÿеЧԪ + Chunk* r; + + // charsij + len = (int) strlen(chars); + + // ûЧԪ + if(len == 0) { + (*T).head = NULL; + (*T).tail = NULL; + (*T).curlen = 0; + + return OK; + } + + m = len / CHUNKSIZE; // ȼҪĿ + n = len % CHUNKSIZE; // δĿ飬ÿЧԪ + if(n != 0) { + m++; // ܿ + } + + // 1.Ľṹ + for(i = 1; i <= m; i++) { + // ¿ + r = (Chunk*) malloc(sizeof(Chunk)); + if(r == NULL) { + exit(OVERFLOW); + } + r->next = NULL; + + // һ + if(i == 1) { + (*T).head = (*T).tail = r; + + // ӺĿ + } else { + (*T).tail->next = r; + (*T).tail = r; + } + } + + r = (*T).head; + i = 0; // Tα + count = 0; // ͳƱԪأ˳Ϊcharsα + + // 2.Ϊ + while(count < len) { + r->ch[i] = chars[count]; + + i = (i + 1) % CHUNKSIZE; + if(i == 0) { + r = r->next; // ָһ + } + + count++; + } + + // 3.δĿ + if(n != 0) { + // Ǵֵ('\0') + while(i < CHUNKSIZE) { + (*T).tail->ch[i] = '\0'; + i++; + } + } + + // 4.¼Ϣ + (*T).curlen = len; + + return OK; +} + +/* + * + * + *ע + * Ľṹ٣ٲ + */ +Status DestroyString(LString* S) { + return OK; +} + +/* + * + * + * Sա + */ +Status ClearString(LString* S) { + Chunk* p, * q; + + p = (*S).head; + + // ͷдռõĿռ + while(p != NULL) { + q = p->next; + free(p); + p = q; + } + + (*S).head = NULL; + (*S).tail = NULL; + (*S).curlen = 0; + + return OK; +} + +/* + * п + * + * жϴSǷЧݡ + * + * ֵ + * TRUE : SΪ + * FALSE: SΪ + */ +Status StrEmpty(LString S) { + return S.curlen == 0 ? TRUE : FALSE; +} + +/* + * + * + * شSԪصĸ + * + *ע + * òСӼ + */ +int StrLength(LString S) { + return S.curlen; +} + +/* + * Ӵ + * + * SubS[pos, pos+len-1] + * ֵָʾǷȡɹ + * + *ע + * òСӼ + */ +Status SubString(LString* Sub, LString S, int pos, int len) { + int m; // Subܿ + int n; // SubδĿ飬洢ÿеЧԪ + int i, j, count; + Chunk* r, * p; + + if(pos < 1 || pos > S.curlen || len < 0 || pos + len - 1 > S.curlen) { + return ERROR; + } + + // ǽȡ0ַҪռ + if(len == 0) { + (*Sub).head = NULL; + (*Sub).tail = NULL; + (*Sub).curlen = 0; + + return OK; + } + + m = len / CHUNKSIZE; // ȼҪĿ + n = len % CHUNKSIZE; // SubδĿ飬ÿЧԪ + if(n != 0) { + m++; // Subܿ + } + + // 1.SubĽṹ + for(i = 1; i <= m; i++) { + // ¿ + r = (Chunk*) malloc(sizeof(Chunk)); + if(r == NULL) { + exit(OVERFLOW); + } + r->next = NULL; + + // һ + if(i == 1) { + (*Sub).head = (*Sub).tail = r; + + // ӺĿ + } else { + (*Sub).tail->next = r; + (*Sub).tail = r; + } + } + + // SеposԪڵĿ飬ָpָ + for(count = 1, p = S.head; pos > count * CHUNKSIZE; count++, p = p->next) { + // ѭ + } + + r = (*Sub).head; // ָSubĿ + + i = 0; // Subα + j = (pos - 1) % CHUNKSIZE; // S α + count = 0; // ͳƱԪ + + // 2.ΪSub + while(count < len) { + r->ch[i] = p->ch[j]; + + i = (i + 1) % CHUNKSIZE; + if(i == 0) { + r = r->next; // ָSubһ + } + + j = (j + 1) % CHUNKSIZE; + if(j == 0) { + p = p->next; // ָSһ + } + + count++; + } + + // 3.δĿ + if(n != 0) { + // Ǵֵ('\0') + while(i < CHUNKSIZE) { + (*Sub).tail->ch[i] = '\0'; + i++; + } + } + + // 4.¼Ϣ + (*Sub).curlen = len; + + return OK; +} + +/* + * + * + * posʼģʽTS״γֵλãڣ򷵻0 + * ҳɹƥλá + * + *ע + * 1.ʵҪСӼ + * 2.ʵֱȽϵЧ + */ +int Index(LString S, LString T, int pos) { + int i, s, t; + LString sub; + + if(pos < 1 || pos > S.curlen || StrEmpty(T)) { + return 0; + } + + s = S.curlen; //S + t = T.curlen; //ģʽT + i = pos; + + while(i + t - 1 <= s) { + // ȡS[i, i+m-1] + SubString(&sub, S, i, t); + + // Ӵģʽƥ䣬Ҫƽ + if(StrCompare(sub, T) != 0) { + ++i; + } else { + return i; + } + } + + return 0; //Ҳƥ򷵻0 +} + +/* + * + * + * T뵽Sposλô + */ +Status StrInsert(LString* S, int pos, LString T) { + Chunk* pre, * p; // preָĿǰpָĿ + Chunk* h, * t; // ָĿͷβ + Chunk* r; + Chunk* s; + int i, j, count; + + if(pos < 1 || pos > (*S).curlen + 1) { + return ERROR; + } + + // ĴΪգǰ + if(StrEmpty(T)) { + return OK; + } + + // ¼ʼֹ + h = t = NULL; + + // TеĿ飨ֻƽṹ + for(r = T.head; r != NULL; r = r->next) { + s = (Chunk*) malloc(sizeof(Chunk)); + if(s == NULL) { + exit(OVERFLOW); + } + s->next = NULL; + + if(r == T.head) { + h = t = s; + } else { + t->next = s; + t = s; + } + } + + // SеposԪڵĿ飨עΪĿ飩ָpreָǰ + if(pos >= 1 && pos <= CHUNKSIZE) { + pre = NULL; // ˵posԪڿΪhead + p = (*S).head; + } else { + for(count = 1, pre = (*S).head; count < (pos - 1) / CHUNKSIZE; count++, pre = pre->next) { + // ѭ + } + p = pre->next; + } + + /* + * htΧĿ뵽posڵĿ֮ǰ + */ + + if(pre == NULL) { + t->next = (*S).head; + (*S).head = h; + } else { + pre->next = h; + t->next = p; + } + + if(pre == (*S).tail) { + (*S).tail = t; + } + + /* + * ƶ/Ԫ + */ + + j = 0; + + // 뵽ijġм䡱 + if((pos - 1) % CHUNKSIZE != 0) { + // ƶĿposλ֮ǰԪ + for(i = 1; i <= (pos - 1) % CHUNKSIZE; i++) { + h->ch[j++] = p->ch[i - 1]; + p->ch[i - 1] = '\0'; + } + } + + r = T.head; + i = 0; + + // TеԪصS + for(count = 1; count <= T.curlen; count++) { + h->ch[j] = r->ch[i]; + + j = (j + 1) % CHUNKSIZE; + i = (i + 1) % CHUNKSIZE; + + if(j == 0) { + h = h->next; + } + + if(i == 0) { + r = r->next; + } + } + + // Tһа'\0' + if(T.curlen % CHUNKSIZE != 0) { + r = p; // ָĿ + i = (pos - 1) % CHUNKSIZE; + + // ƶĿposλü֮Ԫ + for(count = pos; count <= (*S).curlen; count++) { + h->ch[j] = r->ch[i]; + r->ch[i] = '\0'; + + j = (j + 1) % CHUNKSIZE; + i = (i + 1) % CHUNKSIZE; + + if(j == 0) { + h = h->next; + } + + if(i == 0) { + r = r->next; + } + } + } + + (*S).curlen += T.curlen; + + return OK; +} + +/* + * ɾ + * + * ɾS[pos, pos+len-1] + */ +Status StrDelete(LString* S, int pos, int len) { + Chunk* pre; // ָԪS[pos]ڵĿǰ + Chunk* p; // ָԪS[pos]ڵĿ + Chunk* q; // ָԪS[pos+len]ڵĿ + Chunk* r; + int i, j, count, total; + + if(pos < 1 || pos > (*S).curlen || len < 0 || pos + len - 1 > (*S).curlen) { + return ERROR; + } + + // ɾijΪ0ǰ + if(len == 0) { + return OK; + } + + // S[pos]ڵĿ飬ָpreָǰ + if(pos >= 1 && pos <= CHUNKSIZE) { + pre = NULL; // ˵posԪڿΪhead + p = (*S).head; + } else { + for(count = 1, pre = (*S).head; count < (pos - 1) / CHUNKSIZE; count++, pre = pre->next) { + // ѭ + } + p = pre->next; + } + + // S[pos+len]ڵĿ + for(count = (pos - 1) / CHUNKSIZE, q = p; count < (pos + len - 1) / CHUNKSIZE; count++, q = q->next) { + // ѭ + } + + // ҪƶԪظ + total = (*S).curlen - (pos + len) + 1; + + // յijȶ + (*S).curlen -= len; + + i = (pos - 1) % CHUNKSIZE; + j = (pos + len - 1) % CHUNKSIZE; + + if(p != q) { + // ɾpq֮Ŀ + r = p->next; + while(r != q) { + p->next = r->next; + free(r); + r = p->next; + } + + if(q == NULL) { + (*S).tail = p; + } + + // Ҫɾpָ + if((pos - 1) % CHUNKSIZE == 0) { + // pѾָͷ + if(pre == NULL) { + (*S).head = q; + } else { + pre->next = q; + } + + free(p); + p = q; + + if(q == NULL) { + (*S).tail = pre; + } + } + } + + // Ѿλ + if(p == q && i == j) { + return OK; + } + + for(count = 1; count <= total; count++) { + // ƶԪ + p->ch[i] = q->ch[j]; + + i = (i + 1) % CHUNKSIZE; + j = (j + 1) % CHUNKSIZE; + + if(i == 0) { + pre = p; + p = p->next; + } + + if(j == 0) { + q = q->next; + } + } + + // ǡĿ + if(i == 0) { + (*S).tail = pre; + r = p; + } else { + (*S).tail = p; + + // ʣಿǴֵַ + while(i < CHUNKSIZE) { + p->ch[i++] = '\0'; + } + + r = p->next; + } + + // ͷŶĿռ + while(r != NULL) { + (*S).tail->next = r->next; + free(r); + r = (*S).tail->next; + } + + return OK; +} + +/* + * Ƚ + * + * ȽϴSʹTرȽϽ + * + *ע + * òСӼ + */ +int StrCompare(LString S, LString T) { + int i; + Chunk* s = S.head; + Chunk* t = T.head; + + while(s != NULL && t != NULL) { + for(i = 0; i < CHUNKSIZE; i++) { + if(s->ch[i] != t->ch[i]) { + return s->ch[i] - t->ch[i]; + } + } + + s = s->next; + t = t->next; + } + + if(s != NULL) { + return 1; + } else if(t != NULL) { + return -1; + } else { + return 0; + } +} + +/* + * + * + * SƵT + */ +Status StrCopy(LString* T, LString S) { + int i; + Chunk* s, * p; + + for(p = S.head; p; p = p->next) { + s = (Chunk*) malloc(sizeof(Chunk)); + if(s == NULL) { + exit(OVERFLOW); + } + s->next = NULL; + + if(p == S.head) { + (*T).head = (*T).tail = s; + } else { + (*T).tail->next = s; + (*T).tail = s; + } + + for(i = 0; i < CHUNKSIZE; i++) { + (*s).ch[i] = (*p).ch[i]; + } + } + + (*T).curlen = S.curlen; + + return OK; +} + +/* + * 滻 + * + * V滻SгֵTȵҲصӴ + * + *ע + * 1.òСӼ + * 2.ʵֱȽϵЧ + */ +Status Replace(LString* S, LString T, LString V) { + int i; + + if(StrEmpty(*S) || StrEmpty(T)) { + return ERROR; + } + + // SѰģʽTһγֵλ + i = Index(*S, T, 1); + + // ƥַ + while(i != 0) { + StrDelete(S, i, StrLength(T)); // SɾT + StrInsert(S, i, V); // SвV + + i += StrLength(V); // iлһλ + + i = Index(*S, T, i); // һƥַ + } + + return OK; +} + +/* + * + * + * S1S2洢TзءӺijֻδIJ֡ + * ֵʾӺĴǷ + * + *ע + * òСӼ + */ +Status Concat(LString* T, LString S1, LString S2) { + Chunk* p; // S1S2 + Chunk* r; // T + Chunk* s; + int i, j, count; + + // 㳤Ϣ + (*T).curlen = S1.curlen + S2.curlen; + + // Ҫٸ + count = (*T).curlen / CHUNKSIZE + ((*T).curlen % CHUNKSIZE == 0 ? 0 : 1); + + // S1Ľṹ + for(i = 1; i <= count; i++) { + s = (Chunk*) malloc(sizeof(Chunk)); + if(s == NULL) { + exit(OVERFLOW); + } + s->next = NULL; + + if(i == 1) { + (*T).head = (*T).tail = s; + } else { + (*T).tail->next = s; + (*T).tail = s; + } + } + + i = 0; + r = (*T).head; + + // S1е + j = 0; + p = S1.head; + for(count = 0; count < S1.curlen; count++) { + r->ch[i] = p->ch[j]; + + i = (i + 1) % CHUNKSIZE; + j = (j + 1) % CHUNKSIZE; + + if(i == 0) { + r = r->next; + } + + if(j == 0) { + p = p->next; + } + } + + // S2е + j = 0; + p = S2.head; + for(count = 0; count < S2.curlen; count++) { + r->ch[i] = p->ch[j]; + + i = (i + 1) % CHUNKSIZE; + j = (j + 1) % CHUNKSIZE; + + if(i == 0) { + r = r->next; + } + + if(j == 0) { + p = p->next; + } + } + + // ĿռǴֵַ + if(i != 0) { + while(i < CHUNKSIZE) { + r->ch[i] = '\0'; + i++; + } + } + + return OK; +} + +// Ժӡַ +void StrPrint(LString S) { + int i = 0; + Chunk* p = S.head; + + if(S.curlen == 0 || S.head == NULL || S.tail == NULL) { + return; + } + + while(p != NULL) { + // Ǵֵʱ + if(p->ch[i] == '\0') { + break; + } + + printf("%c", p->ch[i]); + + i = (i + 1) % CHUNKSIZE; + + if(i == 0) { + p = p->next; + } + } + + printf("\n"); +} diff --git a/VisualC++/ExerciseBook/04.22/LString.h b/VisualC++/ExerciseBook/04.22/LString.h new file mode 100644 index 0000000..e6f19d1 --- /dev/null +++ b/VisualC++/ExerciseBook/04.22/LString.h @@ -0,0 +1,169 @@ +/*============================= + * Ŀ洢ʾ + ==============================*/ + +#ifndef LSTRING_H +#define LSTRING_H + +#include +#include // ṩmallocreallocfreeexitԭ +#include // ṩstrlenԭ +#include "Status.h" //**01 **// + +/* 궨 */ +#define CHUNKSIZE 3 // СԶ壩 + +/* Ŀ洢ṹ */ +typedef struct Chunk { + char ch[CHUNKSIZE]; // ǰе + struct Chunk* next; // ָһ +} Chunk; + +/* Ŀ洢Ͷ */ +typedef struct { + Chunk* head; //ͷָ + Chunk* tail; //βָ + int curlen; //ĵǰ +} LString; + + +/* + * ʾ + * + * ѭ̲ĵдϰߣposָʾַλ()1ʼ + */ + +/* + * ע + * + * 1.̲ʾʹ#ΪǴֵַʹCе\0ΪǴֵַ + * 2.ָ̲һУĩβ÷Ǵֵַġ + * СΪ4Ϊ14ĿΪ£ã -> ţƣǣ -> ɣʣˣ -> ͣ\0\0 + */ + + +/* + * ʼ + * + * һֵΪcharsĴT + * + *ע + * òСӼ + */ +Status StrAssign(LString* T, const char* chars); + +/* + * + * + * S١ + */ +Status DestroyString(LString* S); + +/* + * + * + * Sա + */ +Status ClearString(LString* S); + +/* + * п + * + * жϴSǷЧݡ + * + * ֵ + * TRUE : SΪ + * FALSE: SΪ + */ +Status StrEmpty(LString S); + +/* + * + * + * شSԪصĸ + * + *ע + * òСӼ + */ +int StrLength(LString S); + +/* + * Ӵ + * + * SubS[pos, pos+len-1] + * ֵָʾǷȡɹ + * + *ע + * òСӼ + */ +Status SubString(LString* Sub, LString S, int pos, int len); + +/* + * + * + * posʼģʽTS״γֵλãڣ򷵻0 + * ҳɹƥλá + * + *ע + * 1.ʵҪСӼ + * 2.ʵֱȽϵЧ + */ +int Index(LString S, LString T, int pos); + +/* + * + * + * T뵽Sposλô + */ +Status StrInsert(LString* S, int pos, LString T); + +/* + * ɾ + * + * ɾS[pos, pos+len-1] + */ +Status StrDelete(LString* S, int pos, int len); + +/* + * Ƚ + * + * ȽϴSʹTرȽϽ + * + *ע + * òСӼ + */ +Status StrCompare(LString S, LString T); + +/* + * + * + * SƵT + */ +Status StrCopy(LString* T, LString S); + +/* + * 滻 + * + * V滻SгֵTȵҲصӴ + * + *ע + * 1.òСӼ + * 2.ʵֱȽϵЧ + */ +Status Replace(LString* S, LString T, LString V); + +/* + * + * + * S1S2洢TзءӺijֻδIJ֡ + * ֵʾӺĴǷ + * + *ע + * òСӼ + */ +Status Concat(LString* T, LString S1, LString S2); + +// Ժӡַ +void StrPrint(LString S); + +#endif diff --git a/VisualC++/ExerciseBook/04.23/04.23.c b/VisualC++/ExerciseBook/04.23/04.23.c new file mode 100644 index 0000000..d310967 --- /dev/null +++ b/VisualC++/ExerciseBook/04.23/04.23.c @@ -0,0 +1,107 @@ +#include +#include "LString.h" //**04 **// + +/* + * жϸĴǷԳơ + * մַĴᱻΪǶԳƵġ + */ +Status Algo_4_23(LString T); + + +int main(int argc, char* argv[]) { + char* t = "abcdefgfedcba"; + LString T; + + StrAssign(&T, t); + printf("T = "); + StrPrint(T); + + Algo_4_23(T) ? printf("TǶԳƴ\n") : printf("TǷǶԳƴ\n"); + + return 0; +} + + +/* + * жϸĴǷԳơ + * մַĴᱻΪǶԳƵġ + */ +Status Algo_4_23(LString T) { + int len; // Tij + + int a1, b1; // Tǰ벿ֱ߽ + int a2, b2; // Tĺ벿ֱ߽ + int k; // ƱTʱҪԪ + int i; // Tʱα + Chunk* t; + + char* stack; // ģջ + int top; // ջα + + char c; // Tȡַ + + len = StrLength(T); + + // մΪǶԳƵ + if(len == 0) { + return OK; + } + + // ijż + if(len % 2 == 0) { + a1 = 0; + b1 = len / 2 - 1; + a2 = len / 2; + b2 = len - 1; + // ij + } else { + a1 = 0; + b1 = len / 2 - 1; + a2 = len / 2 + 1; + b2 = len - 1; + } + + stack = (char*) malloc(len * sizeof(char)); + top = -1; + + i = 0; + t = T.head; + + // ڴǰ벿֣ջ + for(k = a1; k <= b1; k++) { + c = t->ch[i]; + i = (i + 1) % CHUNKSIZE; + if(i == 0) { + t = t->next; + } + + stack[++top] = c; + } + + // ΪҪһַ + if(len % 2 == 1) { + i = (i + 1) % CHUNKSIZE; + if(i == 0) { + t = t->next; + } + } + + for(k = a2; k <= b2; k++) { + c = t->ch[i]; + i = (i + 1) % CHUNKSIZE; + if(i == 0) { + t = t->next; + } + + // ˲ԳƵַ + if(stack[top--] != c) { + return ERROR; + } + } + + if(top == -1) { + return OK; + } else { + return ERROR; + } +} diff --git a/VisualC++/ExerciseBook/04.23/04.23.vcxproj b/VisualC++/ExerciseBook/04.23/04.23.vcxproj new file mode 100644 index 0000000..6035df4 --- /dev/null +++ b/VisualC++/ExerciseBook/04.23/04.23.vcxproj @@ -0,0 +1,76 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {7AF60383-012E-4F71-98BF-8A0EA94A798D} + My0423 + + + + 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/04.23/04.23.vcxproj.filters b/VisualC++/ExerciseBook/04.23/04.23.vcxproj.filters new file mode 100644 index 0000000..f34db4a --- /dev/null +++ b/VisualC++/ExerciseBook/04.23/04.23.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/04.23/04.23.vcxproj.user b/VisualC++/ExerciseBook/04.23/04.23.vcxproj.user new file mode 100644 index 0000000..ace9a86 --- /dev/null +++ b/VisualC++/ExerciseBook/04.23/04.23.vcxproj.user @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/04.23/LString.c b/VisualC++/ExerciseBook/04.23/LString.c new file mode 100644 index 0000000..76b08fa --- /dev/null +++ b/VisualC++/ExerciseBook/04.23/LString.c @@ -0,0 +1,748 @@ +/*============================= + * Ŀ洢ʾ + ==============================*/ + +#include "LString.h" //**04 **// + +/* + * ʼ + * + * һֵΪcharsĴT + * + *ע + * òСӼ + */ +Status StrAssign(LString* T, const char* chars) { + int len; // charsij + int i, count; // ַcharsα + int m; // ܿ + int n; // δĿ飬洢ÿеЧԪ + Chunk* r; + + // charsij + len = (int) strlen(chars); + + // ûЧԪ + if(len == 0) { + (*T).head = NULL; + (*T).tail = NULL; + (*T).curlen = 0; + + return OK; + } + + m = len / CHUNKSIZE; // ȼҪĿ + n = len % CHUNKSIZE; // δĿ飬ÿЧԪ + if(n != 0) { + m++; // ܿ + } + + // 1.Ľṹ + for(i = 1; i <= m; i++) { + // ¿ + r = (Chunk*) malloc(sizeof(Chunk)); + if(r == NULL) { + exit(OVERFLOW); + } + r->next = NULL; + + // һ + if(i == 1) { + (*T).head = (*T).tail = r; + + // ӺĿ + } else { + (*T).tail->next = r; + (*T).tail = r; + } + } + + r = (*T).head; + i = 0; // Tα + count = 0; // ͳƱԪأ˳Ϊcharsα + + // 2.Ϊ + while(count < len) { + r->ch[i] = chars[count]; + + i = (i + 1) % CHUNKSIZE; + if(i == 0) { + r = r->next; // ָһ + } + + count++; + } + + // 3.δĿ + if(n != 0) { + // Ǵֵ('\0') + while(i < CHUNKSIZE) { + (*T).tail->ch[i] = '\0'; + i++; + } + } + + // 4.¼Ϣ + (*T).curlen = len; + + return OK; +} + +/* + * + * + *ע + * Ľṹ٣ٲ + */ +Status DestroyString(LString* S) { + return OK; +} + +/* + * + * + * Sա + */ +Status ClearString(LString* S) { + Chunk* p, * q; + + p = (*S).head; + + // ͷдռõĿռ + while(p != NULL) { + q = p->next; + free(p); + p = q; + } + + (*S).head = NULL; + (*S).tail = NULL; + (*S).curlen = 0; + + return OK; +} + +/* + * п + * + * жϴSǷЧݡ + * + * ֵ + * TRUE : SΪ + * FALSE: SΪ + */ +Status StrEmpty(LString S) { + return S.curlen == 0 ? TRUE : FALSE; +} + +/* + * + * + * شSԪصĸ + * + *ע + * òСӼ + */ +int StrLength(LString S) { + return S.curlen; +} + +/* + * Ӵ + * + * SubS[pos, pos+len-1] + * ֵָʾǷȡɹ + * + *ע + * òСӼ + */ +Status SubString(LString* Sub, LString S, int pos, int len) { + int m; // Subܿ + int n; // SubδĿ飬洢ÿеЧԪ + int i, j, count; + Chunk* r, * p; + + if(pos < 1 || pos > S.curlen || len < 0 || pos + len - 1 > S.curlen) { + return ERROR; + } + + // ǽȡ0ַҪռ + if(len == 0) { + (*Sub).head = NULL; + (*Sub).tail = NULL; + (*Sub).curlen = 0; + + return OK; + } + + m = len / CHUNKSIZE; // ȼҪĿ + n = len % CHUNKSIZE; // SubδĿ飬ÿЧԪ + if(n != 0) { + m++; // Subܿ + } + + // 1.SubĽṹ + for(i = 1; i <= m; i++) { + // ¿ + r = (Chunk*) malloc(sizeof(Chunk)); + if(r == NULL) { + exit(OVERFLOW); + } + r->next = NULL; + + // һ + if(i == 1) { + (*Sub).head = (*Sub).tail = r; + + // ӺĿ + } else { + (*Sub).tail->next = r; + (*Sub).tail = r; + } + } + + // SеposԪڵĿ飬ָpָ + for(count = 1, p = S.head; pos > count * CHUNKSIZE; count++, p = p->next) { + // ѭ + } + + r = (*Sub).head; // ָSubĿ + + i = 0; // Subα + j = (pos - 1) % CHUNKSIZE; // S α + count = 0; // ͳƱԪ + + // 2.ΪSub + while(count < len) { + r->ch[i] = p->ch[j]; + + i = (i + 1) % CHUNKSIZE; + if(i == 0) { + r = r->next; // ָSubһ + } + + j = (j + 1) % CHUNKSIZE; + if(j == 0) { + p = p->next; // ָSһ + } + + count++; + } + + // 3.δĿ + if(n != 0) { + // Ǵֵ('\0') + while(i < CHUNKSIZE) { + (*Sub).tail->ch[i] = '\0'; + i++; + } + } + + // 4.¼Ϣ + (*Sub).curlen = len; + + return OK; +} + +/* + * + * + * posʼģʽTS״γֵλãڣ򷵻0 + * ҳɹƥλá + * + *ע + * 1.ʵҪСӼ + * 2.ʵֱȽϵЧ + */ +int Index(LString S, LString T, int pos) { + int i, s, t; + LString sub; + + if(pos < 1 || pos > S.curlen || StrEmpty(T)) { + return 0; + } + + s = S.curlen; //S + t = T.curlen; //ģʽT + i = pos; + + while(i + t - 1 <= s) { + // ȡS[i, i+m-1] + SubString(&sub, S, i, t); + + // Ӵģʽƥ䣬Ҫƽ + if(StrCompare(sub, T) != 0) { + ++i; + } else { + return i; + } + } + + return 0; //Ҳƥ򷵻0 +} + +/* + * + * + * T뵽Sposλô + */ +Status StrInsert(LString* S, int pos, LString T) { + Chunk* pre, * p; // preָĿǰpָĿ + Chunk* h, * t; // ָĿͷβ + Chunk* r; + Chunk* s; + int i, j, count; + + if(pos < 1 || pos > (*S).curlen + 1) { + return ERROR; + } + + // ĴΪգǰ + if(StrEmpty(T)) { + return OK; + } + + // ¼ʼֹ + h = t = NULL; + + // TеĿ飨ֻƽṹ + for(r = T.head; r != NULL; r = r->next) { + s = (Chunk*) malloc(sizeof(Chunk)); + if(s == NULL) { + exit(OVERFLOW); + } + s->next = NULL; + + if(r == T.head) { + h = t = s; + } else { + t->next = s; + t = s; + } + } + + // SеposԪڵĿ飨עΪĿ飩ָpreָǰ + if(pos >= 1 && pos <= CHUNKSIZE) { + pre = NULL; // ˵posԪڿΪhead + p = (*S).head; + } else { + for(count = 1, pre = (*S).head; count < (pos - 1) / CHUNKSIZE; count++, pre = pre->next) { + // ѭ + } + p = pre->next; + } + + /* + * htΧĿ뵽posڵĿ֮ǰ + */ + + if(pre == NULL) { + t->next = (*S).head; + (*S).head = h; + } else { + pre->next = h; + t->next = p; + } + + if(pre == (*S).tail) { + (*S).tail = t; + } + + /* + * ƶ/Ԫ + */ + + j = 0; + + // 뵽ijġм䡱 + if((pos - 1) % CHUNKSIZE != 0) { + // ƶĿposλ֮ǰԪ + for(i = 1; i <= (pos - 1) % CHUNKSIZE; i++) { + h->ch[j++] = p->ch[i - 1]; + p->ch[i - 1] = '\0'; + } + } + + r = T.head; + i = 0; + + // TеԪصS + for(count = 1; count <= T.curlen; count++) { + h->ch[j] = r->ch[i]; + + j = (j + 1) % CHUNKSIZE; + i = (i + 1) % CHUNKSIZE; + + if(j == 0) { + h = h->next; + } + + if(i == 0) { + r = r->next; + } + } + + // Tһа'\0' + if(T.curlen % CHUNKSIZE != 0) { + r = p; // ָĿ + i = (pos - 1) % CHUNKSIZE; + + // ƶĿposλü֮Ԫ + for(count = pos; count <= (*S).curlen; count++) { + h->ch[j] = r->ch[i]; + r->ch[i] = '\0'; + + j = (j + 1) % CHUNKSIZE; + i = (i + 1) % CHUNKSIZE; + + if(j == 0) { + h = h->next; + } + + if(i == 0) { + r = r->next; + } + } + } + + (*S).curlen += T.curlen; + + return OK; +} + +/* + * ɾ + * + * ɾS[pos, pos+len-1] + */ +Status StrDelete(LString* S, int pos, int len) { + Chunk* pre; // ָԪS[pos]ڵĿǰ + Chunk* p; // ָԪS[pos]ڵĿ + Chunk* q; // ָԪS[pos+len]ڵĿ + Chunk* r; + int i, j, count, total; + + if(pos < 1 || pos > (*S).curlen || len < 0 || pos + len - 1 > (*S).curlen) { + return ERROR; + } + + // ɾijΪ0ǰ + if(len == 0) { + return OK; + } + + // S[pos]ڵĿ飬ָpreָǰ + if(pos >= 1 && pos <= CHUNKSIZE) { + pre = NULL; // ˵posԪڿΪhead + p = (*S).head; + } else { + for(count = 1, pre = (*S).head; count < (pos - 1) / CHUNKSIZE; count++, pre = pre->next) { + // ѭ + } + p = pre->next; + } + + // S[pos+len]ڵĿ + for(count = (pos - 1) / CHUNKSIZE, q = p; count < (pos + len - 1) / CHUNKSIZE; count++, q = q->next) { + // ѭ + } + + // ҪƶԪظ + total = (*S).curlen - (pos + len) + 1; + + // յijȶ + (*S).curlen -= len; + + i = (pos - 1) % CHUNKSIZE; + j = (pos + len - 1) % CHUNKSIZE; + + if(p != q) { + // ɾpq֮Ŀ + r = p->next; + while(r != q) { + p->next = r->next; + free(r); + r = p->next; + } + + if(q == NULL) { + (*S).tail = p; + } + + // Ҫɾpָ + if((pos - 1) % CHUNKSIZE == 0) { + // pѾָͷ + if(pre == NULL) { + (*S).head = q; + } else { + pre->next = q; + } + + free(p); + p = q; + + if(q == NULL) { + (*S).tail = pre; + } + } + } + + // Ѿλ + if(p == q && i == j) { + return OK; + } + + for(count = 1; count <= total; count++) { + // ƶԪ + p->ch[i] = q->ch[j]; + + i = (i + 1) % CHUNKSIZE; + j = (j + 1) % CHUNKSIZE; + + if(i == 0) { + pre = p; + p = p->next; + } + + if(j == 0) { + q = q->next; + } + } + + // ǡĿ + if(i == 0) { + (*S).tail = pre; + r = p; + } else { + (*S).tail = p; + + // ʣಿǴֵַ + while(i < CHUNKSIZE) { + p->ch[i++] = '\0'; + } + + r = p->next; + } + + // ͷŶĿռ + while(r != NULL) { + (*S).tail->next = r->next; + free(r); + r = (*S).tail->next; + } + + return OK; +} + +/* + * Ƚ + * + * ȽϴSʹTرȽϽ + * + *ע + * òСӼ + */ +int StrCompare(LString S, LString T) { + int i; + Chunk* s = S.head; + Chunk* t = T.head; + + while(s != NULL && t != NULL) { + for(i = 0; i < CHUNKSIZE; i++) { + if(s->ch[i] != t->ch[i]) { + return s->ch[i] - t->ch[i]; + } + } + + s = s->next; + t = t->next; + } + + if(s != NULL) { + return 1; + } else if(t != NULL) { + return -1; + } else { + return 0; + } +} + +/* + * + * + * SƵT + */ +Status StrCopy(LString* T, LString S) { + int i; + Chunk* s, * p; + + for(p = S.head; p; p = p->next) { + s = (Chunk*) malloc(sizeof(Chunk)); + if(s == NULL) { + exit(OVERFLOW); + } + s->next = NULL; + + if(p == S.head) { + (*T).head = (*T).tail = s; + } else { + (*T).tail->next = s; + (*T).tail = s; + } + + for(i = 0; i < CHUNKSIZE; i++) { + (*s).ch[i] = (*p).ch[i]; + } + } + + (*T).curlen = S.curlen; + + return OK; +} + +/* + * 滻 + * + * V滻SгֵTȵҲصӴ + * + *ע + * 1.òСӼ + * 2.ʵֱȽϵЧ + */ +Status Replace(LString* S, LString T, LString V) { + int i; + + if(StrEmpty(*S) || StrEmpty(T)) { + return ERROR; + } + + // SѰģʽTһγֵλ + i = Index(*S, T, 1); + + // ƥַ + while(i != 0) { + StrDelete(S, i, StrLength(T)); // SɾT + StrInsert(S, i, V); // SвV + + i += StrLength(V); // iлһλ + + i = Index(*S, T, i); // һƥַ + } + + return OK; +} + +/* + * + * + * S1S2洢TзءӺijֻδIJ֡ + * ֵʾӺĴǷ + * + *ע + * òСӼ + */ +Status Concat(LString* T, LString S1, LString S2) { + Chunk* p; // S1S2 + Chunk* r; // T + Chunk* s; + int i, j, count; + + // 㳤Ϣ + (*T).curlen = S1.curlen + S2.curlen; + + // Ҫٸ + count = (*T).curlen / CHUNKSIZE + ((*T).curlen % CHUNKSIZE == 0 ? 0 : 1); + + // S1Ľṹ + for(i = 1; i <= count; i++) { + s = (Chunk*) malloc(sizeof(Chunk)); + if(s == NULL) { + exit(OVERFLOW); + } + s->next = NULL; + + if(i == 1) { + (*T).head = (*T).tail = s; + } else { + (*T).tail->next = s; + (*T).tail = s; + } + } + + i = 0; + r = (*T).head; + + // S1е + j = 0; + p = S1.head; + for(count = 0; count < S1.curlen; count++) { + r->ch[i] = p->ch[j]; + + i = (i + 1) % CHUNKSIZE; + j = (j + 1) % CHUNKSIZE; + + if(i == 0) { + r = r->next; + } + + if(j == 0) { + p = p->next; + } + } + + // S2е + j = 0; + p = S2.head; + for(count = 0; count < S2.curlen; count++) { + r->ch[i] = p->ch[j]; + + i = (i + 1) % CHUNKSIZE; + j = (j + 1) % CHUNKSIZE; + + if(i == 0) { + r = r->next; + } + + if(j == 0) { + p = p->next; + } + } + + // ĿռǴֵַ + if(i != 0) { + while(i < CHUNKSIZE) { + r->ch[i] = '\0'; + i++; + } + } + + return OK; +} + +// Ժӡַ +void StrPrint(LString S) { + int i = 0; + Chunk* p = S.head; + + if(S.curlen == 0 || S.head == NULL || S.tail == NULL) { + printf("\n"); + return; + } + + while(p != NULL) { + // Ǵֵʱ + if(p->ch[i] == '\0') { + break; + } + + printf("%c", p->ch[i]); + + i = (i + 1) % CHUNKSIZE; + + if(i == 0) { + p = p->next; + } + } + + printf("\n"); +} diff --git a/VisualC++/ExerciseBook/04.23/LString.h b/VisualC++/ExerciseBook/04.23/LString.h new file mode 100644 index 0000000..e6f19d1 --- /dev/null +++ b/VisualC++/ExerciseBook/04.23/LString.h @@ -0,0 +1,169 @@ +/*============================= + * Ŀ洢ʾ + ==============================*/ + +#ifndef LSTRING_H +#define LSTRING_H + +#include +#include // ṩmallocreallocfreeexitԭ +#include // ṩstrlenԭ +#include "Status.h" //**01 **// + +/* 궨 */ +#define CHUNKSIZE 3 // СԶ壩 + +/* Ŀ洢ṹ */ +typedef struct Chunk { + char ch[CHUNKSIZE]; // ǰе + struct Chunk* next; // ָһ +} Chunk; + +/* Ŀ洢Ͷ */ +typedef struct { + Chunk* head; //ͷָ + Chunk* tail; //βָ + int curlen; //ĵǰ +} LString; + + +/* + * ʾ + * + * ѭ̲ĵдϰߣposָʾַλ()1ʼ + */ + +/* + * ע + * + * 1.̲ʾʹ#ΪǴֵַʹCе\0ΪǴֵַ + * 2.ָ̲һУĩβ÷Ǵֵַġ + * СΪ4Ϊ14ĿΪ£ã -> ţƣǣ -> ɣʣˣ -> ͣ\0\0 + */ + + +/* + * ʼ + * + * һֵΪcharsĴT + * + *ע + * òСӼ + */ +Status StrAssign(LString* T, const char* chars); + +/* + * + * + * S١ + */ +Status DestroyString(LString* S); + +/* + * + * + * Sա + */ +Status ClearString(LString* S); + +/* + * п + * + * жϴSǷЧݡ + * + * ֵ + * TRUE : SΪ + * FALSE: SΪ + */ +Status StrEmpty(LString S); + +/* + * + * + * شSԪصĸ + * + *ע + * òСӼ + */ +int StrLength(LString S); + +/* + * Ӵ + * + * SubS[pos, pos+len-1] + * ֵָʾǷȡɹ + * + *ע + * òСӼ + */ +Status SubString(LString* Sub, LString S, int pos, int len); + +/* + * + * + * posʼģʽTS״γֵλãڣ򷵻0 + * ҳɹƥλá + * + *ע + * 1.ʵҪСӼ + * 2.ʵֱȽϵЧ + */ +int Index(LString S, LString T, int pos); + +/* + * + * + * T뵽Sposλô + */ +Status StrInsert(LString* S, int pos, LString T); + +/* + * ɾ + * + * ɾS[pos, pos+len-1] + */ +Status StrDelete(LString* S, int pos, int len); + +/* + * Ƚ + * + * ȽϴSʹTرȽϽ + * + *ע + * òСӼ + */ +Status StrCompare(LString S, LString T); + +/* + * + * + * SƵT + */ +Status StrCopy(LString* T, LString S); + +/* + * 滻 + * + * V滻SгֵTȵҲصӴ + * + *ע + * 1.òСӼ + * 2.ʵֱȽϵЧ + */ +Status Replace(LString* S, LString T, LString V); + +/* + * + * + * S1S2洢TзءӺijֻδIJ֡ + * ֵʾӺĴǷ + * + *ע + * òСӼ + */ +Status Concat(LString* T, LString S1, LString S2); + +// Ժӡַ +void StrPrint(LString S); + +#endif diff --git a/VisualC++/ExerciseBook/04.24-04.26/04.24-04.26.c b/VisualC++/ExerciseBook/04.24-04.26/04.24-04.26.c new file mode 100644 index 0000000..e464ee6 --- /dev/null +++ b/VisualC++/ExerciseBook/04.24-04.26/04.24-04.26.c @@ -0,0 +1,101 @@ +#include +#include "Status.h" //**01 **// +#include "HString.h" //**04 **// + +/* + * ӣConcat + * + *ע + * úHStringļж + */ +Status Algo_4_24(HString* T, HString S1, HString S2); + +/* + * 滻Replace + * + *ע + * úHStringļж + */ +Status Algo_4_25(HString* S, HString T, HString V); + +/* + * 룺StrInsert + * + *ע + * úHStringļж + */ +Status Algo_4_26(HString* S, int pos, HString T); + + +int main(int argc, char* argv[]) { + char* s = "---*^***^*^*^*---"; + char* s1 = "*"; + char* s2 = "^*"; + char* v = "*_*"; + HString S1, S2, T, V, S; + + StrAssign(&S1, s1); + StrAssign(&S2, s2); + StrAssign(&V, v); + StrAssign(&S, s); + + printf("S1 = "); + StrPrint(S1); + printf("S2 = "); + StrPrint(S2); + printf("V = "); + StrPrint(V); + printf("S = "); + StrPrint(S); + + printf(" 4.24 ֤...\n"); + printf("S1S2ΪT...\n"); + Algo_4_24(&T, S1, S2); + printf("T = "); + StrPrint(T); + + printf(" 4.25 ֤...\n"); + printf(" V 滻 S е T...\n"); + Algo_4_25(&S, T, V); + printf("S = "); + StrPrint(S); + + printf(" 4.26 ֤...\n"); + printf(" T 뵽 S ĵ 2 λ...\n"); + Algo_4_26(&S, 2, T); + printf("S = "); + StrPrint(S); + + return 0; +} + + +/* + * ӣConcat + * + *ע + * úHStringļж + */ +Status Algo_4_24(HString* T, HString S1, HString S2) { + return Concat(T, S1, S2); +} + +/* + * 滻Replace + * + *ע + * úHStringļж + */ +Status Algo_4_25(HString* S, HString T, HString V) { + return Replace(S, T, V); +} + +/* + * 룺StrInsert + * + *ע + * úHStringļж + */ +Status Algo_4_26(HString* S, int pos, HString T) { + return StrInsert(S, pos, T); +} diff --git a/VisualC++/ExerciseBook/04.24-04.26/04.24-04.26.vcxproj b/VisualC++/ExerciseBook/04.24-04.26/04.24-04.26.vcxproj new file mode 100644 index 0000000..5377719 --- /dev/null +++ b/VisualC++/ExerciseBook/04.24-04.26/04.24-04.26.vcxproj @@ -0,0 +1,76 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {2F368B7A-8594-45B4-A5EC-91D79E72F614} + My04240426 + + + + 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/04.24-04.26/04.24-04.26.vcxproj.filters b/VisualC++/ExerciseBook/04.24-04.26/04.24-04.26.vcxproj.filters new file mode 100644 index 0000000..6ffb651 --- /dev/null +++ b/VisualC++/ExerciseBook/04.24-04.26/04.24-04.26.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/04.24-04.26/04.24-04.26.vcxproj.user b/VisualC++/ExerciseBook/04.24-04.26/04.24-04.26.vcxproj.user new file mode 100644 index 0000000..ace9a86 --- /dev/null +++ b/VisualC++/ExerciseBook/04.24-04.26/04.24-04.26.vcxproj.user @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/04.24-04.26/HString.c b/VisualC++/ExerciseBook/04.24-04.26/HString.c new file mode 100644 index 0000000..4ed501a --- /dev/null +++ b/VisualC++/ExerciseBook/04.24-04.26/HString.c @@ -0,0 +1,381 @@ +/*========================= + * Ķѷ洢ʾѴ + * + * 㷨: 4.4 + ==========================*/ + +#include "HString.h" //**04 **// + +/* + * ʼ + * + * һֵΪcharsĴT + * + *ע + * òСӼ + */ +Status StrAssign(HString* T, const char* chars) { + int i, j; + + // charsij + i = (int) strlen(chars); + + // ûЧԪ + if(i == 0) { + (*T).ch = NULL; + (*T).length = 0; + + return OK; + } + + // ЧԪʱҪ洢ռ + (*T).ch = (char*) malloc(i * sizeof(char)); + if(!((*T).ch)) { + exit(OVERFLOW); + } + + for(j = 0; j < i; j++) { + (*T).ch[j] = chars[j]; + } + + (*T).length = i; + + return OK; +} + +/* + * + * + * S١ + * + *ע + * ѴĽṹ٣ٲ + */ +Status DestroyString(HString* S) { + return OK; +} + +/* + * + * + * Sա + */ +Status ClearString(HString* S) { + // ûЧԪʱٶѴṹ + if((*S).ch != 0) { + free((*S).ch); + (*S).ch = NULL; + } + + (*S).length = 0; + + return OK; +} + +/* + * п + * + * жϴSǷЧݡ + * + * ֵ + * TRUE : SΪ + * FALSE: SΪ + */ +Status StrEmpty(HString S) { + return S.length == 0 ? TRUE : FALSE; +} + +/* + * + * + * شSԪصĸ + * + *ע + * òСӼ + */ +int StrLength(HString S) { + return S.length; +} + +/* + * Ӵ + * + * SubS[pos, pos+len-1] + * ֵָʾǷȡɹ + * + *ע + * òСӼ + */ +Status SubString(HString* Sub, HString S, int pos, int len) { + int i; + + if(pos < 1 || pos > S.length || len < 0 || pos + len - 1 > S.length) { + return ERROR; + } + + // ǽȡ0ַҪռ + if(len == 0) { + (*Sub).ch = NULL; + (*Sub).length = 0; + + return OK; + } + + (*Sub).ch = (char*) malloc(len * sizeof(char)); + if(!(*Sub).ch) { + exit(OVERFLOW); + } + + // Ԫ + for(i = 0; i < len; i++) { + (*Sub).ch[i] = S.ch[i + pos - 1]; + } + + // ȷ³ + (*Sub).length = len; + + return OK; +} + +/* + * + * + * posʼģʽTS״γֵλãڣ򷵻0 + * ҳɹƥλá + * + *ע + * 1.ʵҪСӼ + * 2.ʵֱȽϵЧ + */ +int Index(HString S, HString T, int pos) { + int i, s, t; + HString sub; + + if(pos < 1 || pos > S.length || StrEmpty(T)) { + return 0; + } + + s = S.length; + t = T.length; + i = pos; + + // ֤ȲԽ + while(i + t - 1 <= s) { + // ȡS[i, i+t-1] + SubString(&sub, S, i, t); + + // Ӵģʽƥ䣬Ҫƽ + if(StrCompare(sub, T) != 0) { + ++i; + } else { + return i; + } + } + + return 0; +} + +/* + * 㷨4.4 + * + * + * + * T뵽Sposλô + */ +Status StrInsert(HString* S, int pos, HString T) { + int i; + + if(pos < 1 || pos > (*S).length + 1) { + return ERROR; + } + + // ĴΪգǰ + if(StrEmpty(T)) { + return OK; + } + + // ¿ռ䣬ὫԪһƹȥ + (*S).ch = (char*) realloc((*S).ch, ((*S).length + T.length) * sizeof(char)); + if(!(*S).ch) { + exit(OVERFLOW); + } + + // SڳλãΪT׼ + for(i = (*S).length - 1; i >= pos - 1; i--) { + // ӺǰǰԪŲ + (*S).ch[i + T.length] = (*S).ch[i]; + } + + // TSڳλ + for(i = pos - 1; i <= pos + T.length - 2; i++) { + (*S).ch[i] = T.ch[i - pos + 1]; + } + + // + (*S).length += T.length; + + return OK; +} + +/* + * ɾ + * + * ɾS[pos, pos+len-1] + */ +Status StrDelete(HString* S, int pos, int len) { + int i; + + if(pos < 1 || pos + len - 1 > (*S).length || len < 0) { + return ERROR; + } + + // ɾijΪ0ǰ + if(len == 0) { + return OK; + } + + // ѺԪŲǰ棬ǵɾԪ + for(i = pos + len - 1; i <= (*S).length - 1; i++) { + (*S).ch[i - len] = (*S).ch[i]; + } + + // ȼ + (*S).length -= len; + + // Ŀռ䣨ȼΪ0᷵ؿָ룩 + (*S).ch = (char*) realloc((*S).ch, (*S).length * sizeof(char)); + + return OK; +} + +/* + * Ƚ + * + * ȽϴSʹTرȽϽ + * + *ע + * òСӼ + */ +Status StrCompare(HString S, HString T) { + int i; + + for(i = 0; i < S.length && i < T.length; i++) { + // ַͬʱȽС + if(S.ch[i] != T.ch[i]) { + return S.ch[i] - T.ch[i]; + } + } + + return S.length - T.length; +} + +/* + * + * + * SƵT + */ +Status StrCopy(HString* T, HString S) { + int i; + + if(StrEmpty(S)) { + (*T).ch = NULL; + (*T).length = 0; + } else { + // ռ + (*T).ch = (char*) malloc(S.length * sizeof(char)); + if(!(*T).ch) { + exit(OVERFLOW); + } + + // Ԫ + for(i = 0; i < S.length; i++) { + (*T).ch[i] = S.ch[i]; + } + + // ƳϢ + (*T).length = S.length; + } + + return OK; +} + +/* + * 滻 + * + * V滻SгֵTȵҲصӴ + * + *ע + * 1.òСӼ + * 2.ʵֱȽϵЧ + */ +Status Replace(HString* S, HString T, HString V) { + int i; + + if(StrEmpty(*S) || StrEmpty(T)) { + return ERROR; + } + + // SѰģʽTһγֵλ + i = Index(*S, T, 1); + + // ƥַ + while(i != 0) { + StrDelete(S, i, StrLength(T)); // SɾT + StrInsert(S, i, V); // SвV + + i += StrLength(V); // iлһλ + + i = Index(*S, T, i); // һƥַ + } + + return OK; +} + +/* + * + * + * S1S2洢TзءӺijֻδIJ֡ + * ֵʾӺĴǷ + * ѴĿռ䱻Ϊ޵ģǷTRUEָʾᱻü + * + *ע + * òСӼ + */ +Status Concat(HString* T, HString S1, HString S2) { + int i; + + // ȷ³ + (*T).length = S1.length + S2.length; + + // ռ + (*T).ch = (char*) malloc((*T).length * sizeof(char)); + if(!(*T).ch) { + exit(OVERFLOW); + } + + // ȰS1ݿ + for(i = 0; i < S1.length; i++) { + (*T).ch[i] = S1.ch[i]; + } + + // ٿS2 + for(i = 0; i < S2.length; i++) { + (*T).ch[S1.length + i] = S2.ch[i]; + } + + return TRUE; +} + +// ӡַ +void StrPrint(HString S) { + int i; + + if(S.length == 0) { + return; + } + + for(i = 0; i < S.length; i++) { + printf("%c", S.ch[i]); + } + printf("\n"); +} \ No newline at end of file diff --git a/VisualC++/ExerciseBook/04.24-04.26/HString.h b/VisualC++/ExerciseBook/04.24-04.26/HString.h new file mode 100644 index 0000000..3d13eaf --- /dev/null +++ b/VisualC++/ExerciseBook/04.24-04.26/HString.h @@ -0,0 +1,159 @@ +/*========================= + * Ķѷ洢ʾѴ + * + * 㷨: 4.4 + ==========================*/ + +#ifndef HSTRING +#define HSTRING + +#include +#include // ṩmallocreallocfreeexitԭ +#include // ṩstrlenԭ +#include "Status.h" //**01 **// + +/* + * ĶѴ洢ʾ + * + * עЧԪشch0ŵԪʼ洢 + */ +typedef struct { + char* ch; // Ƿǿմ򰴴洢chΪNULL + int length; +} HString; + + +/* + * ʾ + * + * ѭ̲ĵдϰߣposָʾַλ()1ʼ + */ + + +/* + * ʼ + * + * һֵΪcharsĴT + * + *ע + * òСӼ + */ +Status StrAssign(HString* T, const char* chars); + +/* + * + * + * S١ + */ +Status DestroyString(HString* S); + +/* + * + * + * Sա + */ +Status ClearString(HString* S); + +/* + * п + * + * жϴSǷЧݡ + * + * ֵ + * TRUE : SΪ + * FALSE: SΪ + */ +Status StrEmpty(HString S); + +/* + * + * + * شSԪصĸ + * + *ע + * òСӼ + */ +int StrLength(HString S); + +/* + * Ӵ + * + * SubS[pos, pos+len-1] + * ֵָʾǷȡɹ + * + *ע + * òСӼ + */ +Status SubString(HString* Sub, HString S, int pos, int len); + +/* + * + * + * posʼģʽTS״γֵλãڣ򷵻0 + * ҳɹƥλá + * + *ע + * 1.ʵҪСӼ + * 2.ʵֱȽϵЧ + */ +int Index(HString S, HString T, int pos); + +/* + * 㷨4.4 + * + * + * + * T뵽Sposλô + */ +Status StrInsert(HString* S, int pos, HString T); + +/* + * ɾ + * + * ɾS[pos, pos+len-1] + */ +Status StrDelete(HString* S, int pos, int len); + +/* + * Ƚ + * + * ȽϴSʹTرȽϽ + * + *ע + * òСӼ + */ +Status StrCompare(HString S, HString T); + +/* + * + * + * SƵT + */ +Status StrCopy(HString* T, HString S); + +/* + * 滻 + * + * V滻SгֵTȵҲصӴ + * + *ע + * 1.òСӼ + * 2.ʵֱȽϵЧ + */ +Status Replace(HString* S, HString T, HString V); + +/* + * + * + * S1S2洢TзءӺijֻδIJ֡ + * ֵʾӺĴǷ + * + *ע + * òСӼ + */ +Status Concat(HString* T, HString S1, HString S2); + +// ӡַ +void StrPrint(HString S); + +#endif diff --git a/VisualC++/ExerciseBook/04.27/04.27.c b/VisualC++/ExerciseBook/04.27/04.27.c new file mode 100644 index 0000000..89fb62d --- /dev/null +++ b/VisualC++/ExerciseBook/04.27/04.27.c @@ -0,0 +1,81 @@ +#include +#include "SString.h" //**04 **// + +/* ԭ */ +int Algo_4_27(SString S, SString T, int pos); + + +/* + * ңIndex + * + * posʼģʽTS״γֵλãڣ򷵻0 + * ҳɹƥλá + * + *ע + * 봫ͳIndexĽ֮ڻȱȽ׸ַĩβַ + * ǶƥʱŻȽʣµַ + */ +int main(int argc, char* argv[]) { + char* s = "aaaaaaaaaaaaaaab"; + char* t = "aaaab"; + SString S, T; + + StrAssign(S, s); + StrAssign(T, t); + printf("S = "); + StrPrint(S); + printf("T = "); + StrPrint(T); + + printf("TS״γֵλΪ"); + printf("%d\n", Algo_4_27(S, T, 1)); + + return 0; +} + + +/* + * ңIndex + * + * posʼģʽTS״γֵλãڣ򷵻0 + * ҳɹƥλá + * + *ע + * 봫ͳIndexĽ֮ڻȱȽ׸ַĩβַ + * ǶƥʱŻȽʣµַ + */ +int Algo_4_27(SString S, SString T, int pos) { + int i, j; + + if(pos < 1 || pos > S[0] || T[0] == 0) { + return 0; + } + + i = pos; + j = 1; + + while(i <= S[0] - T[0] + 1) { + // ȳԱȽ׸ַĩβַ + if(S[i] != T[j] || S[i + T[0] - 1] != T[T[0]]) { + i++; + continue; + } + + // jҪT[0]ΪT[0]Ѿ֤ + for(i++,j++; j + + + + Debug + Win32 + + + Release + Win32 + + + + {00CECE39-4250-4727-B210-4B306167F129} + My0427 + + + + 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/04.27/04.27.vcxproj.filters b/VisualC++/ExerciseBook/04.27/04.27.vcxproj.filters new file mode 100644 index 0000000..3bba698 --- /dev/null +++ b/VisualC++/ExerciseBook/04.27/04.27.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/04.27/04.27.vcxproj.user b/VisualC++/ExerciseBook/04.27/04.27.vcxproj.user new file mode 100644 index 0000000..ace9a86 --- /dev/null +++ b/VisualC++/ExerciseBook/04.27/04.27.vcxproj.user @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/04.27/SString.c b/VisualC++/ExerciseBook/04.27/SString.c new file mode 100644 index 0000000..fc4c757 --- /dev/null +++ b/VisualC++/ExerciseBook/04.27/SString.c @@ -0,0 +1,406 @@ +/*============================= + * Ķ˳洢ʾ˳򴮣 + * + * 㷨: 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 DestroyString(SString S) { + 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; +} + +/* + * 㷨4.1 + * + * + * + * posʼģʽTS״γֵλãڣ򷵻0 + * ҳɹƥλá + * + *ע + * 1.ʵҪСӼ + * 2.ʵֱȽϵЧ + */ +int Index_1(SString S, SString T, int pos) { + int i, n, m; // ¼STij + SString sub; + + /* + * ʧǰ + * ̲д΢ͬ + */ + if(pos < 1 || pos > S[0] || StrEmpty(T)) { + return 0; + } + + n = StrLength(S); + m = StrLength(T); + i = pos; + + // ֤ȲԽ + while(i <= n - m + 1) { + // ȡS[i, i+m-1] + SubString(sub, S, i, m); + + // Ӵģʽƥ䣬Ҫƽ + if(StrCompare(sub, T) != 0) { + ++i; + } else { + return i; + } + } + + return 0; +} + +/* + * 㷨4.5 + * + * + * + * posʼģʽTS״γֵλãڣ򷵻0 + * ҳɹƥλá + * + *ע + * 1.ʵֲСӼ + * 2.ʵֱȽϵЧ + */ +int Index_2(SString S, SString T, int pos) { + int i = pos; + int j = 1; + + if(pos < 1 || pos > S[0] || StrEmpty(T)) { + return 0; + } + + while(i <= S[0] && j <= T[0]) { + // ַͬȽϺַ + if(S[i] == T[j]) { + i++; + j++; + + // ַͬαҪˣ±Ƚ + } else { + i = i - (j - 1) + 1; // j-1ͽ͵ǰj-1ԪأڵjԪϹһ + j = 1; // αjصTĵһλ + } + } + + // һT[0]>0ж + if(j > T[0] && T[0] > 0) { // TΪմ + return i - T[0]; // ƥɹ + } else { + return 0; + } +} + +/* + * + * + * T뵽Sposλô + */ +Status StrInsert(SString S, int pos, SString T) { + int i; + + if(pos < 1 || pos > S[0] + 1 || S[0] + T[0] > MAXSTRLEN) { + return ERROR; + } + + // ĴΪգǰ + if(StrEmpty(T)) { + return OK; + } + + // SڳλãΪT׼ + for(i = S[0]; i >= pos; i--) { + // ӺǰǰԪŲ + S[i + T[0]] = S[i]; + } + + // TSڳλ + for(i = pos; i <= pos + T[0] - 1; i++) { + S[i] = T[i - pos + 1]; + } + + // + S[0] += T[0]; + + 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; +} + +/* + * 滻 + * + * V滻SгֵTȵҲصӴ + * + *ע + * 1.òСӼ + * 2.ʵֱȽϵЧ + */ +Status Replace(SString S, SString T, SString V) { + int i; + + if(StrEmpty(S) || StrEmpty(T)) { + return ERROR; + } + + // SѰģʽTһγֵλ + i = Index_2(S, T, 1); + + // ƥַҿԱȫ滻滻 + while(i != 0 && S[0] - T[0] + V[0] <= MAXSTRLEN) { + StrDelete(S, i, StrLength(T)); // SɾT + StrInsert(S, i, V); // SвV + + i += StrLength(V); // iлһλ + + i = Index_2(S, T, i); // һƥַ + } + + if(i == 0) { // SеTȫ滻 + return OK; + } else { // STVѾ岻ȥ + return ERROR; + } +} + +/* + * 㷨4.2 + * + * + * + * S1S2洢TзءӺijֻδIJ֡ + * ֵʾӺĴǷ + * + *ע + * òСӼ + */ +Status Concat(SString T, SString S1, SString S2) { + int i; + int uncut; // ´Ƿ + + // ȫҪü + if(S1[0] + S2[0] <= MAXSTRLEN) { + // S1T + for(i = 1; i <= S1[0]; i++) { + T[i] = S1[i]; + } + + // S2T + for(i = S1[0] + 1; i <= S1[0] + S2[0]; i++) { + T[i] = S2[i - S1[0]]; + } + + // ³ + T[0] = S1[0] + S2[0]; + + // δü + uncut = TRUE; + + // ҪüS2 + } else if(S1[0] <= MAXSTRLEN) { + // S1T + for(i = 1; i <= S1[0]; i++) { + T[i] = S1[i]; + } + + // S2һָƵT + for(i = S1[0] + 1; i <= MAXSTRLEN; i++) { + T[i] = S2[i - S1[0]]; + } + + // ³ + T[0] = MAXSTRLEN; + + uncut = FALSE; + + // ֻҪS1һ + } else { + // ͬϢһ + for(i = 0; i <= MAXSTRLEN; i++) { + T[i] = S1[i]; + } + + uncut = FALSE; + } + + return uncut; +} + +// ӡַ +void StrPrint(SString S) { + int i; + + for(i = 1; i<=S[0] ; i++) { + printf("%c", S[i]); + } + + printf("\n"); +} diff --git a/VisualC++/ExerciseBook/04.27/SString.h b/VisualC++/ExerciseBook/04.27/SString.h new file mode 100644 index 0000000..386ffb8 --- /dev/null +++ b/VisualC++/ExerciseBook/04.27/SString.h @@ -0,0 +1,179 @@ +/*============================= + * Ķ˳洢ʾ˳򴮣 + * + * 㷨: 4.14.24.34.5 + ==============================*/ + +#ifndef SSTRING_H +#define SSTRING_H + +#include +#include // ṩstrlenԭ +#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 DestroyString(SString S); + +/* + * + * + * 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); + +/* + * 㷨4.1 + * + * + * + * posʼģʽTS״γֵλãڣ򷵻0 + * ҳɹƥλá + * + *ע + * 1.ʵҪСӼ + * 2.ʵֱȽϵЧ + */ +int Index_1(SString S, SString T, int pos); + +/* + * 㷨4.5 + * + * + * + * posʼģʽTS״γֵλãڣ򷵻0 + * ҳɹƥλá + * + *ע + * 1.ʵֲСӼ + * 2.ʵֱȽϵЧ + */ +int Index_2(SString S, SString T, int pos); + +/* + * + * + * T뵽Sposλô + */ +Status StrInsert(SString S, int pos, SString T); + +/* + * ɾ + * + * ɾ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); + +/* + * 滻 + * + * V滻SгֵTȵҲصӴ + * + *ע + * òСӼЧʽϵ͡ + */ +Status Replace(SString S, SString T, SString V); + +/* + * 㷨4.2 + * + * + * + * S1S2洢TзءӺijֻδIJ֡ + * ֵʾӺĴǷ + * + *ע + * òСӼ + */ +Status Concat(SString T, SString S1, SString S2); + +// ӡַ +void StrPrint(SString S); + +#endif diff --git a/VisualC++/ExerciseBook/04.28-04.29/04.28-04.29.c b/VisualC++/ExerciseBook/04.28-04.29/04.28-04.29.c new file mode 100644 index 0000000..adca0c4 --- /dev/null +++ b/VisualC++/ExerciseBook/04.28-04.29/04.28-04.29.c @@ -0,0 +1,211 @@ +#include +#include +#include +#include "Status.h" //**01 **// + +/* + * ԪͶ + * + *ע + * ȻַԪȻintԭǣ + * 1.Ҫͷ洢intֱchar + * 2.charintݣԽȻintҲ洢char + */ +typedef int ElemType; + +/* ַ */ +typedef struct SNode { + ElemType chdata; // ݽ + struct SNode* succ; // ָ̽ + struct SNode* next; // nextУָǰ㣬ģʽУָý㴦ʧʱӦȽϵһ +} SNode; + +// ַ +typedef SNode* String; + + +// ʼ +Status StrAssign_4_28(String* S, char* chars); + +// 󴮳 +int StrLength_4_28(String S); + +// ַ +void StrPrint_4_28(String S); + +/* + * ģʽnextֵĽ㷨 + * + * ൱KMP㷨µget_nextval + */ +Status Algo_4_28(String T); + +/* + * KMP㷨 + * + * ൱KMP㷨µIndex_KMP + */ +int Algo_4_29(String S, String T, int pos); + + +int main(int argc, char* argv[]) { + char* s = "abaaabaababaabcaabaabcacabaabcaabaabcac"; + char* t = "abaabcac"; + String S, T; + int pos, i; + + StrAssign_4_28(&S, s); // + StrAssign_4_28(&T, t); //ģʽ + + printf("S = "); + StrPrint_4_28(S); + printf("ģʽT = "); + StrPrint_4_28(T); + + printf(" 4.28 ֤...\n"); + Algo_4_28(T); + printf("next...\n"); + + printf(" 4.29 ֤...\n"); + pos = 18; + i = Algo_4_29(S, T, pos); + printf("ģʽ T S ĵ %d ַһƥɹλΪ %d\n", pos, i); + + return 0; +} + + +// ʼ +Status StrAssign_4_28(String* S, char* chars) { + int i, len; + String p; + + if(S == NULL || chars == NULL) { + return ERROR; + } + + len = (int) strlen(chars); + + // ͷ + *S = (String) malloc(sizeof(SNode)); + (*S)->chdata = len; // ¼ij + (*S)->next = NULL; // ͷǰ + + p = *S; + + for(i = 0; i < len; i++) { + p->succ = (String) malloc(sizeof(SNode)); + p->succ->chdata = chars[i]; + p->succ->next = p; // nextĬָǰһ + p = p->succ; + } + + // һĺΪNULL + p->succ = NULL; + + return OK; +} + +// 󴮳 +int StrLength_4_28(String S) { + return S == NULL ? 0 : S->chdata; +} + +// ַ +void StrPrint_4_28(String S) { + String p; + + if(S == NULL) { + printf("\n"); + return; + } + + for(p = S->succ; p != NULL; p = p->succ) { + printf("%c", p->chdata); + } + + printf("\n"); +} + +/* + * ģʽnextֵĽ㷨 + * + * ൱KMP㷨µget_nextval + */ +Status Algo_4_28(String T) { + SNode* i, * j; + + if(StrLength_4_28(T) == 0) { + return ERROR; + } + + i = T->succ; // ൱֮ǰi=1 + j = T; // ൱֮ǰj=0 + + // ģʽһַʧʱģʽҪͷȽϣҪǰһλñȽ + i->next = T; + + // ģʽϵַ + while(i->succ != NULL) { + if(j == T || i->chdata == j->chdata) { + i = i->succ; + j = j->succ; + + if(i->chdata != j->chdata) { + i->next = j; + } else { + i->next = j->next; + } + } else { + j = j->next; + } + } + + return OK; +} + +/* + * KMP㷨 + * + * ൱KMP㷨µIndex_KMP + */ +int Algo_4_29(String S, String T, int pos) { + int count; // ¼iλ + SNode* i, * j; // iSjT + + if(pos < 1 || StrLength_4_28(S) == 0 || StrLength_4_28(T) == 0) { + return 0; + } + + for(count = 1, i = S->succ; count < pos; count++, i = i->succ) { + // iָpos + } + + j = T->succ; + + // Ƚַ + while(i != NULL && j != NULL) { + /* + * Σ + * 1.ģʽĵһַʧ + * 2.ģʽַ + */ + if(j == T || i->chdata == j->chdata) { + i = i->succ; + j = j->succ; + + count++; // ¼iλ + } else { + // ʧʱصǰһʵλ + j = j->next; + } + } + + // ƥɹƥλ + if(j == NULL) { + return count-StrLength_4_28(T); + } else { + // ƥʧ + return 0; + } +} diff --git a/VisualC++/ExerciseBook/04.28-04.29/04.28-04.29.vcxproj b/VisualC++/ExerciseBook/04.28-04.29/04.28-04.29.vcxproj new file mode 100644 index 0000000..ca92418 --- /dev/null +++ b/VisualC++/ExerciseBook/04.28-04.29/04.28-04.29.vcxproj @@ -0,0 +1,72 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {785893C0-9DEF-49B4-9A5F-9A6B784A089E} + My04280429 + + + + 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/04.28-04.29/04.28-04.29.vcxproj.filters b/VisualC++/ExerciseBook/04.28-04.29/04.28-04.29.vcxproj.filters new file mode 100644 index 0000000..3ee7cea --- /dev/null +++ b/VisualC++/ExerciseBook/04.28-04.29/04.28-04.29.vcxproj.filters @@ -0,0 +1,22 @@ + + + + + {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/04.28-04.29/04.28-04.29.vcxproj.user b/VisualC++/ExerciseBook/04.28-04.29/04.28-04.29.vcxproj.user new file mode 100644 index 0000000..ace9a86 --- /dev/null +++ b/VisualC++/ExerciseBook/04.28-04.29/04.28-04.29.vcxproj.user @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/04.30/04.30.c b/VisualC++/ExerciseBook/04.30/04.30.c new file mode 100644 index 0000000..eb772c7 --- /dev/null +++ b/VisualC++/ExerciseBook/04.30/04.30.c @@ -0,0 +1,116 @@ +#include +#include "SString.h" //**04 **// + +/* + * ڴSв״γֵظӴλ + * Sub¼ظӴ + * pos¼Sгֵλ + * + * ˴ظӴº壺 + * 1.Ӵ + * 2.ӴظӴ׸ģ + * 3.ӴصȡabcabcaĽΪabca + * 4.ӴڿظȡaaaaĽΪaaa + */ +Status Algo_4_30(SString S, SString Sub, int* pos); + + +int main(int argc, char* argv[]) { + char* s = "abcdeabcabcbcdefbcdefefghefgh"; + SString Sub, S; + int pos; + + StrAssign(S, s); + printf("...\n"); + printf("S = "); + StrPrint(S); + + printf("׸ظӴ...\n"); + printf("Sub = "); + Algo_4_30(S, Sub, &pos); + StrPrint(Sub); + printf("Sub S ״γֵλΪ %d\n", pos); + + return 0; +} + + +/* + * ڴSв״γֵظӴλ + * Sub¼ظӴ + * pos¼Sгֵλ + * + * ˴ظӴº壺 + * 1.Ӵ + * 2.ӴظӴ׸ģ + * 3.ӴصȡabcabcaĽΪabca + * 4.ӴڿظȡaaaaĽΪaaa + */ +Status Algo_4_30(SString S, SString Sub, int* pos) { + int i, j, is, js; + int k, start; + int len, maxLen; + + // Ȳ2 + if(S[0] < 2) { + return ERROR; + } + + start = 0; + maxLen = 0; + + // пܵ + for(k = 1; k < S[0]; k++) { + is = k; // + js = k + 1; // Ӵ + + // ʣַ֪ظַٱȥ + if(S[0] - js + 1 <= maxLen) { + break; + } + + // isΪĴظĴ + while(TRUE) { + // ѰDZڵظӴ + while(js <= S[0] && S[is] != S[js]) { + js++; + } + + // ˵㴦ַΨһ + if(js > S[0]) { + break; + } + + // ʣַ֪ظַٱȥ + if(S[0] - js + 1 <= maxLen) { + break; + } + + len = 0; + i = is; + j = js; + + // ظij + while(j <= S[0] && S[i] == S[j]) { + i++; + j++; + len++; + } + + if(len > maxLen) { + start = k; + maxLen = len; + } + + // 鿴ûиظ + if(j < S[0]) { + js++; + } + } + } + + *pos = start; + SubString(Sub, S, start, maxLen); + + return OK; +} diff --git a/VisualC++/ExerciseBook/04.30/04.30.vcxproj b/VisualC++/ExerciseBook/04.30/04.30.vcxproj new file mode 100644 index 0000000..c53768a --- /dev/null +++ b/VisualC++/ExerciseBook/04.30/04.30.vcxproj @@ -0,0 +1,76 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {9374E1C4-6DD6-4BB8-9DC0-5CA8E86FEA10} + My0430 + + + + 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/04.30/04.30.vcxproj.filters b/VisualC++/ExerciseBook/04.30/04.30.vcxproj.filters new file mode 100644 index 0000000..29f8f06 --- /dev/null +++ b/VisualC++/ExerciseBook/04.30/04.30.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/04.30/04.30.vcxproj.user b/VisualC++/ExerciseBook/04.30/04.30.vcxproj.user new file mode 100644 index 0000000..ace9a86 --- /dev/null +++ b/VisualC++/ExerciseBook/04.30/04.30.vcxproj.user @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/04.30/SString.c b/VisualC++/ExerciseBook/04.30/SString.c new file mode 100644 index 0000000..fc4c757 --- /dev/null +++ b/VisualC++/ExerciseBook/04.30/SString.c @@ -0,0 +1,406 @@ +/*============================= + * Ķ˳洢ʾ˳򴮣 + * + * 㷨: 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 DestroyString(SString S) { + 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; +} + +/* + * 㷨4.1 + * + * + * + * posʼģʽTS״γֵλãڣ򷵻0 + * ҳɹƥλá + * + *ע + * 1.ʵҪСӼ + * 2.ʵֱȽϵЧ + */ +int Index_1(SString S, SString T, int pos) { + int i, n, m; // ¼STij + SString sub; + + /* + * ʧǰ + * ̲д΢ͬ + */ + if(pos < 1 || pos > S[0] || StrEmpty(T)) { + return 0; + } + + n = StrLength(S); + m = StrLength(T); + i = pos; + + // ֤ȲԽ + while(i <= n - m + 1) { + // ȡS[i, i+m-1] + SubString(sub, S, i, m); + + // Ӵģʽƥ䣬Ҫƽ + if(StrCompare(sub, T) != 0) { + ++i; + } else { + return i; + } + } + + return 0; +} + +/* + * 㷨4.5 + * + * + * + * posʼģʽTS״γֵλãڣ򷵻0 + * ҳɹƥλá + * + *ע + * 1.ʵֲСӼ + * 2.ʵֱȽϵЧ + */ +int Index_2(SString S, SString T, int pos) { + int i = pos; + int j = 1; + + if(pos < 1 || pos > S[0] || StrEmpty(T)) { + return 0; + } + + while(i <= S[0] && j <= T[0]) { + // ַͬȽϺַ + if(S[i] == T[j]) { + i++; + j++; + + // ַͬαҪˣ±Ƚ + } else { + i = i - (j - 1) + 1; // j-1ͽ͵ǰj-1ԪأڵjԪϹһ + j = 1; // αjصTĵһλ + } + } + + // һT[0]>0ж + if(j > T[0] && T[0] > 0) { // TΪմ + return i - T[0]; // ƥɹ + } else { + return 0; + } +} + +/* + * + * + * T뵽Sposλô + */ +Status StrInsert(SString S, int pos, SString T) { + int i; + + if(pos < 1 || pos > S[0] + 1 || S[0] + T[0] > MAXSTRLEN) { + return ERROR; + } + + // ĴΪգǰ + if(StrEmpty(T)) { + return OK; + } + + // SڳλãΪT׼ + for(i = S[0]; i >= pos; i--) { + // ӺǰǰԪŲ + S[i + T[0]] = S[i]; + } + + // TSڳλ + for(i = pos; i <= pos + T[0] - 1; i++) { + S[i] = T[i - pos + 1]; + } + + // + S[0] += T[0]; + + 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; +} + +/* + * 滻 + * + * V滻SгֵTȵҲصӴ + * + *ע + * 1.òСӼ + * 2.ʵֱȽϵЧ + */ +Status Replace(SString S, SString T, SString V) { + int i; + + if(StrEmpty(S) || StrEmpty(T)) { + return ERROR; + } + + // SѰģʽTһγֵλ + i = Index_2(S, T, 1); + + // ƥַҿԱȫ滻滻 + while(i != 0 && S[0] - T[0] + V[0] <= MAXSTRLEN) { + StrDelete(S, i, StrLength(T)); // SɾT + StrInsert(S, i, V); // SвV + + i += StrLength(V); // iлһλ + + i = Index_2(S, T, i); // һƥַ + } + + if(i == 0) { // SеTȫ滻 + return OK; + } else { // STVѾ岻ȥ + return ERROR; + } +} + +/* + * 㷨4.2 + * + * + * + * S1S2洢TзءӺijֻδIJ֡ + * ֵʾӺĴǷ + * + *ע + * òСӼ + */ +Status Concat(SString T, SString S1, SString S2) { + int i; + int uncut; // ´Ƿ + + // ȫҪü + if(S1[0] + S2[0] <= MAXSTRLEN) { + // S1T + for(i = 1; i <= S1[0]; i++) { + T[i] = S1[i]; + } + + // S2T + for(i = S1[0] + 1; i <= S1[0] + S2[0]; i++) { + T[i] = S2[i - S1[0]]; + } + + // ³ + T[0] = S1[0] + S2[0]; + + // δü + uncut = TRUE; + + // ҪüS2 + } else if(S1[0] <= MAXSTRLEN) { + // S1T + for(i = 1; i <= S1[0]; i++) { + T[i] = S1[i]; + } + + // S2һָƵT + for(i = S1[0] + 1; i <= MAXSTRLEN; i++) { + T[i] = S2[i - S1[0]]; + } + + // ³ + T[0] = MAXSTRLEN; + + uncut = FALSE; + + // ֻҪS1һ + } else { + // ͬϢһ + for(i = 0; i <= MAXSTRLEN; i++) { + T[i] = S1[i]; + } + + uncut = FALSE; + } + + return uncut; +} + +// ӡַ +void StrPrint(SString S) { + int i; + + for(i = 1; i<=S[0] ; i++) { + printf("%c", S[i]); + } + + printf("\n"); +} diff --git a/VisualC++/ExerciseBook/04.30/SString.h b/VisualC++/ExerciseBook/04.30/SString.h new file mode 100644 index 0000000..386ffb8 --- /dev/null +++ b/VisualC++/ExerciseBook/04.30/SString.h @@ -0,0 +1,179 @@ +/*============================= + * Ķ˳洢ʾ˳򴮣 + * + * 㷨: 4.14.24.34.5 + ==============================*/ + +#ifndef SSTRING_H +#define SSTRING_H + +#include +#include // ṩstrlenԭ +#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 DestroyString(SString S); + +/* + * + * + * 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); + +/* + * 㷨4.1 + * + * + * + * posʼģʽTS״γֵλãڣ򷵻0 + * ҳɹƥλá + * + *ע + * 1.ʵҪСӼ + * 2.ʵֱȽϵЧ + */ +int Index_1(SString S, SString T, int pos); + +/* + * 㷨4.5 + * + * + * + * posʼģʽTS״γֵλãڣ򷵻0 + * ҳɹƥλá + * + *ע + * 1.ʵֲСӼ + * 2.ʵֱȽϵЧ + */ +int Index_2(SString S, SString T, int pos); + +/* + * + * + * T뵽Sposλô + */ +Status StrInsert(SString S, int pos, SString T); + +/* + * ɾ + * + * ɾ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); + +/* + * 滻 + * + * V滻SгֵTȵҲصӴ + * + *ע + * òСӼЧʽϵ͡ + */ +Status Replace(SString S, SString T, SString V); + +/* + * 㷨4.2 + * + * + * + * S1S2洢TзءӺijֻδIJ֡ + * ֵʾӺĴǷ + * + *ע + * òСӼ + */ +Status Concat(SString T, SString S1, SString S2); + +// ӡַ +void StrPrint(SString S); + +#endif diff --git a/VisualC++/ExerciseBook/04.31/04.31.c b/VisualC++/ExerciseBook/04.31/04.31.c new file mode 100644 index 0000000..91ede0d --- /dev/null +++ b/VisualC++/ExerciseBook/04.31/04.31.c @@ -0,0 +1,248 @@ +#include +#include +#include "Status.h" //**01 **// +#include "SString.h" //**04 **// + +/* + * ʾ + * + * һ̬滮⣬ϸ˼·μ㷨ۡ15.4ڡ + * + * ע㷨ۡе""ͳƲӴDZֻͳӴ + */ + + +/* Ӵ */ +typedef struct { + char dir; + int len; +} LCS; + +/* Ӵ */ +typedef struct { + int s; // ӴڴSеλ + int t; // ӴڴTеλ +} Pos; + +/* Ӵ */ +typedef struct { + int maxlen; // Ӵij + Pos* pos; // Ӵ + int count; // Ӵ +} Strs; + + +/* + * STеӴ + * + * УıΪ"һֵӴ" + */ +Status Algo_4_31(SString S, SString T); + +/* + * ȡӴϢ + */ +void LocationPos(SString S, SString T, Strs* strs); + +/* + * ӴȡӴijȡ + */ +Status BuildLCS(SString S, SString T, LCS*** lcs, int* maxLen); + +/* + * ӡӴѡ + */ +void PrintLCS(SString S, SString T, LCS** lcs); + + +int main(int argc, char* argv[]) { + char* s = "csajcu123456ewjfskhsdufasawx"; + char* t = "m123456vsadksjewjfshcdsdufassgcx"; + SString S, T; + + StrAssign(S, s); + StrAssign(T, t); + + Algo_4_31(S, T); + + return 0; +} + + +/* + * STеӴ + * + * УıΪ"һֵӴ" + */ +Status Algo_4_31(SString S, SString T) { + Strs strs; + SString sub; + int i; + + LocationPos(S, T, &strs); + + printf("ӴijΪ%d \n", strs.maxlen); + printf("Ӵ꣺\n"); + for(i=0; i=size) { + size += 10; + (*strs).pos = (Pos*) realloc((*strs).pos, size * sizeof(Pos)); + } + + (*strs).pos[(*strs).count].s = i-maxLen+1; + (*strs).pos[(*strs).count].t = j-maxLen+1; + (*strs).count++; + } + } +} + +/* + * ӴȡӴijȡ + */ +Status BuildLCS(SString S, SString T, LCS*** lcs, int* maxLen) { + int sLen, tLen; + int i, j; + int max; + LCS node; + + sLen = StrLength(S); + tLen = StrLength(T); + + if(sLen == 0 || tLen == 0) { + return ERROR; + } + + // ʼLCS + *lcs = (LCS**) malloc((sLen + 1) * sizeof(LCS*)); + for(i = 0; i <= sLen; i++) { + (*lcs)[i] = (LCS*) malloc((tLen + 1) * sizeof(LCS)); + } + + for(i = 0; i <= sLen; i++) { + (*lcs)[i][0].dir = ' '; + (*lcs)[i][0].len = 0; + } + + for(j = 0; j <= tLen; j++) { + (*lcs)[0][j].dir = ' '; + (*lcs)[0][j].len = 0; + } + + max = 0; + + for(i = 1; i <= sLen; i++) { + for(j = 1; j <= tLen; j++) { + // 롶㷨ۡеĽ΢ͬ˴ҪͳӴ + if(S[i] == T[j]) { + // ǰһַҲȣ˵ǸĹӴ + if(i > 1 && j > 1 && S[i - 1] == T[j - 1]) { + node.dir = '\\'; + node.len = (*lcs)[i - 1][j - 1].len + 1; + + // Ͽ + } else { + node.dir = ' '; + node.len = 1; + } + + if(node.len > max) { + max = node.len; + } + } else { + if((*lcs)[i - 1][j].len >= (*lcs)[i][j - 1].dir) { + node.dir = '^'; + node.len = (*lcs)[i - 1][j].len; + } else { + node.dir = '<'; + node.len = (*lcs)[i][j - 1].len; + } + } + + (*lcs)[i][j] = node; + } + } + + *maxLen = max; + + return ERROR; +} + +/* + * ӡӴѡ + */ +void PrintLCS(SString S, SString T, LCS** lcs) { + int sLen, tLen; + int i, j; + + sLen = StrLength(S); + tLen = StrLength(T); + + if(sLen == 0 || tLen == 0) { + return; + } + + // һ + printf(" "); + for(j = 1; j <= tLen; j++) { + printf(" %c ", T[j]); + } + printf("\n"); + + // ڶ + printf(" "); + for(j = 1; j <= tLen; j++) { + printf("--- "); + } + printf("\n"); + + for(i = 1; i <= sLen; i++) { + for(j = 1; j <= tLen; j++) { + // ÿһеĿʼ + if(j == 1) { + printf("%c |", S[i]); + } + + printf("%c%2d ", lcs[i][j].dir, lcs[i][j].len); + } + printf("\n"); + } + + printf("\n"); +} diff --git a/VisualC++/ExerciseBook/04.31/04.31.vcxproj b/VisualC++/ExerciseBook/04.31/04.31.vcxproj new file mode 100644 index 0000000..68b5a75 --- /dev/null +++ b/VisualC++/ExerciseBook/04.31/04.31.vcxproj @@ -0,0 +1,76 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {2FB26990-0C5E-47FB-9D0F-E3A202D2A47F} + My0431 + + + + 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/04.31/04.31.vcxproj.filters b/VisualC++/ExerciseBook/04.31/04.31.vcxproj.filters new file mode 100644 index 0000000..6b32ae5 --- /dev/null +++ b/VisualC++/ExerciseBook/04.31/04.31.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/04.31/04.31.vcxproj.user b/VisualC++/ExerciseBook/04.31/04.31.vcxproj.user new file mode 100644 index 0000000..ace9a86 --- /dev/null +++ b/VisualC++/ExerciseBook/04.31/04.31.vcxproj.user @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/VisualC++/ExerciseBook/04.31/SString.c b/VisualC++/ExerciseBook/04.31/SString.c new file mode 100644 index 0000000..fc4c757 --- /dev/null +++ b/VisualC++/ExerciseBook/04.31/SString.c @@ -0,0 +1,406 @@ +/*============================= + * Ķ˳洢ʾ˳򴮣 + * + * 㷨: 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 DestroyString(SString S) { + 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; +} + +/* + * 㷨4.1 + * + * + * + * posʼģʽTS״γֵλãڣ򷵻0 + * ҳɹƥλá + * + *ע + * 1.ʵҪСӼ + * 2.ʵֱȽϵЧ + */ +int Index_1(SString S, SString T, int pos) { + int i, n, m; // ¼STij + SString sub; + + /* + * ʧǰ + * ̲д΢ͬ + */ + if(pos < 1 || pos > S[0] || StrEmpty(T)) { + return 0; + } + + n = StrLength(S); + m = StrLength(T); + i = pos; + + // ֤ȲԽ + while(i <= n - m + 1) { + // ȡS[i, i+m-1] + SubString(sub, S, i, m); + + // Ӵģʽƥ䣬Ҫƽ + if(StrCompare(sub, T) != 0) { + ++i; + } else { + return i; + } + } + + return 0; +} + +/* + * 㷨4.5 + * + * + * + * posʼģʽTS״γֵλãڣ򷵻0 + * ҳɹƥλá + * + *ע + * 1.ʵֲСӼ + * 2.ʵֱȽϵЧ + */ +int Index_2(SString S, SString T, int pos) { + int i = pos; + int j = 1; + + if(pos < 1 || pos > S[0] || StrEmpty(T)) { + return 0; + } + + while(i <= S[0] && j <= T[0]) { + // ַͬȽϺַ + if(S[i] == T[j]) { + i++; + j++; + + // ַͬαҪˣ±Ƚ + } else { + i = i - (j - 1) + 1; // j-1ͽ͵ǰj-1ԪأڵjԪϹһ + j = 1; // αjصTĵһλ + } + } + + // һT[0]>0ж + if(j > T[0] && T[0] > 0) { // TΪմ + return i - T[0]; // ƥɹ + } else { + return 0; + } +} + +/* + * + * + * T뵽Sposλô + */ +Status StrInsert(SString S, int pos, SString T) { + int i; + + if(pos < 1 || pos > S[0] + 1 || S[0] + T[0] > MAXSTRLEN) { + return ERROR; + } + + // ĴΪգǰ + if(StrEmpty(T)) { + return OK; + } + + // SڳλãΪT׼ + for(i = S[0]; i >= pos; i--) { + // ӺǰǰԪŲ + S[i + T[0]] = S[i]; + } + + // TSڳλ + for(i = pos; i <= pos + T[0] - 1; i++) { + S[i] = T[i - pos + 1]; + } + + // + S[0] += T[0]; + + 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; +} + +/* + * 滻 + * + * V滻SгֵTȵҲصӴ + * + *ע + * 1.òСӼ + * 2.ʵֱȽϵЧ + */ +Status Replace(SString S, SString T, SString V) { + int i; + + if(StrEmpty(S) || StrEmpty(T)) { + return ERROR; + } + + // SѰģʽTһγֵλ + i = Index_2(S, T, 1); + + // ƥַҿԱȫ滻滻 + while(i != 0 && S[0] - T[0] + V[0] <= MAXSTRLEN) { + StrDelete(S, i, StrLength(T)); // SɾT + StrInsert(S, i, V); // SвV + + i += StrLength(V); // iлһλ + + i = Index_2(S, T, i); // һƥַ + } + + if(i == 0) { // SеTȫ滻 + return OK; + } else { // STVѾ岻ȥ + return ERROR; + } +} + +/* + * 㷨4.2 + * + * + * + * S1S2洢TзءӺijֻδIJ֡ + * ֵʾӺĴǷ + * + *ע + * òСӼ + */ +Status Concat(SString T, SString S1, SString S2) { + int i; + int uncut; // ´Ƿ + + // ȫҪü + if(S1[0] + S2[0] <= MAXSTRLEN) { + // S1T + for(i = 1; i <= S1[0]; i++) { + T[i] = S1[i]; + } + + // S2T + for(i = S1[0] + 1; i <= S1[0] + S2[0]; i++) { + T[i] = S2[i - S1[0]]; + } + + // ³ + T[0] = S1[0] + S2[0]; + + // δü + uncut = TRUE; + + // ҪüS2 + } else if(S1[0] <= MAXSTRLEN) { + // S1T + for(i = 1; i <= S1[0]; i++) { + T[i] = S1[i]; + } + + // S2һָƵT + for(i = S1[0] + 1; i <= MAXSTRLEN; i++) { + T[i] = S2[i - S1[0]]; + } + + // ³ + T[0] = MAXSTRLEN; + + uncut = FALSE; + + // ֻҪS1һ + } else { + // ͬϢһ + for(i = 0; i <= MAXSTRLEN; i++) { + T[i] = S1[i]; + } + + uncut = FALSE; + } + + return uncut; +} + +// ӡַ +void StrPrint(SString S) { + int i; + + for(i = 1; i<=S[0] ; i++) { + printf("%c", S[i]); + } + + printf("\n"); +} diff --git a/VisualC++/ExerciseBook/04.31/SString.h b/VisualC++/ExerciseBook/04.31/SString.h new file mode 100644 index 0000000..386ffb8 --- /dev/null +++ b/VisualC++/ExerciseBook/04.31/SString.h @@ -0,0 +1,179 @@ +/*============================= + * Ķ˳洢ʾ˳򴮣 + * + * 㷨: 4.14.24.34.5 + ==============================*/ + +#ifndef SSTRING_H +#define SSTRING_H + +#include +#include // ṩstrlenԭ +#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 DestroyString(SString S); + +/* + * + * + * 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); + +/* + * 㷨4.1 + * + * + * + * posʼģʽTS״γֵλãڣ򷵻0 + * ҳɹƥλá + * + *ע + * 1.ʵҪСӼ + * 2.ʵֱȽϵЧ + */ +int Index_1(SString S, SString T, int pos); + +/* + * 㷨4.5 + * + * + * + * posʼģʽTS״γֵλãڣ򷵻0 + * ҳɹƥλá + * + *ע + * 1.ʵֲСӼ + * 2.ʵֱȽϵЧ + */ +int Index_2(SString S, SString T, int pos); + +/* + * + * + * T뵽Sposλô + */ +Status StrInsert(SString S, int pos, SString T); + +/* + * ɾ + * + * ɾ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); + +/* + * 滻 + * + * V滻SгֵTȵҲصӴ + * + *ע + * òСӼЧʽϵ͡ + */ +Status Replace(SString S, SString T, SString V); + +/* + * 㷨4.2 + * + * + * + * S1S2洢TзءӺijֻδIJ֡ + * ֵʾӺĴǷ + * + *ע + * òСӼ + */ +Status Concat(SString T, SString S1, SString S2); + +// ӡַ +void StrPrint(SString S); + +#endif diff --git a/VisualC++/ExerciseBook/ExerciseBook.sdf b/VisualC++/ExerciseBook/ExerciseBook.sdf index 94b10c3..67505ba 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 e203e9d..9d20288 100644 --- a/VisualC++/ExerciseBook/ExerciseBook.sln +++ b/VisualC++/ExerciseBook/ExerciseBook.sln @@ -99,6 +99,40 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "03.33", "03.33\03.33.vcxpro EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "03.34", "03.34\03.34.vcxproj", "{0DCA5F0D-B6FB-44E8-9AA4-0806C870D386}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "04.10", "04.10\04.10.vcxproj", "{84E5A31E-0EC6-4747-8B3D-BAFF28320A58}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "04.11", "04.11\04.11.vcxproj", "{403165BF-098D-4F09-87F3-9B2599D663A5}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "04.12", "04.12\04.12.vcxproj", "{4E3B30A1-A3C8-47B9-B2EA-0831F3F9C852}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "04.13", "04.13\04.13.vcxproj", "{63E38EBF-7C63-4D2F-BBFD-A39D28CA3C50}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "04.14", "04.14\04.14.vcxproj", "{C6EBA21E-2309-4331-92D3-8644F769F2FC}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "04.15-04.17", "04.15-04.17\04.15-04.17.vcxproj", "{DA014C3E-5124-41C7-B53F-53AE0B96AE99}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "04.18", "04.18\04.18.vcxproj", "{19006CCD-C88C-44C5-9812-6F4276CDA60B}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "04.19", "04.19\04.19.vcxproj", "{294751C9-0DB7-400C-8603-E1C194170B6C}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "04.20", "04.20\04.20.vcxproj", "{96C98B39-7FA9-434A-BAB4-DCA6EBD5E0BA}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "04.21", "04.21\04.21.vcxproj", "{6D3C3AC9-1F42-4212-A16F-AB6A20ED95EF}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "04.22", "04.22\04.22.vcxproj", "{A8758334-BC63-451B-8CA2-AA69E86B4BAC}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "04.23", "04.23\04.23.vcxproj", "{7AF60383-012E-4F71-98BF-8A0EA94A798D}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "04.24-04.26", "04.24-04.26\04.24-04.26.vcxproj", "{2F368B7A-8594-45B4-A5EC-91D79E72F614}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "04.27", "04.27\04.27.vcxproj", "{00CECE39-4250-4727-B210-4B306167F129}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "04.28-04.29", "04.28-04.29\04.28-04.29.vcxproj", "{785893C0-9DEF-49B4-9A5F-9A6B784A089E}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "04.30", "04.30\04.30.vcxproj", "{9374E1C4-6DD6-4BB8-9DC0-5CA8E86FEA10}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "04.31", "04.31\04.31.vcxproj", "{2FB26990-0C5E-47FB-9D0F-E3A202D2A47F}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 @@ -301,6 +335,74 @@ Global {0DCA5F0D-B6FB-44E8-9AA4-0806C870D386}.Debug|Win32.Build.0 = Debug|Win32 {0DCA5F0D-B6FB-44E8-9AA4-0806C870D386}.Release|Win32.ActiveCfg = Release|Win32 {0DCA5F0D-B6FB-44E8-9AA4-0806C870D386}.Release|Win32.Build.0 = Release|Win32 + {84E5A31E-0EC6-4747-8B3D-BAFF28320A58}.Debug|Win32.ActiveCfg = Debug|Win32 + {84E5A31E-0EC6-4747-8B3D-BAFF28320A58}.Debug|Win32.Build.0 = Debug|Win32 + {84E5A31E-0EC6-4747-8B3D-BAFF28320A58}.Release|Win32.ActiveCfg = Release|Win32 + {84E5A31E-0EC6-4747-8B3D-BAFF28320A58}.Release|Win32.Build.0 = Release|Win32 + {403165BF-098D-4F09-87F3-9B2599D663A5}.Debug|Win32.ActiveCfg = Debug|Win32 + {403165BF-098D-4F09-87F3-9B2599D663A5}.Debug|Win32.Build.0 = Debug|Win32 + {403165BF-098D-4F09-87F3-9B2599D663A5}.Release|Win32.ActiveCfg = Release|Win32 + {403165BF-098D-4F09-87F3-9B2599D663A5}.Release|Win32.Build.0 = Release|Win32 + {4E3B30A1-A3C8-47B9-B2EA-0831F3F9C852}.Debug|Win32.ActiveCfg = Debug|Win32 + {4E3B30A1-A3C8-47B9-B2EA-0831F3F9C852}.Debug|Win32.Build.0 = Debug|Win32 + {4E3B30A1-A3C8-47B9-B2EA-0831F3F9C852}.Release|Win32.ActiveCfg = Release|Win32 + {4E3B30A1-A3C8-47B9-B2EA-0831F3F9C852}.Release|Win32.Build.0 = Release|Win32 + {63E38EBF-7C63-4D2F-BBFD-A39D28CA3C50}.Debug|Win32.ActiveCfg = Debug|Win32 + {63E38EBF-7C63-4D2F-BBFD-A39D28CA3C50}.Debug|Win32.Build.0 = Debug|Win32 + {63E38EBF-7C63-4D2F-BBFD-A39D28CA3C50}.Release|Win32.ActiveCfg = Release|Win32 + {63E38EBF-7C63-4D2F-BBFD-A39D28CA3C50}.Release|Win32.Build.0 = Release|Win32 + {C6EBA21E-2309-4331-92D3-8644F769F2FC}.Debug|Win32.ActiveCfg = Debug|Win32 + {C6EBA21E-2309-4331-92D3-8644F769F2FC}.Debug|Win32.Build.0 = Debug|Win32 + {C6EBA21E-2309-4331-92D3-8644F769F2FC}.Release|Win32.ActiveCfg = Release|Win32 + {C6EBA21E-2309-4331-92D3-8644F769F2FC}.Release|Win32.Build.0 = Release|Win32 + {DA014C3E-5124-41C7-B53F-53AE0B96AE99}.Debug|Win32.ActiveCfg = Debug|Win32 + {DA014C3E-5124-41C7-B53F-53AE0B96AE99}.Debug|Win32.Build.0 = Debug|Win32 + {DA014C3E-5124-41C7-B53F-53AE0B96AE99}.Release|Win32.ActiveCfg = Release|Win32 + {DA014C3E-5124-41C7-B53F-53AE0B96AE99}.Release|Win32.Build.0 = Release|Win32 + {19006CCD-C88C-44C5-9812-6F4276CDA60B}.Debug|Win32.ActiveCfg = Debug|Win32 + {19006CCD-C88C-44C5-9812-6F4276CDA60B}.Debug|Win32.Build.0 = Debug|Win32 + {19006CCD-C88C-44C5-9812-6F4276CDA60B}.Release|Win32.ActiveCfg = Release|Win32 + {19006CCD-C88C-44C5-9812-6F4276CDA60B}.Release|Win32.Build.0 = Release|Win32 + {294751C9-0DB7-400C-8603-E1C194170B6C}.Debug|Win32.ActiveCfg = Debug|Win32 + {294751C9-0DB7-400C-8603-E1C194170B6C}.Debug|Win32.Build.0 = Debug|Win32 + {294751C9-0DB7-400C-8603-E1C194170B6C}.Release|Win32.ActiveCfg = Release|Win32 + {294751C9-0DB7-400C-8603-E1C194170B6C}.Release|Win32.Build.0 = Release|Win32 + {96C98B39-7FA9-434A-BAB4-DCA6EBD5E0BA}.Debug|Win32.ActiveCfg = Debug|Win32 + {96C98B39-7FA9-434A-BAB4-DCA6EBD5E0BA}.Debug|Win32.Build.0 = Debug|Win32 + {96C98B39-7FA9-434A-BAB4-DCA6EBD5E0BA}.Release|Win32.ActiveCfg = Release|Win32 + {96C98B39-7FA9-434A-BAB4-DCA6EBD5E0BA}.Release|Win32.Build.0 = Release|Win32 + {6D3C3AC9-1F42-4212-A16F-AB6A20ED95EF}.Debug|Win32.ActiveCfg = Debug|Win32 + {6D3C3AC9-1F42-4212-A16F-AB6A20ED95EF}.Debug|Win32.Build.0 = Debug|Win32 + {6D3C3AC9-1F42-4212-A16F-AB6A20ED95EF}.Release|Win32.ActiveCfg = Release|Win32 + {6D3C3AC9-1F42-4212-A16F-AB6A20ED95EF}.Release|Win32.Build.0 = Release|Win32 + {A8758334-BC63-451B-8CA2-AA69E86B4BAC}.Debug|Win32.ActiveCfg = Debug|Win32 + {A8758334-BC63-451B-8CA2-AA69E86B4BAC}.Debug|Win32.Build.0 = Debug|Win32 + {A8758334-BC63-451B-8CA2-AA69E86B4BAC}.Release|Win32.ActiveCfg = Release|Win32 + {A8758334-BC63-451B-8CA2-AA69E86B4BAC}.Release|Win32.Build.0 = Release|Win32 + {7AF60383-012E-4F71-98BF-8A0EA94A798D}.Debug|Win32.ActiveCfg = Debug|Win32 + {7AF60383-012E-4F71-98BF-8A0EA94A798D}.Debug|Win32.Build.0 = Debug|Win32 + {7AF60383-012E-4F71-98BF-8A0EA94A798D}.Release|Win32.ActiveCfg = Release|Win32 + {7AF60383-012E-4F71-98BF-8A0EA94A798D}.Release|Win32.Build.0 = Release|Win32 + {2F368B7A-8594-45B4-A5EC-91D79E72F614}.Debug|Win32.ActiveCfg = Debug|Win32 + {2F368B7A-8594-45B4-A5EC-91D79E72F614}.Debug|Win32.Build.0 = Debug|Win32 + {2F368B7A-8594-45B4-A5EC-91D79E72F614}.Release|Win32.ActiveCfg = Release|Win32 + {2F368B7A-8594-45B4-A5EC-91D79E72F614}.Release|Win32.Build.0 = Release|Win32 + {00CECE39-4250-4727-B210-4B306167F129}.Debug|Win32.ActiveCfg = Debug|Win32 + {00CECE39-4250-4727-B210-4B306167F129}.Debug|Win32.Build.0 = Debug|Win32 + {00CECE39-4250-4727-B210-4B306167F129}.Release|Win32.ActiveCfg = Release|Win32 + {00CECE39-4250-4727-B210-4B306167F129}.Release|Win32.Build.0 = Release|Win32 + {785893C0-9DEF-49B4-9A5F-9A6B784A089E}.Debug|Win32.ActiveCfg = Debug|Win32 + {785893C0-9DEF-49B4-9A5F-9A6B784A089E}.Debug|Win32.Build.0 = Debug|Win32 + {785893C0-9DEF-49B4-9A5F-9A6B784A089E}.Release|Win32.ActiveCfg = Release|Win32 + {785893C0-9DEF-49B4-9A5F-9A6B784A089E}.Release|Win32.Build.0 = Release|Win32 + {9374E1C4-6DD6-4BB8-9DC0-5CA8E86FEA10}.Debug|Win32.ActiveCfg = Debug|Win32 + {9374E1C4-6DD6-4BB8-9DC0-5CA8E86FEA10}.Debug|Win32.Build.0 = Debug|Win32 + {9374E1C4-6DD6-4BB8-9DC0-5CA8E86FEA10}.Release|Win32.ActiveCfg = Release|Win32 + {9374E1C4-6DD6-4BB8-9DC0-5CA8E86FEA10}.Release|Win32.Build.0 = Release|Win32 + {2FB26990-0C5E-47FB-9D0F-E3A202D2A47F}.Debug|Win32.ActiveCfg = Debug|Win32 + {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 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/VisualC++/ExerciseBook/ExerciseBook.suo b/VisualC++/ExerciseBook/ExerciseBook.suo index 42293d9..f24f957 100644 Binary files a/VisualC++/ExerciseBook/ExerciseBook.suo and b/VisualC++/ExerciseBook/ExerciseBook.suo differ diff --git a/习题解析/04 串/_v_images/20181128012650395_14443.png b/习题解析/04 串/_v_images/20181128012650395_14443.png new file mode 100644 index 0000000..18e5aba Binary files /dev/null and b/习题解析/04 串/_v_images/20181128012650395_14443.png differ diff --git a/习题解析/04 串/_v_images/20181128012749064_24270.png b/习题解析/04 串/_v_images/20181128012749064_24270.png new file mode 100644 index 0000000..30c45dc Binary files /dev/null and b/习题解析/04 串/_v_images/20181128012749064_24270.png differ diff --git a/习题解析/04 串/_v_images/20181128012817985_10766.png b/习题解析/04 串/_v_images/20181128012817985_10766.png new file mode 100644 index 0000000..d8f8933 Binary files /dev/null and b/习题解析/04 串/_v_images/20181128012817985_10766.png differ diff --git a/习题解析/04 串/_v_images/20181128013044407_30919.png b/习题解析/04 串/_v_images/20181128013044407_30919.png new file mode 100644 index 0000000..9320853 Binary files /dev/null and b/习题解析/04 串/_v_images/20181128013044407_30919.png differ diff --git a/习题解析/04 串/_v_images/20181128013157410_30749.png b/习题解析/04 串/_v_images/20181128013157410_30749.png new file mode 100644 index 0000000..f80b966 Binary files /dev/null and b/习题解析/04 串/_v_images/20181128013157410_30749.png differ diff --git a/习题解析/04 串/_v_images/20181128013251526_202.png b/习题解析/04 串/_v_images/20181128013251526_202.png new file mode 100644 index 0000000..de2a418 Binary files /dev/null and b/习题解析/04 串/_v_images/20181128013251526_202.png differ diff --git a/习题解析/04 串/_v_images/20181128013312950_14120.png b/习题解析/04 串/_v_images/20181128013312950_14120.png new file mode 100644 index 0000000..21e7846 Binary files /dev/null and b/习题解析/04 串/_v_images/20181128013312950_14120.png differ diff --git a/习题解析/04 串/第04章 串.md b/习题解析/04 串/第04章 串.md new file mode 100644 index 0000000..c3a47bd --- /dev/null +++ b/习题解析/04 串/第04章 串.md @@ -0,0 +1,190 @@ +# 第4章 串 + +## 一、基础知识题 + +### 4.1 简述空串和空格串(或称空格符串)的区别。 + +> 一个空字符为:'\0' ,一个空格字符为:' ' 。空串是只包含一个空字符的字符串,其长度为0。 +> 空格串是除了在结尾包含空字符外,还包含若干空格字符的字符串,统计其长度时,要将除空字符外的字符个数都计算在内。 + +### 4.2 对于教科书4.1节中所述串的各个基本操作,讨论是否可由其他基本操作构造而得,如何构造? + +> 对于串操作中的最小操作子集,即串赋值(StrAssign)、串比较(StrCompare)、求串长(StrLength)、串联接(Conact)以及求子串(SubString)5种操作不可由其他操作来实现。 +> 其他串操作则可利用串的最小操作子集实现。 + +### 4.3 设s = 'I AM A STUDENT',t = 'GOOD',q = 'WORKER'。 +##### 求:StrLength(s),StrLength(t),SubString(s, 8, 7),SubString(t, 2, 1),Index(s, 'A'),Index(s, t),Replace(s, 'STUDENT', q),Concat(SubString(s, 6, 2), Concat(t, SubString(s, 7, 8)))。 + +> StrLength(s) = 14; +> StrLength(t) = 4; +> SubString(s, 8, 7) = 'STUDENT'; +> SubString(t, 2, 1) = 'O'; +> Index(s, 'A') = 3; +> Index(s, t) = 0; +> Replace(s, 'STUDENT', q) = 'I AM A WORKER'; +> Concat(SubString(s, 6, 2), Concat(t, SubString(s, 7, 8))) = 'A GOOD STDENT'. + +### 4.4 已知下列字符串 +###### a = 'THIS', f = 'A SAMPLE', c = 'GOOD', d = 'NE', b = ''. +###### s = Concat(a, Concat(SubString(f, 2, 7), Concat(b, SubString(a, 3, 2)))), +###### t = Replace(f, SubString(f, 3, 6), c), +###### u = Concat(SubString(c, 3, 1), d), +###### g = 'IS', +###### v = Concat(s, Concat(b, Concat(t, Concat(b, u)))), +###### 试问:s,t,v,StrLength(s),Index(v, g),Index(u, g)各是什么? + +> s = 'THIS SAMOLE IS'; +> t = 'A GOOD'; +> v = 'THIS SAMPLE IS A GOOD ONE'; +> StrLength(s) = 14; +> Index(v, g) = 3; +> Index(u, g) = 0. + +### 4.5 试问执行以下函数会产生怎样的输出结果? + +```c +void demonstrate() +{ + StrAssign(s, 'THIS IS A BOOK'); + Replace(s, SubString(s, 3, 7), 'ESE ARE'); + StrAssign(t, Concat(s, 'S')); + StrAssign(u, 'XYXYXYXYXYXY'); + StrAssign(v, SubString(u, 6, 3)); + StrAssign(w, 'W'); + printf('t=', t, 'v=', v, 'u=', Replace(u, v, w)); +}//demonstrate +``` + +> t='THESE ARE BOOKS', v='YXY', u='XWXWXW' + +### 4.6 已知:s = '(XYZ)+\*', t = '(X+Z)\*Y'。试利用联接、求子串和置换等基本运算,将s转化为t。 + +> S1 = SubString(s, 3, 1); //S1 = 'Y' +> S2 = SubString(s, 6, 1); //S2 = '+' +> Replace(s, S1, S2); //s = '(X+Z)+\*' +> Concat(S3, s, S1); //S3 = '(X+Z)+\*Y' +> Concat(t, SubString(S3, 1, 5), SubString(S3, 7, 2)); + +### 4.7 令s = 'aaab',t = 'abcabaa',u = 'abcaabbabcabaacbacba'。试分别求出它们的next函数值和nextval函数值。 + +> **s** + +![4.7.1](_v_images/20181128012650395_14443.png) + +> **t** + +![4.7.2](_v_images/20181128012749064_24270.png) + +> **u** + +![4.7.3](_v_images/20181128012817985_10766.png) + +### 4.8 已知主串s = 'ADBADABBAABADABBADADA',模式串pat = 'ADABBADADA',写出模式串的nextval函数值,并由此画出KMP算法匹配的全过程。 + +![4.8.1](_v_images/20181128013044407_30919.png) + +![4.8.2](_v_images/20181128013157410_30749.png) + +### 4.9 在以链表存储串值时,存储密度是结点大小和串长的函数。假设每个字符占一个字节,每个指针占4个字节,每个结点的大小为4的整数倍,已知串长的分布函数为f(l)且![4.9.1](_v_images/20181128013251526_202.png),求结点大小为4k,串长为l时的存储密度d(4k, l)(用公式表示)。 + +![4.9.2](_v_images/20181128013312950_14120.png) + +## 二、算法设计题 + +```c +在编写4.10至4.14题的算法时,请采用StringType数据类型: +StringType是串的一个抽象数据类型,它包含以下五种基本操作: + +void StrAssign (StringType &t, StringType s) +//将s的值赋给t。s的实际参数可以是串变量或者串常量(如:‘abcd’) + +int StrCompare (StringType s, StringType t) +//比较s和t。若s>t,返回值>0;若s=t,返回值=0;若s ###### 在编写4.15至4.20题的算法时,请采用教科书4.2.1节中所定义的定长顺序存储表示,而不允许调用串的基本操作。 + +### 4.15 编写算法,实现串的基本操作StrAssign(&T, chars)。 +### 4.16 编写算法,实现串的基本操作StrCompare(S, T)。 +### 4.17 编写算法,实现串的基本操作Replace(&S, T, V)。 + +---------- + +### 4.18 编写算法,求串s所含不同字符的总数和每种字符的个数。 + +---------- + +### 4.19 在串的定长顺序存储结构上直接实现4.11题要求的算法。 + +---------- + +### 4.20 编写算法,从串s中删除所有和串t相同的子串。 + +---------- + +### 4.21 假设以结点大小为1(且附设头结点)的链表结构表示串。试编写实现下列六种串的基本操作StrAssign,StrCopy,StrCompare,StrLength,Concat和SubString的函数。 + +---------- + +### 4.22 假设以块链结构表示串。试编写将串s插入到串t中某个字符之后的算法(若串t中不存在此字符,则将串s联接在串t的末尾)。 + +---------- + +### 4.23 假设以块链结构作串的存储结构。试编写判别给定串是否具有对称性的算法,并要求算法的时间复杂度为O(StrLength(S))。 + +---------- + +> ###### 在编写4.24至4.26题的算法时,请采用教科书4.2.2节中所定义的堆分配存储表示。 + +### 4.24 试写一算法,在串的堆存储结构上实现串基本操作Concat(&T, s1,s2)。 +### 4.25 试写一算法,实现堆存储结构的串的置换操作Replace(&S, T, V)。 +### 4.26 试写一算法,实现堆存储结构的串的插入操作 StrInsert(&S, pos, T)。 + +---------- + +### 4.27 当以教科书4.2.1节中定义的定长顺序结构表示串时,可如下所述改进定位函数的算法:先将模式串t中的第一个字符和最后一个字符与主串s中相应的字符比较,在两次比较都相等之后,再依次从t的第二个字符逐个比较。这样做可以克服算法Index(算法4.5)在求模式串'akb'(ak表示连续k个字符'a') 在主串'anb'(k≤n)中的定位函数时产生的弊病。试编写上述改进算法,并比较这两种算法在作Index('anb','akb')运算时所需进行的字符间的比较次数。 + +---------- + +### 4.28 假设以结点大小为1(带头结点)的链表结构表示串,则在利用next函数值进行串匹配时,在每个结点中需设三个域:数据域chdata、指针域succ和指针域next。其中chdata域存放一个字符;succ域存放指向同一链表中后继结点的指针;next域在主串中存放指向同一链表中前驱结点的指针;在模式串中,存放指向当该结点的字符与主串中的字符不等时,在模式串中下一个应进行比较的字符结点(即与该字符的next函数值相对应的字符结点)的指针,若该节点字符的next函数值为0,则其next域的值应指向头结点。试按上述定义的结构改写求模式串的next函数值的算法。 +### 4.29 试按4.28题定义的结构改写串匹配的改进算法(KMP算法)。 + +---------- + +### 4.30 假设以定长顺序存储结构表示串,试设计一个算法,求串s中出现的第一个最长重复子串及其(第一次出现的)位置,并分析你的算法的时间复杂度。 + +---------- + +### 4.31 假设以定长顺序存储结构表示串,试设计一个算法,求串s和串t的一个最长公共子串,并分析你的时间复杂度。若要求第一个出现的最长公共子串(即它在串s和串t的最左边的位置上出现)和所有的最长公共子串,讨论你的算法能否实现。 + +----------