作者: lxr_ | 来源:发表于2019-02-21 17:30 被阅读0次

注:不足及错误请指正

+qq 1366963396 讨论

串(string)是由零个或多个字符组成的有限序列,又名叫字符串

//生成一个其值等于字符串常量chars的串T,即在头部添加长度

char* StrAssign(char* T, char* chars)

{

    T[0] =strlen(chars);

    for (int i = 1; i <= T[0]; i++)

    {

        T[i] = *(chars + i - 1);

    }

    return T;

}

//串S存在,由串S复制得串T

char* StrCopy(char* T, char* S)

{

    for (int i = 0; i < S[0]; i++)

    T[i] = S[i];

    return T;

}

//串S存在,将串清空

void ClearString(char* S)

{

    if (StringEmpty(S))

    return;

    S[0] = 0;

}

//若串S为空,返回True

bool StringEmpty(char* S)

{

    if (S[0] == 0)

    return true;

    return false;

}

//返回串S的长度

int StrLength(char* S)

{

    return S[0];

}

//比较两个字符串(S>T,返回>0;S<T,返回<0;S=0,返回0) 

int Strcompare(char* S, char* T)

{

    for (int i = 1; i <= S[0] && i <= T[0]; i++)

    {

        if (S[i] != T[i])

            return S[i] - T[i];

    }

    return S[0] - T[0];

}

//连接成新串

char* Concat(char* T, char* S1, char* S2)

{

    T[0] = S1[0] + S2[0];

    for (int i = 1; i <= S1[0]; i++)

    {

        T[i] = S1[i];

    }

    for (int i = S1[0]+1; i <= T[0]; i++)

    {

        T[i] = S1[i-S1[0]];

    }

    return T;

}

//串S存在,用sub返回S的第pos个字符起长度为len的字串

char* SubString(char* Sub, char* S, int pos, int len)

{

    if (pos<1 || pos>S[0] || len > S[0] - pos + 1)

        return NULL;

    Sub[0] = len;

    for (int i = 1; i <=len; i++)

    {

        Sub[i] = S[i+pos-1];

    }

    return Sub;

}

//朴素的模式匹配算法

//串S和T存在,T是非空串,若主串S中存在和串T值相同的子串,则返回他在主串S中第pos个字符之后第一次出现的位置,否则返回0

int Index(char* S, char* T, int pos)

{

    int n, m, i;

    char Sub[20];

    if (pos > 0)

    {

        n = StrLength(S);

        m = StrLength(T);

        i = pos;

        while (i<=n-m+1)

        {

            SubString(Sub, S, i, m);

            if (Strcompare(Sub, T)!= 0)

                ++i;

            else

            {

                return i;

            }

        }

    }

    return 0;

}

//串S,T,V存在,T是非空串,用V替换主串S中所有与T相等的不重叠的子串

char* Replace(char* S, char* T, char* V)

{

    if (StringEmpty(T))

        return S;

    int n = StrLength(S);

    int m = StrLength(T);

    int k = StrLength(V);

    char sub[20];

    for (int i = 1; i <= n-m; i++)

    {

        if (Strcompare(SubString(sub,S,i,m),T)==0)

        {

            StrDelete(S, i, m);//删除T

            StrInsert(S, i, V);//插入V

            i += StrLength(V);//在插入V后继续寻找相同字串

        }

        else

        {

            continue;

        }

    }

    return S;

}

//串S和T存在,在串S的第pos个字符之前插入串T

char* StrInsert(char* S, int pos, char* T)

{

    if (pos<1 || pos>S[0] + 1)

        return S;

     for (int i = S[0]; i >= pos; i--)//后移

        S[i + T[0]] = S[i];

    for (int i = pos; i < pos + T[0]; i++)//插入

    {

        S[i] = T[i - pos + 1];

    };

    S[0] = S[0] + T[0];

    return S;

}

//串S存在,从串S中删除第pos个字符起长度为len的字符串

char* StrDelete(char* S, int pos, int len)

