#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);
}
C string
最新推荐文章于 2020-07-14 13:29:11 发布