数据结构——串的相关算法实现

数据结构——串的相关算法实现

顺序串的插入函数实现

在进行顺序串的插入时,插入pos将串分为两个部分(假设为A、B,长度为LA、LB)及待插入部分(假设为C,长度为LC),则串由插入前的AB变为ACB,由于是顺序串,插入会引起元素的移动。可能会出现以下的三种情况:

  • ①插入后串长度(LA+LC+LB)<=MAXLEN,则将B后移LC个元素位置,再将C插入;
  • ②插入后串长度 >=MAXLEN 且 pos+LC <=MAXLEN,则 B 后移时会有部分字符被舍弃;
  • ③插入后串长度>MAXLEN 且 pos+LC > MAXLEN,则 B 的全部字符被舍弃(不需要后移),并且C在插入时也有部分字符被舍弃。

代码实现

#include<stdio.h>

#define MAX_SIZE 128

typedef struct
{
    char ch[MAX_SIZE];
    int last;
}string;

void init_str(string * s, int max)
{
    int i;

    for(i = 0; i < max; i++)
        s->ch[i] = 0;//而谁的 ASCII 码对应的是 整型的0呢?是字符'\0'
    s->last = 0;
}

void create_str(string * s, char * a, int n)
{
    int i=0;
    for(;i < n; i++)
        s->ch[i] = a[i];

    s->ch[i+1] = '\0';
    s->last = n;
    printf("你输入的字符串为:\n");
    printf("%s\n",s->ch);
}

void insert_str(string * s,char * substr, int len, int pos)
{
    int i;

    if(pos < 0 || pos >= MAX_SIZE)
    {
        printf("输入的位置不合理!\n");
        return;
    }

    if (s->last + len >= MAX_SIZE) {
        printf("Can't insert, new string too long!\n");
        return;
    }

    if (pos >= s->last) {    /* 若插入的位置在last之后*/
        for (i = 0; i < len; i++)
            s->ch[s->last+i] = substr[i];//把新插入的串从s串的组后开始插入
        s->ch[s->last+i] = 0;//插入新串之后,字符串的最末尾'\0' ,0 是'\0' 的 ASCII
        puts(s->ch);
        s->last += len;
    } else {    /* 若插入的位置在ch内*/
        for (i = 0; i < len; i++)
            s->ch[pos+len+i] = s->ch[pos+i];//在没有插入新的串之前把s串分2部分,然后把后面部分整体向后移动len个长度
                                            //即,给即将要插入的串“腾空 ” 

        for (i = 0; i < len; i++)
            s->ch[pos+i] = substr[i]; //把新的串插入到刚刚腾出来的地方
        s->ch[s->last+len] = 0; //插入后的“串”已经确定,改变了最后'/0'位置
        s->last += len; //串的最大长度也重新确定 即,s->last = s->last+len
    }
}
int main()
{
    string s;
    int pos, i;
    char a[80],b[80];

    init_str(&s, MAX_SIZE);
    printf("请输入字符串:\n");
    scanf("%s",a);

    /* 遍历整个字符串,并把a[]中的字符存在s中,长度为i ,然后输出*/
    for(i = 0; a[i]; i++)//for(i=0;a[i]!='\0';i++) 后者这个准确些
        ;
    create_str(&s, a, i);//
    printf("请输入你要插入的字符串:\n");
    scanf("%s", b);

    for(i = 0; b[i]; i++)
        ;
    printf("请输入你要插入的位置:\n");
    scanf("%d",&pos);
    insert_str(&s, b, i, pos);//找到原来的串“s”,把b[]中的字符存进去,新插入的字符串的长度为i,插入的
                               // 位置为pos

    printf("新的字符串为:\n");
    printf("%s\n",s.ch);//输出插入后 所组成的 新串
    return 0;
}

串的删除函数实现

指定要删除的位置,和从此位置要删除的字符的长度,实现删除字符串的删除操作。

代码实现

#include<stdio.h>

#define MAX_SIZE 128

typedef struct
{
    char ch[MAX_SIZE];
    int last;
}string;

void init_str(string * s, int max)
{
    int i;

    for(i = 0; i < max; i++)
        s->ch[i] = 0;//而谁的 ASCII 码对应的是 整型的0呢?是字符'\0'
    s->last = 0;
}

void create_str(string * s, char * a, int n)
{
    int i=0;
    for(;i < n; i++)
        s->ch[i] = a[i];

    s->ch[i+1] = '\0';
    s->last = n;
    printf("你输入的字符串为:\n");
    printf("%s\n",s->ch);
}

//顺序串的删除函数

