基本概念

  • 串:字符串是由零个或多个字符组成的有限序列(特殊的线性表)

  • 字串:串中任意个连续字符组成的子序列(空串也是字串)

  • 主串:包含字串的串

  • 字符在主串中的位置:字符在串中的序号(假设位序从1开始)

  • 字串在主串中的位置:字串的第一个字符在主串中的位置

  • 空串:"" 空格串:" "

    S="asdadads";
    //串名:S
    //串的长度:8
    //字串 T="as"
    //S是T的主串
    //'a'在S中出现的位置是1
    //T在S中的位置是1
    

逻辑结构

与线性表相似,但数据对象为限定字符集(中文字符、英文字符、数字字符、标点字符等)

基本操作

以字串为操作对象

赋值操作

StrAssign(&T,chars):把串T赋值为chars

复制操作

StrCopy(&T,S):由串S复制得到串T

判空操作

StrEmpty(S):若字符串为空串,返回TRUE,否则返回FALSE

求串长

StrLength(S):返回串S的元素个数

清空操作

ClearString(S):把S清为空串

销毁串

DestroyString(S):将串S销毁(回收存储空间)

串连接

Concat(&T,S1,S2):用T返回S1和S2连接而成的新串

求子串

SubString($Sub,S,pos,len):用sub返回串S的第pos个字符起长度为len的字串

定位操作

Index(S,T):若主串S中存在与串T值相同的字串,则返回它在主串S中第一次出现的位置,否则返回函数值为0

比较操作

strCompare(S,T):若S>T,返回值>0; 若S=T,返回值=0,若S<T返回值<0

  • 从第一个字符开始往后依次对比,先出现更大字符的串就更大。

  • 长串的前缀与短串相同时,长串更大

  • 只有两个串完全相同时,才相等

存储结构

顺序存储

  • 静态数组实现,定长的顺序存储

    #define MAXLEN 255	//预定义最大串255
    typedef struct {
    	char ch[MAXLEN];//每个分量存储一个字符
    	int length;		//串的实际长度
    }SString;
    
  • 动态数组实现,堆分配存储(需要手动free)

    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
    #define MAXLEN 255	//预定义最大串255
    
    typedef struct {
    	char* ch;		//按串长分配存储区,ch指向串的基地址
    	int length;		//串的长度
    }HString;
    int main()
    {
    	HString S;
    	S.ch = (char*)malloc(MAXLEN * sizeof(char));
    	S.length = 0;
    }
    
    

链式存储

typedef struct StringNode {
	char ch;
	struct StringNode* next;
}StringNode,*String;
typedef struct StringNode {
	char ch[4];					//增加存储密度
	struct StringNode* next;
}StringNode,*String;

基本操作的实现

//求子串
//Sub储存返回的字串,S是原来的串,pos是要取的坐标,len是要取的长度
bool SubString(SString& Sub, SString S, int pos, int len)
{
	//判断所取的位置是否正确
	if (pos+len > S.length-1)
	{
		return false;
	}
	int i=0;
	for ( i = pos; i < pos + len; i++)
	{
		Sub.ch[i - pos] = S.ch[i];
	}
	Sub.ch[i-pos] = '\0';
	Sub.length = len;
	return true;
}
//串的比较
//返回值大于0就相等,返回值大于0就S>T,小于0就S<T a=97,c=99
int strCompare(string S, string T)
{
	int i = 0;
	for (i= 0; i < S.length()&&i <T.length(); i++)
	{
		if (S[i] != T[i])
		{
			return S[i] - T[i];
		}
	}
	return S.length() - T.length();
}
//求串在字串中的位置,若S和T中存在相同的字串,返回他在主串中第一次出现的位置
int matchIndex(string S,string T)
{
	int i = 0, j = 0;
	//从S第一个元素依次往后取,共需要取长度之差-1次
	for (i = 0; i < S.length()-T.length()+1; i++)
	{
		//取S中的第i个位置往后取T的长度的字串,和T比较,若相等则返回
		if (strCompare(S.substr(i, T.length()), T) == 0)
		{
			return i;
		}
	}
	return -1;
}

BF算法

在主串中找到模式串相同的字串,并返回其所在的位置

//BF算法
int BFMatch(string S, string T)
{
	//i来记录主串的当前坐标,j来记录模式串的当前坐标,k来表示当前主串所匹配的位置
	int i = 0, j = 0, k = 0;
	//退出while有两个条件一个是遍历完主串没找到,另一个是模式串指导了最后,也就是模式串匹配上了
	while (i < S.length() && j < T.length())
	{
		//如果相等就继续往后看是否匹配
		if (S[i] == T[j])
		{
			++i;
			++j;
		}
		//如果不相等,模式串指针指向开头,主串的k+1,并令主串的指针指向k(当前匹配的串)
		else
		{
			j = 0;
			k++;
			i = k;
		}
	}
	//如果模式串的指针成功指到了最后,说明成功匹配了
	if (j >= T.length())
	{
		return 1;
	}
	return 0;
}

KMP算法

  • 字符串前后缀

    串的前缀:包含第一个字符,且不包含最后一个字符的字串

    串的后缀:包含最后一个字符,且不包含第一个字符的字串

    abbabss前缀:a,ab,abb,abba,abbab,abbabs

    abbabss后缀:s,ss,bss,abss,babss,bbabss

  • next数组

    当第j个字符匹配失败,由前1~j-1个字符组成的串记为S

    next[j]=S的最长相等前后缀长度+1

    next[1]=0

    //求next数组
    int getNext(string s,int next[])
    {
    	int i=1, j=0;
    	next[1] = 0;
    	while (i<s.length())
    	{
    		if (j == 0 || s[i] == s[j])
    		{
    			++i;
    			++j;
    			next[i] = j;
    		}
    		else {
    			j = next[j];
    		}
    	}
    	return 0;
    
    }
    
    //KMP算法
    int KMPMatch(string S,string T,int next[])
    {
    	int i = 1;
    	int j = 1;
    	while (i<=S.length()&&j<=T.length())
    	{
    		if (S[i] == T[j]||j==0)
    		{
    			i++;
    			j++;
    		}
    		else {
    			j = next[j];
    		}
    
    	}
    	if (j > T.length())
    	{
    		return 1;
    	}
    	return 0;
    }
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值