C string

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct{
    char *ch;
    int length;
}MyString;

int InitMyString(MyString *s){
    // s = (MyString*)malloc(sizeof(MyString));
    // 不能在这里面 malloc 的原因:
    // 因为值传递,s的值被复制过来,无法改变s的值
    // 要想改变s的值 需要传递 *s
    // 参数应为 MyString **s
    if(!s)return 0;
    s->ch = NULL;
    s->length = 0;
    return 1;
}

void PrintMyString(const MyString *s){
    if(!s)
        printf("Wrong input for PrintMyString.\n");
    else if(!(s->ch))
        printf("Empty MyString\n");
    else
        printf("string: %s \nlength: %d\n", s->ch, s->length);
}

/*
https://www.zhihu.com/question/28104169
**sizeof**
When applied to an operand that has type char, unsigned char, 
or signed char, (or a qualified version thereof) the result is 1. 
When applied to an operand that has array type, the result is 
the total number of bytes in the array.) When applied to an operand 
that has structure or union type, the result is the total number of bytes 
in such an object, including internal and trailing padding.
**char**

char *s = "hello";
    printf("sizeof char is %lu, sizeof char* is %lu, sizeof 'a' is %lu\n",
        sizeof(char), sizeof(char*), sizeof('a')); 
//  char 字符大小 1byte char* 指针 64位的机子为 8byte  ‘a’为int 4byte
    printf("sizeof s is %lu\n", sizeof(*s+0)); 
// *s为数组第一个,'h' +0 转化为 int 4byte
    printf("sizeof s is %lu\n", sizeof(*s));
 // *s 数组第一个元素 ’h‘  1byte

*/
int AssignMyString(MyString *s, char *data){
    // if(!s)InitMyString(s);
    if(s->ch)free(s->ch);
    int i = 0;
    char *c;
    for(i=0, c=data; *c; i++, c++);
    i++;
    if(!data){
        printf("Empty data string input for AssignMyString.\n");
        return 0;
    }

    s->ch = (char *)malloc(i * sizeof(data[0]));
    if(!s->ch)return 0;
    s->length = i;
    // s->length = sizeof(data) / sizeof(data[0]);
    memcpy(s->ch, data, s->length);
    return 1;
}

int MyStringLength(const MyString *s){
    return s->length;
}

int ConcatMyString(MyString *s, MyString *s1, MyString *s2){
    // if(!s)InitMyString(s);
    if(s->ch)free(s->ch);
    s->ch = (char *)malloc((s1->length + s2->length - 1) * sizeof(char));
    if(!s->ch)return 0;
    memcpy(s->ch, s1->ch, s1->length - 1);
    memcpy(s->ch + s1->length - 1, s2->ch, s2->length);
    s->length = s1->length + s2->length - 1;
    return 1;
}

// KMP 模式匹配 子串
/*
KMP 匹配的思路就是在 模式(用来匹配的子串)中 是否存在相同的子串
例如  ababcdeab   就存在 ab
[TODO]
        未完待续。。。。
*/
void _get_next(char *a, int *n, int size){
    /*
    寻址 next 数组
    对于第1个,next=0
    对于第i个,如果a[i] == a[j],匹配成功 i++, j++, next[i]=j
            如果没有匹配成功 j=next[j], 也就是说在匹配 原串的第i个时
            发生了 不匹配的情况,那么我就去找这个不匹配的 第j个 对应的
            next[j] 直到找到j==0
    e.g.
        j:  0 1 2 3 4 5   6 7
      pat:  a b a a b c   a c
  next[j]:  0 1 1 2 2 3   1 2 

  next[5] = 3
  计算next[6]的时候 pat[6] != pat[next[5] + 1]
  因此 计算 pat[6] 是否可以从 next[next[5]] 开始匹配

    */
    int i = 0;
    n[0] = -1;
    int j = -1;
    while(i < size){
        if(j == -1 || a[i] == a[j]){
            ++i;
            ++j;
            n[i] = j;
        }else{
            j = n[j];
        }
    }
}
int KMPMyString(MyString *s, MyString *s_sub, int sub_size){
    int i = -1, j = -1;
    int next[sub_size];
    _get_next(s_sub->ch, next, sub_size);

    while(i <= s->length && j <= s_sub->length){
        if(j == -1 || s->ch[i] == s_sub->ch[j]){++i; ++j;}
        else j = next[j];
    }
    if(j >= s_sub->length)return i - s_sub->length;
    else return 0;
}

int main(){
    MyString *s1, *s2, *s3;
    s1 = (MyString*)malloc(sizeof(MyString));
    s2 = (MyString*)malloc(sizeof(MyString));
    s3 = (MyString*)malloc(sizeof(MyString));

    if(InitMyString(s1))
        PrintMyString(s1);

    if(InitMyString(s2))
        PrintMyString(s2);

    if(InitMyString(s3))
        PrintMyString(s3);


    if(AssignMyString(s1, "Hello MyString!"))
        PrintMyString(s1);

    if(AssignMyString(s2, "!gnirtSyM olleH"))
        PrintMyString(s2);

    // printf("length: %d\n", MyStringLength(s1));
    if(ConcatMyString(s3, s1, s2))
        PrintMyString(s3);

    MyString *s_sub;
    s_sub = (MyString*)malloc(sizeof(MyString));
    if(InitMyString(s_sub))AssignMyString(s_sub, "llo");
    PrintMyString(s_sub);

    int pos = -1;
    pos = KMPMyString(s1, s_sub, 3);
    printf("%d\n", pos);

}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值