void StrDelete(string * s,int pos,int len)
{
    int i;
    if(pos<0||pos>(s->last-len))
        {
            printf("删除参数不合法!");
            return;
        }
    for(i=pos+len;i<s->last;i++)
    {
        s->ch[i-len] = s->ch[i];
    }
    s->ch[s->last-len] = 0;
    s->last = s->last - len;
}

int main()
{
    string s;
    int pos, i,n;
    char a[80];

    init_str(&s, MAX_SIZE);
    printf("请输入字符串:\n");
    scanf("%s",a);

   for(i = 0; a[i]; i++)//for(i=0;a[i]!='\0';i++) 后者这个准确些
        ;
    create_str(&s, a, i);// 

    printf("请输入要删除的位置 及字符串长度:");
    scanf("%d %d",&pos,&n);
    StrDelete(&s,pos,n);

    printf("新的字符串为:\n");
    printf("%s\n",s.ch);//输出插入后 所组成的 新串
    return 0;
}

串的比较函数实现

串的比较,即对两个字符串进行比较(ascii)在本例中,若串s和相等,则返回0,若s>t则返回正数,反之则返回负数。

代码实现

#include<stdio.h>

#define MAX_SIZE 128

typedef struct
{
    char ch[MAX_SIZE];
    int last;
}string;

void init_str(string * s, int max)
{
    int i;

    for(i = 0; i < max; i++)
        s->ch[i] = 0;//而谁的 ASCII 码对应的是 整型的0呢?是字符'\0'
    s->last = 0;
}

void create_str(string * s, char * a, int n)
{
    int i=0;
    for(;i < n; i++)
        s->ch[i] = a[i];

    s->ch[i+1] = '\0';
    s->last = n;
    printf("你输入的字符串为:\n");
    printf("%s\n",s->ch);
}

//串比较函数

int StrCompare(string s,string t)
{
    /*若串s和t相等则返回0,若s>t则返回正数;若s<t,则返回负数*/
    int i;
    int equle = 0;
    for(i=0;i<s.last&&i<t.last;i++)
    {
        if(s.ch[i]!=t.ch[i])
            return(s.ch[i]-t.ch[i]);//都是ascii码 

    }
    return equle;

} 

int main()
{
    string s,t;
    int pos,i;
    int m;
    char a[80];
    char b[80];

    init_str(&s, MAX_SIZE);
    printf("请输入字符串1:\n");
    scanf("%s",a);
    printf("请输入字符串2:\n");
    scanf("%s",b);

   for(i = 0; a[i]; i++)//for(i=0;a[i]!='\0';i++) 后者这个准确些
        ;
    create_str(&s, a, i);//
    for(i = 0; b[i]; i++)//for(i=0;a[i]!='\0';i++) 后者这个准确些
        ;

    create_str(&t, b, i);
    m = StrCompare(s,t);
    printf("%d",m);                        

    return 0;
}

串的简单模式匹配BF算法

简单的模式匹配算法是一种带回溯的匹配算法,算法的基本思想这里不再进行描述,可以在网上或书上找到很好的答案。这个算法时间复杂度较高。

代码实现

/*串的简单模式匹配函数*/

#include<stdio.h>

#define MAX_SIZE 128

typedef struct
{
    char ch[MAX_SIZE];
    int last;//串的长度
}string;

void init_str(string * s, int max)
{
    int i;

    for(i = 0; i < max; i++)
        s->ch[i] = 0;//而谁的 ASCII 码对应的是 整型的0呢?是字符'\0'
    s->last = 0;
}

void create_str(string * s, char * a, int n)
{
    int i=0;
    for(;i < n; i++)
        s->ch[i] = a[i];

    s->ch[i+1] = '\0';
    s->last = n;
    printf("你输入的字符串为:\n");
    printf("%s\n",s->ch);
}

//顺序串的基本匹配算法

void StrIndex (string s,int pos,string t)
{
    /*求从主串的下标pos起....*/
    int i,j,start;
    if(t.last == 0)
        printf("匹配成功!");
     start = pos;
     i = start;//主串不一定从索引为0的字符开始,具体位置又客户指定
     j = 0;//模式串从索引0开始
     while(i<s.last&&j<t.last)
     {
        if(s.ch[i]==t.ch[j])
        {
            i++;
            j++;
        }
        else
        {
            start++;
            i = start;
            j=0;
        }

     }
      if(j>=t.last)
        printf("匹配成功!匹配成功的位置索引为%d",start);
      else
        printf("匹配失败!"); 

}

