feat: string find
This commit is contained in:
@@ -239,7 +239,7 @@ char *mcl_string_cstr(mcl_string_s *string) {
|
||||
tl_buffer_s *tb = (tl_buffer_s *)tss_get(buffer_key);
|
||||
if (tb == NULL) {
|
||||
/* Not found, make a new one */
|
||||
tb = malloc(sizeof(*tb));
|
||||
tb = malloc(sizeof(tl_buffer_s));
|
||||
if (tb == NULL) {
|
||||
mtx_unlock(&string->lock);
|
||||
|
||||
@@ -352,3 +352,57 @@ void mcl_string_tolower(mcl_string_s *string) {
|
||||
|
||||
mtx_unlock(&string->lock);
|
||||
}
|
||||
|
||||
/* Build Longest Prefix Suffix array */
|
||||
static void build_lsp(int *lps, const char *substring, size_t sub_len) {
|
||||
int len = 0;
|
||||
int i = 1;
|
||||
|
||||
while (i < sub_len) {
|
||||
if (substring[i] == substring[len]) {
|
||||
lps[i++] = ++len;
|
||||
} else {
|
||||
if (len != 0) {
|
||||
len = lps[len - 1];
|
||||
} else {
|
||||
lps[i++] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int mcl_string_find(mcl_string_s *string, const char *substring) {
|
||||
if (string == NULL || substring == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Handle empty case */
|
||||
if (strcmp(string->data, "") == 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
size_t sub_len = strlen(substring);
|
||||
int lps[sub_len];
|
||||
memset(lps, 0, sizeof(lps));
|
||||
build_lsp(lps, substring, sub_len);
|
||||
|
||||
size_t i = 0; /* string iterator */
|
||||
size_t j = 0; /* substring iterator */
|
||||
while (i < string->size) {
|
||||
if (string->data[i] == substring[j]) {
|
||||
i++;
|
||||
j++;
|
||||
if (j == sub_len) {
|
||||
return i - j;
|
||||
}
|
||||
} else {
|
||||
if (j != 0) {
|
||||
j = lps[j - 1];
|
||||
} else {
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -111,8 +111,6 @@ void mcl_string_tolower(mcl_string_s *string);
|
||||
* @param string String where to search.
|
||||
* @param substring Substring to search.
|
||||
* @return Index of the first occurrence, -1 on failure.
|
||||
*
|
||||
* @note TODO
|
||||
*/
|
||||
int mcl_string_find(mcl_string_s *string, const char *substring);
|
||||
|
||||
|
||||
@@ -28,6 +28,10 @@ void test_str2(void) {
|
||||
assert(mcl_string_length(s1) == 50);
|
||||
assert(mcl_string_capacity(s1) == 64);
|
||||
|
||||
/* Find substring in string */
|
||||
int pos = mcl_string_find(s1, "is");
|
||||
assert(pos == 2);
|
||||
|
||||
mcl_string_free(s1);
|
||||
mcl_string_free(s2);
|
||||
mcl_string_free(extend_me);
|
||||
|
||||
Reference in New Issue
Block a user