字符串的学习(1)

C语言里并没有字符串这种数据类型,而是利用字符数组加以特殊处理(末尾加'\0')来表示一个字符串,事实上数据结构里的串就是一个存储了字符的链表,并且封装实现了各种字符串的常用操作。

主要阐述 BF算法和KMP算法

串的常用操作
strcpy (s1, s2)

  复制字符串,将s2的内容复制到s1,函数原型strcpy (char*, const char*),可以看出第二参数可以是常量也可以是变量,但第一参数必须是变量。这里要注意的是s2的内容长度(包括'\0')不能超出s1的总长度。该函数通常可以用来为字符数组赋值,示例(第3行可以认为是在给cpy赋值):

char str[233];  
char cpy[233];  
strcpy(cpy, "i am string");  
strcpy(str, cpy);  
strncpy(p, p1, n) 

  复制指定长度字符串,与上一个函数类似,只不过多了第三个参数,指的是要拷贝的字符串的长度,此函数会将p1首地址开始的n个字节的内容拷贝到p中,需要注意的是,拷贝后的内容并不包含字符串结束标志'\0',所以需要手动添加才可使p变成需要的字符串,示例:


char str[233];  
char cpy[233] = "i am string";  
strncpy(str, cpy, 8);  
str[8] = '\0';  

//避免数组越界
strncpy(s1,s2,sizeof(s1)-1);
s1[sizeof(s1)-1]='\0';
strcat(p, p1) 

  字符串连接 ,该函数会将p1的内容添加到p的末尾,比如p="Hello",p1="World",则执行该函数,p的内容变为"HelloWorld"。原型_CRTIMP char* __cdecl __MINGW_NOTHROW strcat (char*, const char*);同样第二参数可为常量,这里需要注意的是,p和p1必须都是合法字符串(即包含结束标志'\0')且需要保证连接后的总长度不会超过p的总大小。示例:

char str[233] = "Hello";  
char cat[233] = "World";  
strcat(str, cat);  
strncat(p, p1, n) 

  附加指定长度字符串,类似上面strcpy和strncpy的区别,这里也是一样的,截取p1前n个字节的内容添加到p的末尾,注意,此函数会覆盖p末尾的'\0',并在添加p1完成后自动在最后添加'\0',所以无需像上面那样手动加'\0'。示例:

char str[233] = "Hello";  
char cat[233] = "Worldxxx";  
strncat(str, cat, 5);  

strlen(p) 

  取字符串长度,这是我们最常用的一个函数了,得到字符串长度,没什么好说的,需要注意的是p必须为合法字符串,即有'\0',下文中若再次提到“合法字符串”即为“包含“'\0'”的字符串 。还有一点是,该函数返回值为字符串的字符数,要区别于字符串占用空间,比如对于字符串"love",它的长度为4,而占用空间为5,strlen对于此字符串的返回值即为4,示例:


char str[233] = "Hello";  
int len = strlen(str);  
strcmp(p, p1) 

  比较字符串,即比较p与p1的字典序大小,如果p比p1小(p字典序靠前),则返回小于0的数;若p比p1大(p字典序靠后),则返回大于0的数;若两字符串一样,则返回0。所谓的字典序,指的是将字符串首部对齐,从左到右依次比较对应位置的字符大小,直至找到第一个不一样的位置,其大小关系就是整个字符串的大小关系(如果大写与小写比较,则实际是比较其ASCII码),当然,如果比较到一个字符串结束还未有结果,则短的字符串靠前(想一下英文词典里单词的排序)。

例如"a"<"b","food"<"foot","hack">"back","hasak">"hasa","bbc">"abcd","Ask"<"ask"等……

该函数通常用于判断两字符串是否相等,两参数均可为常量,示例(该例子res值为-1):


char str[233] = "hello";  
char cmp[233] = "world";  
int res = strcmp(str, cmp);  
strcasecmp(p, p1)

strcasecmp(p, p1)

  忽略大小写比较字符串,与上一个函数是同样的功能,只不是上面是区别大小写的,这里是忽略大小写,也就是说,此函数认为'a'和'A'是相等的,也就是说字符串"abCdEFGhiJ"和"AbCDEfgHij"是相等的,返回值为0,示例(此例res为0)


char str[233] = "HEllo";  
char cmp[233] = "hELlo";  
int res = strcasecmp(str, cmp);  

strchr(p, c) 

  在字符串中查找指定字符, 即在p中从左向右查找第一次出现字符c的位置(找不到就返回NULL),参数c可为字符或表示ASCII码的整型。需要注意的是该函数的返回值并非下标整数值,而是一个代表该位置的地址,所以我们需要减去p的首地址即可得到该字符第一次出现的下标值。示例(下例res值为4):

char str[233] = "Hello world";  
char ch = 'o';  
int res = strchr(str, ch) - str;  
strrchr(p, c) 

  在字符串中反向查找指定字符, 与上一个函数功能一致,只不过这个是从右向左查找第一次出现的位置(返回值也是该位置的地址,找不到则NULL),同样需要减去首地址来获取索引下标值,示例(该res值为7):

char str[233] = "Hello world";  
char ch = 'o';  
int res = strrchr(str, ch) - str;  


strstr(p, p1) 

  查找字符串, 上述两个函数均是在字符串里查找字符,这个函数是从字符串查找字符串,也就是查找字符串的子串(找不到就返回NULL),在p中从左向右查找第一次匹配了p1的位置,比如p为"abcdabcd",p1为"bcd",则执行函数,返回值为第一次匹配的地方即蓝色的bcd中的b,同样是返回地址,需要减去首地址得到下标,示例(此res为2):

char str[233] = "Hello hello";  
int res = strstr(str, "llo") - str;  
即BP算法:
朴素的模式匹配算法
子串的定位操作通常称做模式匹配,
其中子串称做模式串,主串称做目标串,
朴素的模式匹配算法即是模式匹配的一种算法,
其优点是简单易懂,易于理解,某些应用场合效率较高。
缺点是需要多次回溯,
//对于数据较大的文本文件而言效率极低。
int index(char *a,char *b)
{
    int alen,blen;
    int i,j;
    alen=strlen(a);
    blen=strlen(b);
    i=0;
    j=0;
    while(i<alen&&j<blen)
    {
        if(a[i]==b[j])
        {
            i++;
            j++;
        }
        else
        {
            i=i-j+1;
            j=0;
        }
    }
    if(j>=blen) return i-blen;
    else return 0;
}
int main()
{
    char a[]="abacdefgj"; //主串
    char b[]="efg";//子串
    int pos;
    pos=index(a,b);
    printf("%d\n",pos);
    return 0;
}

KMP算法:
处理字符串匹配的较高效算法,明天好好研究一下。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值