int main()
{
    string s,t;
    int pos,i;
    int m;
    char a[80];
    char b[80];

    init_str(&s, MAX_SIZE);
    printf("请输入字符串1:\n");
    scanf("%s",a);
    printf("请输入字符串2:\n");
    scanf("%s",b);

   for(i = 0; a[i]; i++)//for(i=0;a[i]!='\0';i++) 后者这个准确些
        ;
   create_str(&s, a, i);//
   for(i = 0; b[i]; i++)//for(i=0;bi]!='\0';i++) 后者这个准确些
        ;

    create_str(&t, b, i);

    StrIndex (s,0,t);

    return 0;
}

串的模式匹配改进的KMP算法

KMP算法的效率比Bf算法是要快的,具体的算法不再描述,这里只是简单给出相关代码实现。具体算法实现的内容可以参考课本和网上的解释。

代码实现

/*串的KMP匹配函数 */
/*http://www.ruanyifeng.com/blog/2013/05/Knuth%E2%80%93Morris%E2%80%93Pratt_algorithm.html*/
/*上面的是对KMF算法的讲解,我个人觉得写的很清晰了emmmmm*/ 

#include<stdio.h>

#define MAX_SIZE 128

typedef struct
{
    char ch[MAX_SIZE];
    int last;//串的长度
}string;

void init_str(string * s, int max)
{
    int i;

    for(i = 0; i < max; i++)
        s->ch[i] = 0;//而谁的 ASCII 码对应的是 整型的0呢?是字符'\0'
    s->last = 0;
}

void create_str(string * s, char * a, int n)
{
    int i=0;
    for(;i < n; i++)
        s->ch[i] = a[i];

    s->ch[i+1] = '\0';
    s->last = n;
    printf("你输入的字符串为:\n");
    printf("%s\n",s->ch);
}

//顺序串的基KMP算法

void Index_KMP(string s,int pos,string t)
{
    int i,j;
    int next[MAX_SIZE];
    i = pos;
    j = 1;//规定若指向了空格的话就是0,所以这里从1开始
    while(i<s.last&&j<t.last)
    {
        if(j == 0||s.ch[i] == t.ch[j])
        {
            i++;
            j++;
        }
        else
        {
            j = next[j];
        }

    }
    if(j>=t.last)
        printf("匹配成功!匹配成功的位置索引为%d",i-j);//i是模式串移动后“最后”的位置索引,
    else                                              //如果想要开始索引,减去“移动的块的长度就可以了”
        printf("匹配失败!"); 

}

int main()
{
    string s,t;
    int pos,i;
    int m;
    char a[80];
    char b[80];

    init_str(&s, MAX_SIZE);
    printf("请输入字符串1:\n");

    printf("请输入字符串2:\n");
    scanf("%s",b);

   for(i = 0; a[i]; i++)//for(i=0;a[i]!='\0';i++) 后者这个准确些
        ;
   create_str(&s, a, i);//
   for(i = 0; b[i]; i++)//for(i=0;bi]!='\0';i++) 后者这个准确些
        ;

    create_str(&t, b, i);

    Index_KMP (s,0,t);

    return 0;
}

参考文献

  • 数据结构-用C语言描述(第二版)[耿国华]

原文地址:https://www.cnblogs.com/yjlblog/p/8997703.html

时间: 2024-10-08 04:21:31

数据结构——串的相关算法实现的相关文章

数据结构-单向链表相关算法

#include <stdio.h>#include <stdlib.h>#define OVERFLOW -2#define OK 1#define ERROR 0typedef int ElemType;//单向链表结构体typedef struct LNode {    ElemType data;    struct LNode *next;}LNode,*LinkList; LinkList CreateList_L(LinkList L,int n);void Trav

数据结构与算法JavaScript (五) 串(经典KMP算法)

数据结构与算法JavaScript (五) 串(经典KMP算法) KMP算法和BM算法 KMP是前缀匹配和BM后缀匹配的经典算法,看得出来前缀匹配和后缀匹配的区别就仅仅在于比较的顺序不同 前缀匹配是指:模式串和母串的比较从左到右,模式串的移动也是从 左到右 后缀匹配是指:模式串和母串的的比较从右到左,模式串的移动从左到右. 通过上一章显而易见BF算法也是属于前缀的算法,不过就非常霸蛮的逐个匹配的效率自然不用提了O(mn),网上蛋疼的KMP是讲解很多,基本都是走的高大上路线看的你也是一头雾水,我试

数据结构(C语言版)顺序栈相关算法的代码实现

