Last active
January 11, 2017 09:44
-
-
Save limboinf/c9d8ef8bd105a515794c99411397b5fd to your computer and use it in GitHub Desktop.
数据结构之:串
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <string.h> | |
#include <stdlib.h> | |
#define OK 1 | |
#define ERROR 0 | |
#define TRUE 1 | |
#define FALSE 0 | |
#define MAXSIZE 40 /* 存储空间初始分配量 */ | |
typedef int Status; /* Status是函数的类型,其值是函数结果状态代码,如OK等 */ | |
typedef int ElemType; /* ElemType类型根据实际情况而定,这里假设为int */ | |
typedef char String[MAXSIZE+1]; // 0号存放串的长度 | |
/*********************************************************** | |
* Function Name: StrAssign | |
* Description: 生成一个其值等于chars的串T | |
* Inputs: T, String类型, chars | |
* Outputs: 返回OK | |
* Notes: 判断字符串chars是否超出最大长度, 插入时字符串向后移动 | |
* chars + i -1, 然后取值 | |
************************************************************/ | |
Status StrAssign(String T, char *chars) | |
{ | |
if(strlen(chars) > MAXSIZE) return ERROR; | |
T[0] = strlen(chars); | |
for (int i = 1; i <= T[0] ; ++i) { | |
T[i] = *(chars + i - 1); | |
} | |
return OK; | |
} | |
/*********************************************************** | |
* Function Name: StrLength | |
* Description: 返回串的长度 | |
* Inputs: S, String类型 | |
* Outputs: int | |
************************************************************/ | |
int StrLength(String S) | |
{ | |
return S[0]; | |
} | |
/*********************************************************** | |
* Function Name: StrEmpty | |
* Description: 若S为空串,则返回TRUE,否则返回FALSE | |
* Inputs: S, String类型 | |
* Outputs: int | |
************************************************************/ | |
int StrEmpty(String S) | |
{ | |
return S[0] == 0 ? TRUE : FALSE; | |
} | |
/*********************************************************** | |
* Function Name: StrCopy | |
* Description: 由串S复制得串T | |
* Inputs: S,T String类型 | |
* Outputs: int | |
************************************************************/ | |
void StrCopy(String T, String S) | |
{ | |
for (int i = 1; i <= S[0]; i++) { | |
T[i] = S[i]; | |
} | |
T[0] = S[0]; | |
} | |
/*********************************************************** | |
* Function Name: StrCompare | |
* Description: 两个串比较大小 | |
* Inputs: S,T String类型 | |
* Outputs: 若S>T,则返回值>0;若S=T,则返回值=0;若S<T,则返回值<0 | |
************************************************************/ | |
int StrCompare(String S, String T) | |
{ | |
for (int i = 1; i <= S[0] && i <= T[0] ; i++) { | |
if (S[i] != T[i]) return S[i] - T[i]; | |
} | |
return S[0] - T[0]; | |
} | |
/*********************************************************** | |
* Function Name: StrPrint | |
* Description: 打印 | |
* Inputs: S,String类型 | |
* Outputs: void | |
************************************************************/ | |
void StrPrint(String T) | |
{ | |
for (int i = 1; i <= T[0] ; i++) { | |
printf ("%c", T[i]); | |
} | |
} | |
/*********************************************************** | |
* Function Name: Concat | |
* Description: 联合 | |
* Inputs: S,String类型 | |
* Outputs: void | |
* Notes: 用T返回S1和S2联接而成的新串。若未截断,则返回TRUE,否则FALSE | |
************************************************************/ | |
Status Concat(String T, String S1, String S2) | |
{ | |
if (S1[0] + S2[0] <= MAXSIZE) // 未截断 | |
{ | |
for (int i = 1; i <= S1[0] ; i++) { | |
T[i] = S1[i]; | |
} | |
for (int j = S1[0] + 1; j <= S1[0] + S2[0]; j++) { | |
T[j] = S2[j - S1[0]]; | |
} | |
T[0] = S1[0] + S2[0]; | |
return TRUE; | |
} else { // 截断 | |
for (int i = 1; i <= S1[0] ; i++) { | |
T[i] = S1[i]; | |
} | |
for (int j = S1[0] + 1; j <= MAXSIZE; j++) { | |
T[j] = S2[j - S1[0]]; | |
} | |
T[0] = MAXSIZE; | |
return FALSE; | |
} | |
} | |
/* 初始条件:串S存在。操作结果:将S清为空串 */ | |
Status ClearString(String S) | |
{ | |
S[0]=0;/* 令串长为零 */ | |
return OK; | |
} | |
/*********************************************************** | |
* Function Name: SubString | |
* Description: 用Sub返回串S的第pos个字符起长度为len的子串。 | |
* Inputs: Sub 子串, S:主串, pos:S的第pos个字符的位置, len:长度 | |
* Outputs: OK | |
* Notes: | |
************************************************************/ | |
Status SubString(String Sub, String S, int pos, int len) | |
{ | |
if(pos < 1 || pos > MAXSIZE || len < 0 || len > S[0]-pos+1) | |
return ERROR; | |
for (int i = 1; i <=len ; i++) { | |
Sub[i] = S[pos + i - 1]; | |
} | |
Sub[0] = len; | |
return OK; | |
} | |
/*********************************************************** | |
* Function Name: StrDelete | |
* Description: 从串S中删除第pos个字符起长度为len的子串。 | |
* Inputs: S:主串, pos:S的第pos个字符的位置, len:长度 | |
* Outputs: OK | |
* Notes: 初始条件: 串S存在,1≤pos≤StrLength(S)-len+1 | |
************************************************************/ | |
Status StrDelete(String S, int pos, int len) | |
{ | |
if(pos < 1 || pos > S[0] - len + 1 || len < 0) | |
return ERROR; | |
for (int i = pos + len; i <= S[0] ; i++) { | |
S[i - len] = S[i]; | |
printf ("i=%d, i - len=%d, S[%d] = %c, S[%d]=%c,\n", i, i - len, i, S[i], i-len, S[i]); | |
} | |
S[0]-=len; | |
return OK; | |
} | |
/*********************************************************** | |
* Function Name: StrInsert | |
* Description: 在串S的第pos个字符之前插入串T。完全插入返回TRUE, 部分插入返回FALSE | |
* Inputs: S:串, pos:S的第pos个字符的位置 | |
* Outputs: OK | |
* Notes: 初始条件: 串S和T存在,1≤ pos ≤ StrLength(S)+1 | |
************************************************************/ | |
Status StrInsert(String S, int pos, String T) | |
{ | |
if (pos < 1 || pos > S[0] + 1) return ERROR; | |
if(S[0] + T[0] <= MAXSIZE) // 完全插入 | |
{ | |
for (int i = S[0]; i >=pos ; i--) { | |
S[i + T[0]] = S[i]; | |
} | |
for (int j = pos; j < T[0] + pos ; j++) { | |
S[j] = T[j - pos + 1]; | |
} | |
S[0] = S[0] + T[0]; | |
return TRUE; | |
} else { // 部分插入 | |
for (int i = MAXSIZE; i >=pos ; i--) { | |
S[i] = S[i - T[0]]; | |
} | |
for (int j = pos; j < T[0] + pos; j++) { | |
S[j] = T[j - pos + 1]; | |
} | |
S[0] = MAXSIZE; | |
return FALSE; | |
} | |
} | |
/*********************************************************** | |
* Function Name: Index | |
* Description: 朴素匹配:返回子串T在主串S中第pos个字符之后的位置。若不存在,则函数返回值为0 | |
* Inputs: S:串, pos:S的第pos个字符的位置 | |
* Outputs: int | |
* Notes: 其中,T非空,1≤pos≤StrLength(S) | |
************************************************************/ | |
int Index(String S, String T, int pos) | |
{ | |
if(pos < 1 || pos > S[0]) return ERROR; | |
int i = pos; // i用于主串S中当前位置下标值,若pos 不为1则从pos位置开始匹配 | |
int j = 1; // j用于子串T中当前位置下标值 | |
while (i <=S[0] && j <= T[0]) // 若i小于S的长度并且j小于T的长度时, 循环继续 | |
{ | |
if (S[i] == T[j]) // 两字母相同 | |
{ | |
++i; | |
++j; | |
} | |
else // 否则指针后退重新开始匹配 | |
{ | |
i = i - j + 2; // i 退回到上次匹配首位的下一位 | |
j = 1; // j 退回T首位 | |
} | |
} | |
if (j > T[0]) | |
return i - T[0]; | |
return 0; | |
} | |
/*********************************************************** | |
* Function Name: Index2 | |
* Description: 组合匹配:返回子串T在主串S中第pos个字符之后的位置。若不存在,则函数返回值为0 | |
* Inputs: S:串, pos:S的第pos个字符的位置 | |
* Outputs: int | |
* Notes: T为非空串。若主串S中第pos个字符之后存在与T相等的子串, | |
* 则返回第一个这样的子串在S中的位置,否则返回0 | |
************************************************************/ | |
int Index2(String S, String T, int pos) | |
{ | |
int n, m, i; | |
String sub; | |
if (pos > 0) | |
{ | |
n = StrLength(S); // 主串S长度 | |
m = StrLength(T); // 子串T长度 | |
i = pos; | |
while (i <= n - m + 1) | |
{ | |
// 取主串第i个位置, 长度与T相等子串给sub | |
SubString (sub, S, i, m); | |
// 如果两串不相同 | |
if (StrCompare (sub, T) != 0) | |
{ | |
++i; | |
} else | |
{ | |
return i; | |
} | |
} | |
} | |
return 0; | |
} | |
/*********************************************************** | |
* Function Name: Replace | |
* Description: 用V替换主串S中出现的所有与T相等的不重叠的子串 | |
* Inputs: | |
* Outputs: | |
* Notes: 初始条件: 串S,T和V存在,T是非空串(此函数与串的存储结构无关) | |
************************************************************/ | |
Status Replace(String S, String T, String V) | |
{ | |
int i = 1; // 从串S的第一个字符起查找串T | |
if(StrEmpty (T)) return ERROR; // T是空串 | |
do | |
{ | |
i = Index (S, T, i); // 结果i为从上一个i之后找到的子串T的位置 | |
if(i) // 串S中存在T | |
{ | |
StrDelete (S, i, StrLength (T)); // 删除该串T | |
StrInsert (S, i, V); // 在原串T的位置插入串V | |
i+=StrLength (V); // 在插入的串V后面继续查找串T | |
} | |
} while (i); | |
return OK; | |
} | |
int main() | |
{ | |
int i, j; | |
Status k; | |
char s; | |
String t, s1, s2; | |
printf("请输入串s1: "); | |
k = StrAssign(s1, "abcd"); | |
if(!k) | |
{ | |
printf("串长超过MAXSIZE(=%d)\n",MAXSIZE); | |
exit(0); | |
} | |
printf("串长为%d 串空否?%d(1:是 0:否)\n",StrLength(s1), StrEmpty(s1)); | |
StrCopy(s2, s1); | |
printf("拷贝s1生成的串为: "); | |
StrPrint(s2); | |
printf("\n请输入串s2: "); | |
k=StrAssign(s2, "efghijk"); | |
if(!k) | |
{ | |
printf("串长超过MAXSIZE(%d)\n",MAXSIZE); | |
exit(0); | |
} | |
StrPrint(s2); | |
i=StrCompare(s1,s2); | |
if(i<0) | |
s='<'; | |
else if(i==0) | |
s='='; | |
else | |
s='>'; | |
printf("\n串s1%c串s2\n",s); | |
k=Concat(t,s1,s2); | |
printf("串s1联接串s2得到的串t为: "); | |
StrPrint(t); | |
if(k==FALSE) | |
printf("串t有截断\n"); | |
ClearString(s1); | |
printf("清为空串后,串s1为: "); | |
StrPrint(s1); | |
printf("串长为%d 串空否?%d(1:是 0:否)\n",StrLength(s1),StrEmpty(s1)); | |
printf("求串t的子串,请输入子串的起始位置,子串长度: "); | |
i=2; | |
j=3; | |
printf("%d,%d \n",i,j); | |
k=SubString(s2,t,i,j); | |
if(k) | |
{ | |
printf("子串s2为: "); | |
StrPrint(s2); | |
} | |
printf("从串t的第pos个字符起,删除len个字符,请输入pos,len: "); | |
i=4; | |
j=2; | |
printf("%d,%d \n",i,j); | |
printf ("串t:"); | |
StrPrint (t); | |
printf ("\n"); | |
StrDelete(t,i,j); | |
printf("删除后的串t为: "); | |
StrPrint(t); | |
i=StrLength(s2)/2; | |
printf ("\n串s2:"); | |
StrPrint (s2); | |
printf ("\n串t:"); | |
StrPrint (t); | |
StrInsert(s2,i,t); | |
printf("\n在串s2的第%d个字符之前插入串t后,串s2为:\n",i); | |
StrPrint(s2); | |
i=Index2(s2,t,1); | |
printf("s2的第%d个字母起和t第一次匹配\n",i); | |
SubString(t,s2,1,1); | |
printf("串t为:"); | |
StrPrint(t); | |
Concat(s1,t,t); | |
printf("串s1为:"); | |
StrPrint(s1); | |
Replace(s2,t,s1); | |
printf("用串s1取代串s2中和串t相同的不重叠的串后,串s2为: "); | |
StrPrint(s2); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment