串是由0个或者多个字符组成的有限序列
在各种语言中都定义了自己的字符串,比如C++,java
现在给出一个C中顺序串的实现(PS:串不适合用链表的形式,因为每个节点的数据只存储一个字符,如果还要额外加指针,空间上会产生很大的浪费)
#include <stdio.h>
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
#define MAXSIZE 40
typedef int Status;
typedef int ElemType;
//自定义一个MyString串,数组中首字母
typedef struct {
char data[MAXSIZE];
int length;
}MyString;
void PrintString(MyString S) {
printf("MyString = ");
for (int i = 0; i < S.length; i++) {
printf("%c", S.data[i]);
}
printf("\n");
}
//生成一个其值等于chars的串
Status StrAssign(MyString* S, const char* chars) {
int len = strlen(chars);
if (len == 0) {
S->data[0] = '\0';
S->length = 0;
}
else {
for (int i = 0; i < len; i++) {
S->data[i] = chars[i];
}
S->length = len;
}
return OK;
}
//复制串
Status StrCpoy(MyString* S, MyString T) {
for (int i = 0; i < T.length; i++) {
S->data[i] = T.data[i];
}
S->length = T.length;
return OK;
}
//判断是否为空串
Status StrEmpty(MyString S) {
if (S.length == 0) {
return TRUE;
}
else {
return FALSE;
}
}
//获取长度
int StrLength(MyString S) {
return S.length;
}
//比较两个串的大小
int StrCompare(MyString S, MyString T) {
int lenS = S.length;
int lenT = T.length;
//对比相同长度部分
for (int i = 0; i < lenS && i < lenT; i++) {
if (S.data[i] != T.data[i]) {
return S.data[i] - T.data[i];
}
}
//相同长度部分都相同话,长度较长的字符串比较大
return lenS - lenT;
}
//清空字符串
Status ClearnString(MyString* S) {
S->length = 0;
return OK;
}
//字符串的拼接
Status Strcat(MyString* S, MyString S1, MyString S2) {
//拷贝S1
for (int i = 0; i < S1.length; i++) {
S->data[i] = S1.data[i];
}
if (S1.length + S2.length > MAXSIZE) {
//拷贝S2的部分内容
for (int j = S1.length; j < MAXSIZE; j++) {
S->data[j] = S2.data[j - S1.length];
}
S->length = MAXSIZE;
}
else {
//拷贝S2的全部内容
for (int j = 0; j < S2.length; j++) {
S->data[j + S1.length] = S2.data[j];
}
S->length = S1.length + S2.length;
}
return OK;
}
Status SubString(MyString* Sub, MyString S, int pos, int len) {
if (pos < 1 || pos > S.length) {
printf("SubString pos out of range\n");
return ERROR;
}
if (len < 0 || len > S.length - pos + 1) {
printf("SubString len is illegal or to long\n");
return ERROR;
}
for (int i = 0; i < len; i++) {
Sub->data[i] = S.data[pos - 1 + i];
}
Sub->length = len;
return OK;
}
//返回子串在主串中的位置
int Index(MyString S, MyString Sub, int pos) {
if (Sub.length > S.length) {
printf("Sub is longer than S\n");
return 0;
}
if (pos < 1 || S.length == 0 || Sub.length == 0) {
printf("Index pos out of range\n");
return 0;
}
int posS = pos - 1;
int posSub = 0;
while (posS < S.length && posSub < Sub.length) {
if (S.data[posS] == Sub.data[posSub]) {
//相等则继续
posS++;
posSub++;
}
else {
//不匹配,则主串的起始位置+1,子串位置归零
posS = posS - posSub + 1;
posSub = 0;
}
}
if (posSub == Sub.length) {
return posS - posSub + 1;
}
else {
return 0;
}
}
Status StrInsert(MyString* S, int pos, MyString T) {
if (pos < 1 || pos > S->length + 1) {
printf("StrInsert pos illegal\n");
return ERROR;
}
if (S->length + T.length <= MAXSIZE) {
//完全插入
for (int i = S->length; i >= pos; i--) {
//主要串元素后移
S->data[i + T.length - 1] = S->data[i - 1];
}
for (int j = pos; j < pos + T.length; j++) {
//插入元素
S->data[j - 1] = T.data[j - pos];
}
S->length += T.length;
} else {
//部分插入
for (int i = MAXSIZE; i >= pos; i--) {
//主要串元素后移
S->data[i - 1] = S->data[i - 1 - T.length];
}
for (int j = pos; j < pos + T.length; j++) {
//插入元素
//注意,这个有一个隐藏bug,就是pos+t-1有可能超出数组的范围,示例代码不考虑这种情况,仅提示
S->data[j - 1] = T.data[j - pos];
}
S->length = MAXSIZE;
}
return OK;
}
Status StrDelete(MyString *S, int pos, int len) {
if (pos < 1 || pos >(S->length - len + 1) || len < 0) {
printf("StrDelete illegal argument\n");
return FALSE;
}
for (int i = pos + len; i <= S->length; i++) {
S->data[i - len - 1] = S->data[i - 1];
}
S->length -= len;
return OK;
}
//初始条件: 串S,target和src存在,target是非空串
//操作结果: 用src替换主串S中出现的所有与target相等的不重叠的子串
Status Replace(MyString *S, MyString target, MyString src) {
if (StrEmpty(target)) {
printf("Replace target cannot be empty string");
return ERROR;
}
int curPos = 1;
do {
curPos = Index(*S,target,curPos);
if (curPos) {
//说明找到相符的元素
StrDelete(S,curPos,target.length);
StrInsert(S,curPos,src);
curPos += src.length;
}
} while (curPos);
return OK;
}
int main(void) {
MyString S;
//printf("String is empty = %d\n", StrEmpty(S));
StrAssign(&S,"123456789");
printf("String is empty = %d\n", StrEmpty(S));
printf("String length = %d\n",StrLength(S));
PrintString(S);
MyString newString;
//复制串
//StrCpoy(&newString,S);
//StrAssign(&newString, "1234567");
//比较串
//printf("String compare:%d", StrCompare(newString,S));
//PrintString(newString);
//拼接
//MyString hpk;
//StrAssign(&hpk,"hpk");
//MyString hyj;
//StrAssign(&hyj, "hyj");
//Strcat(&S,hpk,hyj);
//取得子串
//MyString substring;
//SubString(&substring,S,2,4);
//PrintString(substring);
//获取子串位置
//MyString substring;
//StrAssign(&substring,"456");
//int pos = Index(S,substring,2);
//printf("substring pos = %d\n",pos);
//插入
//MyString substring;
//StrAssign(&substring,"hpk");
//StrInsert(&S,10,substring);
//PrintString(S);
//删除
//StrDelete(&S,1,3);
//PrintString(S);
//替换
MyString src;
StrAssign(&src,"hpk");
MyString dest;
StrAssign(&dest, "234");
Replace(&S,dest,src);
PrintString(S);
return 0;
}