C语言字符串的实现以及基本功能

1、 C语言字符串的实现以及基本功能

输入数据的时候按我这样输入:不然的话会把换行读进去
在这里插入图片描述

#include<stdio.h>
#include <mm_malloc.h>
#include <conio.h>

#define MAXSIZE 50
typedef struct String {

    char elem[MAXSIZE];
    int length;

} String, *LinearString;


int main() {
    int getArrayLength(char array[]);
    LinearString InitLinearString();
    int StrInsert(LinearString s, int pos, LinearString t);
    void InsertData(LinearString s);
    void InsertData(LinearString s);
    void display(LinearString s);
    int StrDelete(LinearString s, int pos, int length);
    int StrCompare(LinearString s, LinearString t);
    int StrIndex(LinearString s, int pos, LinearString t);
    int StrIndexKMP(LinearString s, LinearString t);

    LinearString s = InitLinearString();
    printf("给s点数据:");
    InsertData(s);
    display(s);
    printf("\n");
    printf("长度%d\n", s->length);

    printf("给t点数据:\n");
    LinearString t = InitLinearString();
    InsertData(t);
    display(t);
    printf("\n");
    printf("长度%d\n", t->length);
    printf("判断t在s中的位置在哪里:%d",StrIndex(s,0,t));
    printf("判断t在s中的位置在哪里KMP:%d",StrIndexKMP(s,t));
    printf("比较字符串s和字符窜t:%d\n", StrCompare(s, t));
    StrInsert(s, 4, t);
    display(s);
    printf("长度%d\n", s->length);
    StrDelete(s, 3, 3);
    display(s);


}

//初始化字符串
LinearString InitLinearString() {

    LinearString s = (String *) malloc(sizeof(String));
    s->length = 0;
    return s;
}

//插入数据
void InsertData(LinearString s) {
    int flag = 1, i = 0;
    char ch;
    while (flag) {
        ch = getch();
        if (ch != '$') {
            s->elem[i] = ch;
            s->length++;
            i++;
        } else {
            flag = 0;
        }
    }

}

//遍历数据
void display(LinearString s) {

    for (int i = 0; i < s->length; ++i) {
        printf("%c", s->elem[i]);
    }
    printf("\n");
}

//得到数组长度
int getArrayLength(char array[]) {
    int i = -1;
    int length;
    do {
        i++;
    } while (array[i] != '\0');
    return length = i;
}

//字符串插入函数  以数组的下标为基准
/**
 *        插入的时候会将字符串分为三部分: LA LB(LA和LB是 字符串S被拆开成了两部分) LC(LC是插入的那个字符串)
 *        有三种情况:
 *         1、如果s.length+t.length <= MAXSIZE, 那么意味着s中的数组容量够大,那么这个时候只需要将LB部分往后面挪,LC插入进来就可以啦
 *         2、如何s.length+t.length <= MAXSIZE不成立,并且pos +t.length <= MAXSIZE,那么这意味着,LB会失去一部分
 *         3、如何s.length+t.length <= MAXSIZE不成立,并且pos +t.length > MAXSIZE,那么这意味着,LB会全部失去,而且LC也会失去一些
 *
 */
int StrInsert(LinearString s, int pos, LinearString t) {

    if (pos < 0 || pos > s->length) {
        printf("插入的位置不对!");
        return -1;
    }

    if (s->length + t->length <= MAXSIZE) {

        for (int i = s->length + t->length - 1; i >= pos + t->length; i--) {
            s->elem[i] = s->elem[i - t->length]; // 这一步其实就是将第三部分往后面挪
        }
        for (int i = 0; i < t->length; i++) {
            s->elem[pos + i] = t->elem[i];
        }
        s->length = s->length + t->length;

    } else if ((pos + t->length) <= MAXSIZE) {

        for (int i = MAXSIZE - 1; i > t->length + pos - 1; i--) {
            s->elem[i] = s->elem[i - t->length];
        }
        for (int i = 0; i < t->length; i++) {
            s->elem[pos + i] = t->elem[i];
        }
        s->length = MAXSIZE;


    } else {

        for (int i = 0; i < MAXSIZE - pos; i++) {
            s->elem[pos + i] = t->elem[i];
        }
        s->length = MAXSIZE;
    }
    return 1;


}

//删除字符串
int StrDelete(LinearString s, int pos, int length) {

    if (pos < 0 || pos > s->length - length) {
        printf("删除不合理!");
        return -1;
    }

    for (int i = pos + length; i < s->length; ++i) {
        s->elem[i - length] = s->elem[i];
    }
    s->length = s->length - length;
    return 1;

}

//串的比较   比较的原理很简单就是一个字符一个字符比较,如果相等就返回0,同时也意味着他们一样长,如果不相等就返回第一次不同的字符之间的差值
int StrCompare(LinearString s, LinearString t) {

    for (int i = 0; i < s->length && i < t->length; ++i) {
        if (s->elem[i] != t->elem[i]) {
            return s->elem[i] - t->elem[i];
        }
    }
    return (s->length - t->length);

}

//串的简单匹配模式 暴力破解法    pos的作用可以使匹配模式更加灵活,可以找主串中任意位置后面模式串第一次出现的位置,不必一定要从第一个位置开始啦;
int StrIndex(LinearString s, int pos, LinearString t) {

    int i, j = 0, start;
    start = pos;
    i = start;

    if (t->length == 0) return (0);  // 模式串为空串的时候,是任意串的匹配串

    while (i < s->length && j < t->length) {

        if (s->elem[i] == t->elem[j]) {
            i++;
            j++;
        } else {
            // 用start记录i应该回到的位置
            start++;
            i = start;
            j = 0;

        }

    }

    if (j >= t->length){
        return start;
    }else{
        return -1;// 这一步意味着start已经到主串的末尾了,说明没有匹配成功
    }


}

//KMP算法解决串的匹配;
int StrIndexKMP(LinearString s,LinearString t){
    void getNext(LinearString t,int next[]);
    int next[t->length];
      int i = 0,j = 0;
    getNext(t,next);
    while (i < s->length && j < t->length){

        if ( j == -1 || s->elem[i] == t->elem[j]){
             i++;
             j++;
        }else{

                j = next[j];
        }
    }
    if ( j >= t->length){
        return i - t->length;
    }else{
        return  -1;
    }
}

void getNext(LinearString t,int next[]){

          int j,k; // j始终指向t中的元素,并且从头一直移动到尾,不发生重返的过程,k代表着最大公共前缀的长度
          //我们约定第一个元素的最长公共前缀长度为-1,其实没有公共前缀的元素约定为0;
          next[0] = -1;
          j = 0;
          k = -1;
          /**
           *  实现next的原理就是通过递推的方法,知道next[j],从而起的next[j+1]
           *  并且如果 Pk = Pj,那么有next[j+1] = k+1;
           *  如果k = -1,那就意味着next[j] = 1;就是没有公共前缀
           */

          while( j < t->length-1){
              // k如果等于 -1那么就代表着已经回溯到了next[0],那就意味着,next[j+1]的最长公共前缀一定是0的;
              // 如果是t->elem[k] == t->elem[j],那么及时满足这个条件Pk = Pj,那么有next[j+1] = k+1;
              if ( k == -1 || t->elem[k] == t->elem[j]){
                      j++;
                      k++;
                      next[j] = k;
              }else{
                    k = next[k];
              }
          }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值