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);
|
tl_buffer_s *tb = (tl_buffer_s *)tss_get(buffer_key);
|
||||||
if (tb == NULL) {
|
if (tb == NULL) {
|
||||||
/* Not found, make a new one */
|
/* Not found, make a new one */
|
||||||
tb = malloc(sizeof(*tb));
|
tb = malloc(sizeof(tl_buffer_s));
|
||||||
if (tb == NULL) {
|
if (tb == NULL) {
|
||||||
mtx_unlock(&string->lock);
|
mtx_unlock(&string->lock);
|
||||||
|
|
||||||
@@ -352,3 +352,57 @@ void mcl_string_tolower(mcl_string_s *string) {
|
|||||||
|
|
||||||
mtx_unlock(&string->lock);
|
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 string String where to search.
|
||||||
* @param substring Substring to search.
|
* @param substring Substring to search.
|
||||||
* @return Index of the first occurrence, -1 on failure.
|
* @return Index of the first occurrence, -1 on failure.
|
||||||
*
|
|
||||||
* @note TODO
|
|
||||||
*/
|
*/
|
||||||
int mcl_string_find(mcl_string_s *string, const char *substring);
|
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_length(s1) == 50);
|
||||||
assert(mcl_string_capacity(s1) == 64);
|
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(s1);
|
||||||
mcl_string_free(s2);
|
mcl_string_free(s2);
|
||||||
mcl_string_free(extend_me);
|
mcl_string_free(extend_me);
|
||||||
|
|||||||
Reference in New Issue
Block a user