chapter_4 串

目录

串(或字符串)是由零个或多个字符组成的有限序列。
串中所含字符的个数称为该串的长度(或串长),含零个字符的串称为空串,用Ф表示。

串的逻辑表示, ai(1≤i≤n)代表一个字符:"a1a2…an",双引号不是串的内容,起标识作用

串相等:当且仅当两个串的长度相等并且各个对应位置上的字符都相同时,这两个串才是相等的。

如:
"abcd" ≠ "abc";
"abcd" ≠ "abcde";
所有空串是相等的。

子串:一个串中任意个连续字符组成的子序列(含空串)称为该串的子串。
例如:"abcde" 的子串有:"", "a", "b", "c", "d", "e", "ab", ..., "abcde"
真子串是指不包含自身的所有子串。

ADT List {
    数据对象:D={ ai | ai ∈ElemSet, i=1,2,...,n,  n≥0 }
    数据关系:R={ <ai-1 ,ai >|ai-1 ,ai∈D,  i=2,...,n }
    基本操作:
    StrAssign(s,cstr):将字符串常量cstr赋给串s,即生成其值等于cstr的串s。
    StrCopy(s,t):串复制。将串t赋给串s。
    StrEqual(s,t):判串相等。若两个串s与t相等则返回真;否则返回假。
    StrLength(s):求串长。返回串s中字符个数。
    Concat(s,t):串连接:返回由两个串s和t连接在一起形成的新串。
    SubStr(s,i,j):求子串。返回串s中从第i(1≤i≤n)个字符开始的、由连续j个字符组成的子串。
} ADT List

主串与模式串匹配问题

#include<stdio.h>
#include<string.h>
#define N 10001
int next[N], nextval[N];

int bf(char *s1,char *s2,int pos) {
    int i=0, j=0;
    while(s1[i]!='\0' && s2[j]!='\0') {
        if(s1[i]==s2[j]) {
            ++i, ++j;
        } else {
            i = i-j+1, j = 0;
        }
    }
    if(s2[j]=='\0') return i-j;
    return -1;//未匹配成功
}
/*
next数组:确定下一轮匹配中子串的元素位置
S:abaabcac
T:abc
     S : a b a a b c a c
     j : 1 2 3 4 5 6 7 8
next[j]: 0 1 1 2 2 3 1 2
.val[j]: 0 1 0 2 1 3 0 2
T : aaaaaaaab
于是next可以改进修正,得到 nextval数组 */

void get_next(char* s,int *next) {
    int j=0, k=-1, len=strlen(s);
    next[0] = -1;
    while(j < len-1) {
        if(k==-1 || s[j]==s[k]) {
            ++j, ++k;
            next[j] = k;
        } else k = next[k];
    }
}
void get_nextval(char* s,int *next) {
    int j=0, k=-1, len=strlen(s);
    next[0] = -1;
    while(j < len-1) {
        if(k==-1 || s[j]==s[k]) {
            ++j, ++k;
            if(s[j]==s[k]) next[j] = next[k];
            else next[j] = k;
        } else k = next[k];
    }
}
int kmp(char *s1,char *s2,int pos) {
//    get_next(s2, next);
    get_nextval(s2, next);
    int i=pos, j=0, l1=strlen(s1), l2=strlen(s2);
    while(i<l1 && j<l2) {
        if(j==-1 || s1[i]==s2[j]) {
            i++, j++;
        } else j = next[j];
    }
    if(j>=l2) return i-l2;
    return -1;
}

int main() {
    char s1[]="acabaabcacaabc";
    char s2[]="abaabcac";
    int index1 = bf(s1, s2, 0);
    int index2 = kmp(s1, s2, 0);
    printf("%d %d\n",index1,index2);

    get_next(s2, next);
    get_nextval(s2, nextval);
    int i=0;
    printf("id:");
    for(i=0; s1[i]!='\0'; i++) printf("%2d ", i); printf("\n");

    printf("S :");
    for(i=0; s1[i]!='\0'; i++) printf("%2c ", s1[i]); printf("\n");

    printf("T :");
    for(i=0; s2[i]!='\0'; i++) printf("%2c ", s2[i]); printf("\n");

    printf("ne:");
    for(i=0; s2[i]!='\0'; i++) printf("%2d ", next[i]); printf("\n");

    printf("nv:");
    for(i=0; s2[i]!='\0'; i++) printf("%2d ", nextval[i]); printf("\n");
    return 0;
}

posted @ 2022-03-07 10:50  HelloHeBin  阅读(87)  评论(0)    收藏  举报