#ifndef STRING_H
#define STRING_H
#include"Head.h"
#define MAXSTRLEN 255//顺序存储最大串长
#define CHUNKSIZE 4//块链存储块长
//顺序存储
typedef char SString[MAXSTRLEN + 1];//第一个位置存储串长
//堆分配存储
typedef struct {
char* ch;
int length;
}HString;
//块链存储
typedef struct Chunk {
char ch[CHUNKSIZE];
struct Chunk* next;
}Chunk;
typedef struct {
Chunk* head, * tail;//头尾指针
int curlen;//当前长度
}LString;
//块链串初始化
Status InitLString(LString* S);
//生成值为chars的串
Status SStrAssign(SString* S, char* chars);
Status HStrAssign(HString* S, char* chars);
Status LStrAssign(LString* S, char* chars);
//探空
Status Empty_SString(SString S);
Status Empty_HString(HString S);
Status Empty_LString(LString S);
//比较
Status SStrCompare(SString S, SString T);
Status HStrCompare(HString S, HString T);
//串长
int StrLength(SString S);
int HStrLength(HString S);
int LStrLength(LString S);
//销毁
Status DestoryHString(HString* S);
Status DestoryLString(LString* S);
//清空
Status SStrClear(SString* S);
Status HStrClear(HString* S);
Status LStrClear(LString* S);
//连接S1和S2
Status SStrConnect(SString* S1, SString S2);
Status HStrConnect(HString* S1, HString S2);
Status LStrConnect(LString* S1, LString S2);
//用sub返回S的第pos个字符起长度为len的子串
Status SubSString(SString* sub, SString S, int pos, int len);
Status SubHString(HString* sub, HString S, int pos, int len);
Status SubLString(LString* sub, LString S, int pos, int len);
//返回T在S中第pos个字符后第一次出现的位置,否则返回0
int Index(SString S, SString T, int pos);
//在S的第pos个字符之前插入T
Status SStrInsert(SString* S, SString T, int pos);
//从S中删除第pos个字符起长度为len的子串
Status SStrDelete(SString* S, int pos, int len);
//用V替换S中所有的T
Status Replace(SString* S, SString V, SString T);
//模式匹配,KMP算法
void Get_next(SString T, int next[]);
void Get_nextval(SString T, int nextval[]);
int Index_KMP(SString T, SString S, int pos);
//打印输出
void OutPutSString(SString S);
void OutPutHString(HString S);
void OutPutLString(LString S);
#endif // !STRING_H
#ifndef STRING_C
#define STRING_C
#include"String.h"
//块链串初始化
Status InitLString(LString* S) {
(*S).head = NULL;
(*S).tail = (*S).head;
(*S).curlen = 0;
return OK;
}
//生成值为chars的串
Status SStrAssign(SString* S, char* chars) {
int len = strlen(chars);
(*S)[0] = 0;
while ((*S)[0] < len && (*S)[0] < MAXSTRLEN) {
(*S)[(*S)[0] + 1] = chars[(*S)[0]];
(*S)[0]++;
}
return OK;
}
Status HStrAssign(HString* S, char* chars) {
(*S).length = strlen(chars);
int i = 0;
(*S).ch = MALLOC((*S).length, char);
while (i < (*S).length) {
(*S).ch[i] = chars[i];
i++;
}
return OK;
}
void InsertLString(LString* S, char c) {
Chunk* p;
if (!((*S).curlen % CHUNKSIZE)) {
if (!(*S).head) {
(*S).head = MALLOC(1, Chunk);
(*S).tail = (*S).head;
(*S).head->next = NULL;
(*S).curlen = 1;
(*S).head->ch[0] = c;
}
else {
p = MALLOC(1, Chunk);
p->ch[0] = c;
(*S).curlen++;
(*S).tail->next = p;
p->next = NULL;
(*S).tail = p;
}
}
else {
if ((*S).curlen % CHUNKSIZE)
(*S).tail->ch[(*S).curlen % CHUNKSIZE] = c;
else
(*S).tail->ch[CHUNKSIZE] = c;
(*S).curlen++;
}
}
Status LStrAssign(LString* S, char* chars) {
if (!Empty_LString(*S))
LStrClear(S);
int i = 0;
InitLString(S);
while (chars[i]) {
InsertLString(S, chars[i]);
i++;
}
return OK;
}
//探空
Status Empty_SString(SString S) {
return !S[0] ? OK : ERROR;
}
Status Empty_HString(HString S) {
return S.length;
}
Status Empty_LString(LString S) {
return S.curlen;
}
//比较
Status SStrCompare(SString S, SString T) {
int i = 1;
while (i <= S[0] && i <= T[0])
if (S[i] > T[i])
return OK;
else if (S[i] < T[i])
return INFEASIBLE;
else
i++;
if (i == S[0])
if (i == T[0])
return ERROR;
else
return INFEASIBLE;
else
return OK;
}
Status HStrCompare(HString S, HString T) {
S.ch[S.length] = 0;
T.ch[S.length] = 0;
return strcmp(S.ch, T.ch);
}
//串长
int StrLength(SString S) {
return S[0];
}
int HStrLength(HString S) {
return S.length;
}
int LStrLength(LString S) {
return S.curlen;
}
//销毁
Status DestoryHString(HString* S) {
free((*S).ch);
(*S).ch = NULL;
(*S).length = 0;
return OK;
}
Status DestoryLString(LString* S) {
if ((*S).head) {
Chunk* p, * q;
p = (*S).head;
q = p->next;
while (q) {
free(p);
p = NULL;
p = q;
q = q->next;
}
free(p);
p = NULL;
(*S).head = NULL;
(*S).tail = (*S).head;
(*S).curlen = 0;
return OK;
}
return ERROR;
}
//清空
Status SStrClear(SString* S) {
(*S)[0] = 0;
return OK;
}
Status HStrClear(HString* S) {
free((*S).ch);
(*S).length = 0;
return OK;
}
Status LStrClear(LString* S) {
(*S).curlen = 0;
(*S).head = NULL;
(*S).tail = (*S).head;
return OK;
}
//连接S1和S2
Status SStrConnect(SString* S1, SString S2) {
int newlen = (*S1)[0] + S2[0];
int len2 = 1;
if (newlen > MAXSTRLEN)
newlen = MAXSTRLEN;
while ((*S1)[0] < newlen)
(*S1)[++(*S1)[0]] = S2[len2++];
return OK;
}
Status HStrConnect(HString* S1, HString S2) {
(*S1).ch = REALLOC((*S1).ch, ((*S1).length + S2.length), char);
int i = 0;
while (i < S2.length) {
(*S1).ch[(*S1).length + i - 1] = S2.ch[i];
i++;
}
(*S1).length += S2.length;
return OK;
}
Status LStrConnect(LString* S1, LString S2) {
Chunk* p, * q, * t;
int i, j, k;
i = (*S1).curlen % CHUNKSIZE;
if (!i) {
(*S1).tail->next = S2.head;
(*S1).tail = S2.tail;
}
else {
p = (*S1).tail;
q = S2.head;
t = q;
k = 0;
j = 0;
while (k < S2.curlen) {
p->ch[i++] = q->ch[j++];
k++;
if (i == CHUNKSIZE) {
i = 0;
p->next = MALLOC(1, Chunk);
p = p->next;
p->next = NULL;
}
if (j == CHUNKSIZE && k < S2.curlen) {
q = q->next;
free(t);
t = NULL;
t = q;
}
}
}
(*S1).curlen += S2.curlen;
return OK;
}
//用sub返回S的第pos个字符起长度为len的子串
Status SubSString(SString* sub, SString S, int pos, int len) {
if (pos<1 || (pos + len)>S[0])
return ERROR;
(*sub)[0] = 0;
while ((*sub)[0] < len)
(*sub)[++(*sub)[0]] = S[pos++];
return OK;
}
Status SubHString(HString* sub, HString S, int pos, int len) {
if (pos<1 || (pos + len)>S.length)
return ERROR;
(*sub).ch = MALLOC(len, char);
(*sub).length = 0;
while ((*sub).length < len) {
(*sub).ch[(*sub).length] = S.ch[pos + (*sub).length];
(*sub).length++;
}
return OK;
}
Status SubLString(LString* sub, LString S, int pos, int len) {
if (pos + len > S.curlen || pos < 1)
return ERROR;
int i = 0, j = 1, k = 0;
Chunk* p = S.head, * q;
for (; j < pos; j++) {
i++;
if (i == CHUNKSIZE) {
i = 0;
p = p->next;
}
}
InitLString(sub);
(*sub).curlen = len;
(*sub).head = MALLOC(1, Chunk);
(*sub).tail = (*sub).head;
(*sub).tail->next = NULL;
for (j = 0; j < len; j++) {
(*sub).tail->ch[k] = p->ch[i];
i++; k++;
if (i == CHUNKSIZE) {
i = 0;
p = p->next;
}
if (k == CHUNKSIZE&&j+1<len) {
q = MALLOC(1, Chunk);
q->next = (*sub).tail->next;
(*sub).tail->next = q;
(*sub).tail = q;
k = 0;
}
}
return OK;
}
//返回T在S中第pos个字符后第一次出现的位置,否则返回0
int Index(SString S, SString T, int pos) {
int loc1, loc2;
while (T[0] + pos + 1 <= S[0]) {
loc1 = pos + 1; loc2 = 1;
while (loc2 <= T[0])
if (S[loc1] != T[loc2])
break;
else {
loc1++;
loc2++;
}
if (loc2 == T[0])
return loc1;
else
pos++;
}
return 0;
}
//在S的第pos个字符之前插入T
Status SStrInsert(SString* S, SString T, int pos) {
if (pos<1 || pos>(*S)[0])
return OK;
int i = (*S)[0], j;
while (i >= pos) {
(*S)[i + T[0]] = (*S)[i];
i--;
}
j = T[0];
while (j > 0) {
(*S)[i + T[0]] = T[j];
i--; j--;
}
(*S)[0] += T[0];
return OK;
}
//从S中删除第pos个字符起长度为len的子串
Status SStrDelete(SString* S, int pos, int len) {
if (pos<1 || (pos + len)>(*S)[0])
return ERROR;
while (pos < (*S)[0] - len) {
(*S)[pos] = (*S)[pos + len];
pos++;
}
(*S)[0] -= len;
return OK;
}
//用V替换S中所有的T
Status Replace(SString* S, SString V, SString T) {
int loc = 0, pos, i, j;
while (loc <= (*S)[0] - T[0]) {
pos = Index(*S, T, loc);
if (pos) {
SStrDelete(S, pos, T[0]);
SStrInsert(S, V, pos + 1);
loc = pos + V[0] - T[0] - 1;
}
else
break;
}
return OK;
}
//模式匹配
void Get_next(SString T, int next[]) {
int i, j;
next[1] = 0;
i = 1; j = 0;
while (i < T[0]) {
if (!j || T[i] == T[j]) {
++i;
++j;
next[i] = j;
}
else
j = next[j];
}
}
void Get_nextval(SString T, int nextval[]) {
int i, j;
nextval[1] = 0;
i = 1; j = 0;
while (i < T[0]) {
if (!j || T[i] == T[j]) {
++i;
++j;
if (T[i] != T[j])
nextval[j] = j;
else
nextval[j] = nextval[i];
}
else
j = nextval[j];
}
}
int Index_KMP(SString T, SString S, int pos) {
int i, j;
int* next = MALLOC((S[0] + 1), int);
Get_next(S, next);
i = 1;
j = 1;
while (j <= S[0] && i <= T[0]) {
if (!j || T[i] == S[j]) {
i++; j++;
}
else
j = next[j];
}
if (j > S[0])
return i - S[0];
else
return 0;
}
//打印输出
void OutPutSString(SString S) {
int i;
for (i = 1; i <= S[0]; i++)
printf("%c", S[i]);
printf("\n");
}
void OutPutHString(HString S) {
S.ch[S.length + 1] = 0;
puts(S.ch);
printf("\n");
}
void OutPutLString(LString S) {
int i = 0, j = 0;
Chunk* p;
p = S.head;
while (j < S.curlen) {
printf("%c", p->ch[i]);
i++;
j++;
if (i == CHUNKSIZE) {
i = 0;
p = p->next;
}
}
printf("\n");
}
#endif // ! STRING_C