• 基本概念:

          维基百科:https://en.wikipedia.org/wiki/String_(computer_science)

          百度百科:http://baike.baidu.com/link?url=YZL4T0SmYXbWBAQyUtrBMDt0pDmZRR_dDCID6BBcbL9i9y-ZmheoNT93PsXCvZbo

        串(或字符串),是由零个或多个字符组成的有穷序列。含零个字符的串称为空串,用Ф表示。
        串中所含字符的个数称为该串的长度(或串长)。
        当且仅当两个串的长度相等并且各个对应位置上的字符都相同时,这两个串才是相等的。
        一个串中任意个连续字符组成的子序列(含空串,但不含串本身)称为该串的子串。例如,“a”、“ab”、“abc”和“abcd”等都是“abcde”的子串(平凡子串不包括自身)。

        例子: “abcde”有多少个平凡子串?
               解:    空串数:1
                       含1个字符的子串数:5
                       含2个字符的子串数:4
                       含3个字符的子串数:3
                       含4个字符的子串数:2
                       共有1+2+3+4+5=15个子串。

    串的存储结构:

      串的顺序存储及其基本操作实现

             串是一种特殊的线性表,在非紧缩格式中,它的每个结点仅由一个字符组成,因此存储串的方法也就是存储线性表的一般方法。存储串最常用的方式是采用顺序存储,即把串的字符顺序地存储在内存一片相邻的空间,这称为顺序串。

    串的非紧缩格式(一个单元存放一个字符)与串的紧缩格式(一个单元存放多个字符)。

    顺序存储采用一般顺序表的存储结构,其类型定义如下:

    #define MaxSize 100
    typedef struct
    {
      char data[MaxSize];
      int len;
    } strtype;//[紧缩格式]

         其中,ch域用来存储字符串,len域用来存储字符串的当前长度,MaxSize常量表示允许所存储字符串的最大长度。在C语言中每个字符串以''标志结束(在这个结构体中不需要用''标志结束,以下标为0开始存入字符)。

    ASCII比较字符串
      由于 "大写字母<小写字母" ,并且a<b,因此在比较时ASCII大的字母比较靠前,但要特殊考虑大小写夹杂的情况。

    串的链式结构存储
         链式方式存储串,即用单链表形式存储串。这称为链式串或链串。
    链串中的结点类型定义:

    typedef struct snode
    {    char data;
         struct snode *next;
    } LiString;

    例:在链串中,设计一个算法把最先出现的子串"ab"改为"xyz"。    
    解:在串s中找到最先出现的子串"ab",p指向data域值为'a'的结点,其后为data域值为'b'的结点。将它们的data域值分别改为'x'和'z',再创建一个data域值为'y'的结点,将其插入到*p之后。本例算法如下:

    void Repl(LiString *&s)
    {    
        iString *p=s->next,*q;int find=0;
        while (p->next!=NULL && find==0)
        {     
            if (p->data==‘a’ && p->next->data==‘b’)  /*找到*/    
            {   p->data='x';p->next->data='z';        
                   /*替换为xyz*/
                    q=(lstring *)malloc(sizeof(lstring));
                    q->data='y';q->next=p->next;
                    p->next=q;
                    find=1;
                   }
                   else p=p->next;
            }
    }

    相关算法:

    串的模式匹配----------------------------

          设有主串s和子串t,子串t的定位就是要在主串s中找到一个与子串t相等的子串。通常把主串s称为目标串,把子串t称为模式串,因此定位也称作模式匹配。模式匹配成功是指在目标串s中找到一个模式串t;不成功则指目标串s中不存在模式串t。 

    算法一:BF算法(Brute-Force)
        Brute-Force简称为BF算法,亦称简单匹配算法,其基本思路是:
        从目标串s="s0s1…sn-1"的第一个字符开始和模式串t="t0t1…tm-1"中的第一个字符比较,若相等,则继续逐个比较后续字符;否则从目标串s的第二个字符开始重新与模式串t的第一个字符进行比较。依次类推,若从模式串s的第i个字符开始,每个字符依次和目标串t中的对应字符相等,则匹配成功,该算法返回i;否则,匹配失败,函数返回-1。 

    有2种实现方法:

    //方法一
    int indexpos(SqString str,SqString substr)
    {    int i,j,k,idx=-1;
        for (i=0;i<str.len;i++)
        {   
             for (j=i,k=0;str.data[j]==substr.data[k];j++,k++);
             if (k==substr.len) //注意j每次从i开始,有回溯
                      return(i);
        }
        return(-1);
    }
    //方法二
    int index(SqString s,SqString t)
    {  
        int i=0,j=0,k;
        while (i<s.len && j<t.len)
        {   
             if (s.data[i]==t.data[j])      /*继续匹配下一个字符*/
            {        
               i++; j++;     /*主串和子串依次匹配下一个字符*/
            }
            else     /*主串、子串指针回溯重新开始下一次匹配*/
           {     
                      i=i-j+1;     /*主串从下一个位置开始匹配*/
                      j=0;            /*子串从头开始匹配*/
            }
         }
         if (j>=t.len)   k=i-t.len;     /*返回匹配的第一个字符的下标*/
         else  k=-1;                /*模式匹配不成功*/
         return k;
      }

    算法二(KMP算法):

    基本概念:(转自:http://kb.cnblogs.com/page/176818/)

    实现代码:

    #include<stdio.h>
    #include<string.h>
    void makeNext(const char P[],int next[])
    {
        int q,k;
        int m = strlen(P);
        next[0] = 0;
        for (q = 1,k = 0; q < m; ++q)
        {
            while(k > 0 && P[q] != P[k])
                k = next[k-1];
            if (P[q] == P[k])
            {
                k++;
            }
            next[q] = k;
        }
    }
    
    int kmp(const char T[],const char P[],int next[])
    {
        int n,m;
        int i,q;
        n = strlen(T);
        m = strlen(P);
        makeNext(P,next);
        for (i = 0,q = 0; i < n; ++i)
        {
            while(q > 0 && P[q] != T[i])
                q = next[q-1];
            if (P[q] == T[i])
            {
                q++;
            }
            if (q == m)
            {
                printf("Pattern occurs with shift:%d
    ",(i-m+1));
            }
        }    
    }
    
    int main()
    {
        int i;
        int next[20]={0};
        char T[] = "ababxbababcadfdsss";
        char P[] = "abcdabd";
        printf("%s
    ",T);
        printf("%s
    ",P );
        // makeNext(P,next);
        kmp(T,P,next);
        for (i = 0; i < strlen(P); ++i)
        {
            printf("%d ",next[i]);
        }
        printf("
    ");
    
        return 0;
    }
  • 相关阅读:
    第02组 Alpha冲刺 (6/6)
    面向对象分析设计考试复习【历年卷】
    第02组 Alpha冲刺 (5/6)
    第02组 Alpha冲刺 (4/6)
    第02组 Alpha冲刺 (3/6)
    第02组 Alpha冲刺 (2/6)
    第02组 Alpha冲刺 (1/6)
    linux内核结构
    从别人的博客学习
    递归的认识
  • 原文地址:https://www.cnblogs.com/darklights/p/5302207.html
Copyright © 2020-2023  润新知