Skip to content

Instantly share code, notes, and snippets.

@limboinf
Last active January 11, 2017 09:44
Show Gist options
  • Save limboinf/c9d8ef8bd105a515794c99411397b5fd to your computer and use it in GitHub Desktop.
Save limboinf/c9d8ef8bd105a515794c99411397b5fd to your computer and use it in GitHub Desktop.
数据结构之:串
#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