头文件:head.h
#include<string.h>
#include<ctype.h>
#include<malloc.h> /* malloc()等 */
#include<limits.h> /* INT_MAX等 */
#include<stdio.h> /* EOF(=^Z或F6),NULL */
#include<stdlib.h> /* atoi() */
#include<io.h> /* eof() */
#include<math.h> /* floor(),ceil(),abs() */
#include<process.h> /* exit() */
/* 函数结果状态代码 */
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
/* #define OVERFLOW -2 因为在math.h中已定义OVERFLOW的值为3,故去掉此行 */
typedef int Status; /* Status是函数的类型,其值是函数结果状态代码,如OK等 */
typedef int Boolean; /* Boolean是布尔类型,其值是TRUE或FALSE */
#define DestoryString ClearString //作用相同
typedef struct {
char *ch;
int length;
}HString;
Status InitString(HString *S);
Status StrAssign(HString *T, char *chars);
Status StrCopy(HString *T, HString S);
Boolean StrEmpty(HString S);
int StrCompare(HString S, HString T);
int StrLength(HString s);
Status ClearString(HString *S);
Status Concat(HString *T, HString S1, HString S2);
Status SubString(HString *Sub, HString S, int pos, int len);
int Index(HString S, HString T, int pos);
Status Replace(HString *S, HString T, HString V);
Status StrInsert(HString *S, int pos, HString T);
Status StrDelete(HString *S, int pos, int len);
void StrPrint(HString T);
算法实现:
#include"head.h"
Status InitString(HString *S)
{
(*S).ch = NULL;
(*S).length = 0;
}
Status StrAssign(HString *T, char *chars)
{
//生成一个其值等于串常量chars的串T
int len;
if ((*T).ch)
free((*T).ch);
len = strlen(chars);
if (!len) //长度为0的情况下处理方法
{
(*T).ch = NULL;
(*T).length = 0;
}
else
{
(*T).ch = (char *)malloc(len * sizeof(char));
if (!((*T).ch))
{
printf("内存分配失败!");
system("pause");
exit(-1);
}
for (int i = 0; i < len; i++)
((*T).ch)[i] = chars[i];
(*T).length = len;
}
return OK;
}
Status StrCopy(HString *T, HString S)
{
if ((*T).ch)
free((*T).ch);
(*T).ch = (char *)malloc(S.length * sizeof(char));
if (!((*T).ch))
{
printf("赋值时内存空间分配失败!");
system("pause");
exit(-1);
}
(*T).length = S.length;
for (int i = 0; i < S.length; i++)
((*T).ch)[i] = S.ch[i];
return OK;
}
Boolean StrEmpty(HString S)
{
if (S.length != 0)
return ERROR;
else
return TRUE;
}
int StrCompare(HString S, HString T)
{
for (int 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;
}
int StrLength(HString s)
{
return s.length;
}
Status ClearString(HString *S)
{
if ((*S).ch)
free((*S).ch);
(*S).length = 0;
(*S).ch = NULL;
return OK;
}
Status Concat(HString *T, HString S1, HString S2)
{
//用T返回S1和S2联接而成的新串
if ((*T).ch)
free((*T).ch);
(*T).ch = (char *)malloc((S1.length + S2.length)*sizeof(char));
if (!((*T).ch))
{
printf("联接过程中内存分配失败!");
system("pause");
exit(OVERFLOW);
}
(*T).length = S1.length + S2.length;
for (int i = 0; i < S1.length; i++)
(*T).ch[i] = S1.ch[i];
for (int i = 0; i < S2.length; i++)
(*T).ch[i + S1.length] = S2.ch[i];
return OK;
}
Status SubString(HString *Sub, HString S, int pos, int len)
{
//0<=len<=S.length-pos+1;
if (pos<0 || pos>S.length || len<0 || len>S.length - pos + 1)
return ERROR;
if ((*Sub).ch)
free((*Sub).ch);
if (!len) //截取的字节长度可以是0
{
(*Sub).ch = NULL;
(*Sub).length = 0;
}
else
{
(*Sub).ch = (char *)malloc(len*sizeof(char));
if (!(*Sub).ch)
{
printf("求子串过程中内存分配失败!");
system("pause");
exit(OVERFLOW);
}
(*Sub).length = len;
for (int i = 0; i < len; i++)
(*Sub).ch[i] = S.ch[i + pos - 1]; //注意和定长顺序存储表示的差别,这里的数据是从0号位置开始的
}
return OK;
}
int Index(HString S, HString T, int pos)
{
HString temp;
InitString(&temp);
if (pos > 0)
{
for (int i = pos; i <= S.length - T.length + 1; i++)
{
SubString(&temp, S, i, T.length);
if (StrCompare(temp, T) == 0)
return i;
}
}
return 0;
}
Status Replace(HString *S, HString T, HString V)
{
int i = 1;
if (StrEmpty(T))
return ERROR;
do
{
i = Index(*S, T, i);
if (i)
{
StrDelete(S, i, T.length);
StrInsert(S, i, V);
i += V.length;
}
} while (i);
return OK;
}
Status StrInsert(HString *S, int pos, HString T)
{
if (pos<0 || pos>(*S).length + 1)
return ERROR;
if (StrEmpty(T))
return ERROR;
(*S).ch = (char *)realloc((*S).ch, ((*S).length + T.length) * sizeof(char));
for (int i = (*S).length - 1; i > pos-1; i--)
(*S).ch[i + T.length] = (*S).ch[i];
for (int i = 0; i < T.length; i++)
(*S).ch[pos - 1 + i] = T.ch[i];
(*S).length = (*S).length + T.length;
return OK;
}
Status StrDelete(HString *S, int pos, int len)
{
if (pos<0 || pos>(*S).length - len + 1)
return ERROR;
for (int i = pos - 1; i < (*S).length - len; i++)
(*S).ch[i] = (*S).ch[i + len];
(*S).length = (*S).length - len;
(*S).ch = (char *)realloc((*S).ch, (*S).length*sizeof(char));
return OK;
}
void StrPrint(HString T)
{
for (int i = 0; i < T.length; i++)
printf("%c", T.ch[i]);
printf("\n");
}
测试文件
#include"head.h"
void main()
{
int i;
char c, *p = "God bye", *q = "Bod luck!";
HString t, s, r;
InitString(&t); /* HString类型必需初始化 */
InitString(&s);
InitString(&r);
StrAssign(&t, p);
printf("串t为: ");
StrPrint(t);
printf("串长为%d 串空否?%d(1:空 0:否)\n", StrLength(t), StrEmpty(t));
StrAssign(&s, q);
printf("串s为: ");
StrPrint(s);
i = StrCompare(s, t);
if (i<0)
c = '<';
else if (i == 0)
c = '=';
else
c = '>';
printf("串s%c串t\n", c);
Concat(&r, t, s);
printf("串t联接串s产生的串r为: ");
StrPrint(r);
StrAssign(&s, "oo");
printf("串s为: ");
StrPrint(s);
StrAssign(&t, "o");
printf("串t为: ");
StrPrint(t);
Replace(&r, t, s);
printf("把串r中和串t相同的子串用串s代替后,串r为:\n");
StrPrint(r);
ClearString(&s);
printf("串s清空后,串长为%d 空否?%d(1:空 0:否)\n", StrLength(s), StrEmpty(s));
SubString(&s, r, 6, 4);
printf("串s为从串r的第6个字符起的4个字符,长度为%d 串s为: ", s.length);
StrPrint(s);
StrCopy(&t, r);
printf("复制串t为串r,串t为: ");
StrPrint(t);
StrInsert(&t, 6, s);
printf("在串t的第6个字符前插入串s后,串t为: ");
StrPrint(t);
StrDelete(&t, 1, 5);
printf("从串t的第1个字符起删除5个字符后,串t为: ");
StrPrint(t);
printf("%d是从串t的第1个字符起,和串s相同的第1个子串的位置\n", Index(t, s, 1));
printf("%d是从串t的第2个字符起,和串s相同的第1个子串的位置\n", Index(t, s, 2));
system("pause");
}
Running Result:
串t为: God bye
串长为7 串空否?0(1:空 0:否)
串s为: Bod luck!
串s<串t
串t联接串s产生的串r为: God byeBod luck!
串s为: oo
串t为: o
把串r中和串t相同的子串用串s代替后,串r为:
Goob byeBool luck!
串s清空后,串长为0 空否?1(1:空 0:否)
串s为从串r的第6个字符起的4个字符,长度为4 串s为: byeB
复制串t为串r,串t为: Goob byeBool luck!
在串t的第6个字符前插入串s后,串t为: Goob byeBoyeBool luck!
从串t的第1个字符起删除5个字符后,串t为: byeBoyeBool luck!
1是从串t的第1个字符起,和串s相同的第1个子串的位置
0是从串t的第2个字符起,和串s相同的第1个子串的位置
请按任意键继续. . .