这两天完成了栈的顺序存储结构的相关算法,包括初始化.压栈.出栈.取栈顶元素.判断栈是否为空.返回栈长度.栈的遍历.清栈.销毁栈.这次的实现过程有两点收获,总结如下: 一.清楚遍历栈的概念 栈的遍历指的是从栈底想栈顶方向运行visit()函数,这是之前的学习中所忽略的:栈的遍历解除了栈的输出顺序只能从栈顶像栈底方向的限制. 二.清空栈时要不要将stacksize重置 网上看到有的人在实现清空栈这一功能时,将stacksize重置为0,我觉得有点问题,起初的想法是将其重置为初始化时的值,在与同学讨论

数据结构(二) — 算法

一.数据结构与算法的关系 上一次我大致说了数据结构的一些基本概念,应该还蛮通俗易懂的吧(大概吧!!!).数据结构与算法这两个概念其实是可以单独拿出来讲的,毕竟我们大学有数据结构课,有算法课,单独拿出来讲好像没什么问题,但是数据结构就那么一些(数组.队列.树.图等结构),单独拿出来很快就说完了,但是说完之后,一脸懵逼,两脸茫然,感觉数据结构没什么用啊,但是,注意了啊,但是引入算法,变成程序之后你就会发觉某些特别困难的问题,原来可以用程序这么简单的解决. 所以在我们用程序解决问题看来,程序 = 数据

探索推荐引擎内部的秘密,第 2 部分: 深入推荐引擎相关算法 - 协同过滤(转)

第 2 部分: 深入推荐引擎相关算法 - 协同过滤 本系列的第一篇为读者概要介绍了推荐引擎,下面几篇文章将深入介绍推荐引擎的相关算法,并帮助读者高效的实现这些算法. 在现今的推荐技术和算法中,最被大家广泛认可和采用的就是基于协同过滤的推荐方法.它以其方法模型简单,数据依赖性低,数据方便采集 , 推荐效果较优等多个优点成为大众眼里的推荐算法“No.1”.本文将带你深入了解协同过滤的秘密,并给出基于 Apache Mahout 的协同过滤算法的高效实现.Apache Mahout 是 ASF 的一个

javascript实现数据结构: 串的块链存储表示

和线性表的链式存储结构相类似,也可采用链式方式存储串值.由于串结构的特殊性--结构中的每个数据元素是一个字符,则用链表存储串值时,存在一个"结点大小"的问题,即每个结点可以存放一个字符,也可以存放多个字符. 下面是结点大小为4(即每个结点存放4个字符)的链表: head --> (a) --> (b) --> (c) --> ... --> (i) 当结点大小大于1时,由于串长不一定是结点大小的整倍数,则链表中的最后一个结点不一定全被串值占满,此时通常补上

加密类型及其相关算法

在互联网通信过程中,如何保证数据的安全性? 在通信过程中,数据安全主要从三个方面考虑:机密性(数据的内容不能被窃取) 完整性(数据的内容不能被修改) 身份验证(确定通信双方的身份) 加密类型:1.对称加密,加密和解密使用同一个密钥,但是密钥如何安全传输比较重要,对称加密数度较快,适于加密数据 2.单向加密,提取数据指纹,主要用于保证数据的完整性 单向加密的特点:输入相同则输出一定相同 雪崩效应:输入的微小改变会引起结果的巨大反差 定长输出 3.非对称加密,使用一对密钥(public-key和pr

探索推荐引擎内部的秘密,第 3 部分: 深入推荐引擎相关算法 - 聚类

聚类分析 什么是聚类分析? 聚类 (Clustering) 就是将数据对象分组成为多个类或者簇 (Cluster),它的目标是:在同一个簇中的对象之间具有较高的相似度,而不同簇中的对象差别较大.所以,在很多应用中,一个簇中的数据对象可以被作为一个整体来对待,从而减少计算量或者提高计算质量. 其实聚类是一个人们日常生活的常见行为,即所谓"物以类聚,人以群分",核心的思想也就是聚类.人们总是不断地改进下意识中的聚类模式来学习如何区分各个事物和人.同时,聚类分析已经广泛的应用在许多应用中,包

HDU ACM 4513 吉哥系列故事——完美队形II-&gt;求最长回文串(manacher算法)

分析:该題可以通过求最长回文串的方法来解决:求最长回文串使用manacher算法,O(n)时间复杂度. 注意:while(a[i-len[i]]==a[i+len[i]] && a[i-len[i]]<=a[i-len[i]+2])这里多出的判断a[i-len[i]]<=a[i-len[i]+2]即为该題的限制从左到中保证身高不降,因在回文串的计算过程中添加了额外的字符,所以这里是i-len[i]+2而不是i-len[i]+1,以避开添加的字符. #include<ios