{

    if (pos<1 || len<0 || pos>S[0]-len + 1)

        return S;

    for (int i = pos; i <=S[0]-len; i++)

        S[i] = S[i + len];

    S[0] -= len;

    return S;

}

//输出字符串

void PrintString(char* S)

{

    for (int i = 1; i <= S[0]; i++)

        printf("%c ", S[i]);

    printf("\n");

}

//模式匹配,不用串的操作,只用基本数组,与上面Index的效果一样

int Index(char* S,char* T,int pos)

{

    int i=pos;//i用于主串S中当前位置下标

    int j=i;//j用于指示子串T中当前位置下标

    while(i<=S[0]&&j<=T[0])

    {

        if(S[i]==T[j])//两字符相等则继续

        {

            ++i;

            ++j;

        }

        else//重新开始匹配

        {

            i=i-j+2;//i退回到上次匹配首位的下一位

            j=1;//j退回到子串的首位

        }

    }

    if(j>T[0])

        return i-T[0];

    else

        return 0;

}

KMP匹配算法

//计算子串T的next数组

void get_next(char* T, int* next)

{

    int i, j;

    i = 1;

    j = 0;

    next[1] = 0;

    while (i < T[0])

    {

        if (j == 0 || T[i] == T[j])//T[i]表示后缀,T[j]表示前缀

        {

            ++i;

            ++j;

            next[i] = j;

        }

        else

        {

            j = next[j];//字符不相同,j值回溯

        }

    }

}

KMP匹配算法改进

//求模式串T的next函数修正值并存入nextval

void get_nextval(char* T, int* nextval)

{

    int i = 1, j = 0;

    nextval[1] = 0;

    while (i < T[0])

    {

        if (j == 0 || T[i] == T[j])

        {

            ++i;

            ++j;

            if (T[i] != T[j])//若当前字符与前缀字符不同,,则当前的j为nextval在i位置的值

                nextval[i] = j;

            else

                nextval[i] = nextval[j];//若相同,则将前缀字符的nextval值赋给nextval在i位的值

        }

        else

        {

            j = nextval[j];//若字符不相同,则j值回溯

        }

    }

}

相关文章

  • 串手串

    某多买的手工材料到了,晚饭后回到家,开始串手串。 之前在老家在店里买的石榴石手串200多,有点紧,勒胳膊。 想着买...

  • 糖葫芦

    糖葫芦啊,糖葫芦, 串一串啊,串一串, 五个串一串, 味道酸又甜。

  • 日日行

    一串串的星月隐了,一串串的太阳升起来;一串串的日子里,和着一串串的柴米油盐;一串串的笑声后,或躲着一串串...

  • 模式匹配中Brute-Force与KMP算法关键提取

    模式匹配是串结构的一种操作方法,用于串的匹配。待匹配串称为主串(也叫目标串),执行串称为子串(也叫模式串)。模式匹...

  • iOS中的NSString与NSMutableString

    字符串的创建 字符串读写 字符串的比较 字符串的搜索 字符串截取 字符串替换 字符串与路径 字符串转换 NSMut...

  • Javascript知识点整合

    字符串 单行字符串: ‘字符串’或“字符串” 多行字符串: `多行字符串` 字符串操作: 字符串连接‘+’号 长度...

  • DS串应用--串替换

    题目描述 给出主串、模式串、替换串,用KMP算法找出模式串在主串的位置,然后用替换串的字符替换掉模式串 本题只考虑...

  • Go 关于串的三个经典案例

    子串查找 介绍 子串查找,也可以成为字符串查找。其中有两个字符串,分为主串和子串(模式串)。在主串中查找是否含有子...

  • php 字符串常见方法汇总

    字符串拼接 字符串检索 字符串截取 字符串替换 字符串大小写转化 字符串转数组 字符串格式化

  • jq的字符串操作

    字符串拼接 字符串长度 子串 split trim 子串替换

网友评论

      本文标题:

      本文链接:https://www.haomeiwen.com/subject/xklhcqtx.html