数据结构与算法(三)串
- 串的顺序实现
/*插入有些问题,还请大佬指正*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX 20
typedef struct
{
char ch[MAX];
int last;
}SeqString;
void init_String(SeqString* pS)
{
int i = 0;
pS->last = 0;
printf("请输入字符串; ");
gets_s(pS->ch);
while (pS->ch[i] != '\0')
{
pS->last ++;
i++;
}
}
bool StrInsert(SeqString* pS,int pos,SeqString T)
{
int i;
if (pos<0 || pos>pS->last + 1)
return false;
if (pS->last + T.last + 1 <= MAX)
{
for (i = pS->last + T.last - 1; i >= pos + T.last; --i)
{
pS->ch[i] = pS->ch[i - T.last];
}
for (i = 0; i < T.last; i++)
{
pS->ch[i + pos] = T.ch[i];
}
pS->last = pS->last + T.last;
}
else
printf("超范围啦!!!\n");
if (pos + T.last < MAX)
{
for (i = MAX-1; i > pos + T.last; --i)
{
pS->ch[i] = pS->ch[i - T.last];
}
for (i = 0; i <= T.last; i++)
{
pS->ch[i + pos] = T.ch[i];
}
pS->last = MAX;
}
else
{
for (i = 0; i < MAX - pos; i++)
{
pS->ch[i + pos] = T.ch[i];
}
pS->last = MAX;
}
return true;
}
bool StrDelete(SeqString* pS, int pos, int len)
{
int i;
if (pos<0 || pos>pS->last - 1)
return false;
else
for (i = pos + len; i <= pS->last; i++)
pS->ch[i - len] = pS->ch[i];
pS->last = pS->last - len;
return true;
}
bool StrCopy(SeqString* pS, SeqString* pT)//将T中的值复制到S中
{
int i;
for (i = 0; i <= pT->last; i++)
pS->ch[i] = pT->ch[i];
pS->ch[i + 1] = '\0';
pS->last = pT->last;
return true;
}
void StrCompare(SeqString* pS, SeqString* pT)
{
int i;
for (i = 0; i <= pS->last && i <= pT->last; i++)
{
if (pS->ch[i] != pT->ch[i])
break;
}
if (pS->ch[i] > pT->ch[i])
printf("%s大于%s\n",pS->ch,pT->ch);
else
printf("%s小于%s\n", pS->ch, pT->ch);
}
bool StrCat(SeqString* pS, SeqString* pT)
{
int i;
if (pS->last + pT->last + 1 > MAX)
{
for (i = pS->last; i < pS->last + pT->last + 1; ++i)
{
pS->ch[i] = pT->ch[i - pS->last];
}
pS->last = pS->last + pT->last;
return true;
}
else
if (pS->last < MAX)
{
for (i = pS->last; i < MAX; i++)
pS->ch[i] = pT->ch[i - pS->last];
pS->last = MAX;
return false;
}
else
return false;
}
bool SubString(SeqString* sub, SeqString* pS, int pos, int len)//将pS所指的串从pos处开始len长度的字符串复制到sub中
{
int i;
if (pos<0 || pos>pS->last || len<1 || len>pS->last - pos)
{
sub->last = 0;
return false;
}
else
{
for (i = 0; i < len; i++)
{
sub->ch[i] = pS->ch[i + pos];
}
sub->last = len;
return true;
}
}
bool StrIndex(SeqString* pS, SeqString* pT, int* pPos)
{
int i=0, j=0;
if (pT->last == 0)
return false;
while (i < pS->last && j < pT->last)
{
if (pS->ch[i] == pT->ch[j])
{
i++;
j++;
}
else
{
i = i - j + 1;
j = 0;
}
}
if (j >= pT->last)
{
*pPos = i - j + 1;
return true;
}
else
return false;
}
void show_string(SeqString* Sq)
{
printf("%s\n",Sq->ch);
}
int main()
{
SeqString s;
SeqString t;
int pos;
init_String(&s);
init_String(&t);
//StrCopy(&s,&t);
printf("第一个字符串为:");
show_string(&s);
printf("第二个字符串为:");
show_string(&t);
//StrInsert(&s, 2, t);//有问题
//StrCompare(&s,&t);
//StrCat(&s, &t);
//SubString(&t, &s, 2, 2);
//if (StrIndex(&s, &t, &pos))
// printf("%d\n",pos);
show_string(&s);
//show_string(&t);
return 0;
}
- 串的堆存储结构
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <malloc.h>
typedef struct
{
char* str;
int length;
}HeapString;
void InitString(HeapString* S)
{
S->length = 0;
S->str = NULL;
}
int StrEmpty(HeapString S)
//判断串是否为空,串为空返回1,否则返回0
{
if (S.length == 0) //判断串的长度是否等于
return 1; //当串为空时,返回1;否则返回0
else
return 0;
}
int StrLength(HeapString S)
//求串的长度操作
{
return S.length;
}
void StrAssign(HeapString* S, char cstr[])
//串的赋值操作
{
int i = 0, len;
if (S->str)
free(S->str);
for (i = 0; cstr[i] != '\0'; i++); //求cstr字符串的长度
len = i;
if (!i)
{
S->str = NULL;
S->length = 0;
}
else
{
S->str = (char*)malloc((len + 1) * sizeof(char));
if (!S->str)
exit(-1);
for (i = 0; i < len; i++)
S->str[i] = cstr[i];
S->length = len;
}
}
int StrInsert(HeapString* S, int pos, HeapString T)
//串的插入操作。在S中第pos个位置插入T分为三种情况
{
int i;
if (pos<0 || pos - 1>S->length) //插入位置不正确,返回0
{
printf("插入位置不正确");
return 0;
}
S->str = (char*)realloc(S->str, (S->length + T.length) * sizeof(char));
if (!S->str)
{
printf("内存分配失败");
exit(-1);
}
for (i = S->length - 1; i >= pos - 1; i--)
S->str[i + T.length] = S->str[i];
for (i = 0; i < T.length; i++)
S->str[pos + i - 1] = T.str[i];
S->length = S->length + T.length;
return 1;
}
int StrDelete(HeapString* S, int pos, int len)
//在串S中删除pos开始的len个字符
{
int i;
char* p;
if (pos < 0 || len<0 || pos + len - 1>S->length)
{
printf("删除位置不正确,参数len不合法");
return 0;
}
p = (char*)malloc(S->length - len); //p指向动态分配的内存单元
if (!p)
exit(-1);
for (i = 0; i < pos - 1; i++) //将串第pos位置之前的字符复制到p中
p[i] = S->str[i];
for (i = pos - 1; i < S->length - len; i++) //将串第pos+len位置以后的字符复制到p中
p[i] = S->str[i + len];
S->length = S->length - len; //修改串的长度
free(S->str); //释放原来的串S的内存空间
S->str = p; //将串的str指向p字符串
return 1;
}
int StrCompare(HeapString S, HeapString T)
{
int i;
for (i = 0; i < S.length && i < T.length; i++)
if (S.str[i] != T.str[i])
return (S.str[i] - T.str[i]);
return (S.length - T.length);
}
int StrCat(HeapString* T, HeapString S)
{
int i;
T->str = (char*)realloc(T->str, (T->length + S.length) * sizeof(char));
if (!T->str)
{
printf("分配空间失败");
exit(-1);
}
else
{
for (i = T->length; i < T->length + S.length; i++)
T->str[i] = S.str[i - T->length];
T->length = T->length + S.length;
}
return 1;
}
void StrClear(HeapString* S)
{
S->str = 0;
S->length = 0;
}
void StrDestroy(HeapString* S)
{
if (S->str)
free(S->str);
}
void StrPrint(HeapString S)
{
int i;
for (i = 0; i < S.length; i++)
{
printf("%c", S.str[i]);
}
printf("\n");
}
int main()
{
HeapString s;
InitString(&s);
char* c = (char*)"ngcab";
//strcpy(c, "Hello");
StrAssign(&s, c);
StrPrint(s);
return 0;
}
- 暴力匹配算法
bool StrIndex(SeqString* pS, SeqString* pT, int* pPos)
{
int i=0, j=0;
if (pT->last == 0)
return false;
while (i < pS->last && j < pT->last)
{
if (pS->ch[i] == pT->ch[j])
{
i++;
j++;
}
else
{
i = i - j + 1;
j = 0;
}
}
if (j >= pT->last)
{
*pPos = i - j + 1;
return true;
}
else
return false;
}
- KMP模式匹配算法
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX 10
int next[20];
typedef struct
{
char ch[MAX];
int length;
}SeqString;
void initString(SeqString* Sq)
{
int i=0;
Sq->length = 0;
printf("输入字符串: ");
gets_s(Sq->ch);
while (Sq->ch[i] != '\0')
{
i++;
}
Sq->length = i;
}
void getNext(SeqString* pT)
{
int j = 0;
int k = -1;
next[j] = -1;
while (j < pT->length - 1)
{
if (k == -1 || pT->ch[k] == pT->ch[j])
{
j++;
k++;
next[j] = k;
}
else
{
k = next[k];
}
}
}
bool KMP(SeqString* Sq, SeqString* Tq, int* pos)//S中找到T开始的位置
{
getNext(Tq);
int i=0, j=0;
while (i < Sq->length && j < Tq->length)
{
if (j==-1||Sq->ch[i] == Tq->ch[j])
{
i++;
j++;
}
else
{
j = next[j];
}
}
if (j == Tq->length)
*pos = i - j+1 ;
return true;
}
int main()
{
int pos;
SeqString s;
SeqString t;
initString(&s);
initString(&t);
printf("第一个字符串是%s\n", (&s)->ch);
printf("第二个字符串是%s\n", (&t)->ch);
KMP(&s,&t,&pos);
printf("位置是%d\n",pos);
return 0;
}
如有问题多多指正