substring.h 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. #include <stddef.h>
  2. #include <misc/debug.h>
  3. static void build_substring_backtrack_table (const char *str, size_t len, size_t *out_table)
  4. {
  5. ASSERT(len > 0)
  6. size_t x = 0;
  7. for (size_t i = 1; i < len; i++) {
  8. out_table[i] = x;
  9. while (x > 0 && str[i] != str[x]) {
  10. x = out_table[x];
  11. }
  12. if (str[i] == str[x]) {
  13. x++;
  14. }
  15. }
  16. }
  17. static int find_substring (const char *text, size_t text_len, const char *word, size_t word_len, const size_t *table, size_t *out_position)
  18. {
  19. ASSERT(word_len > 0)
  20. size_t x = 0;
  21. for (size_t i = 0; i < text_len; i++) {
  22. while (x > 0 && text[i] != word[x]) {
  23. x = table[x];
  24. }
  25. if (text[i] == word[x]) {
  26. if (x + 1 == word_len) {
  27. *out_position = i - x;
  28. return 1;
  29. }
  30. x++;
  31. }
  32. }
  33. return 0;
  34. }
  35. static void build_substring_backtrack_table_reverse (const char *str, size_t len, size_t *out_table)
  36. {
  37. ASSERT(len > 0)
  38. size_t x = 0;
  39. for (size_t i = 1; i < len; i++) {
  40. out_table[i] = x;
  41. while (x > 0 && str[len - 1 - i] != str[len - 1 - x]) {
  42. x = out_table[x];
  43. }
  44. if (str[len - 1 - i] == str[len - 1 - x]) {
  45. x++;
  46. }
  47. }
  48. }
  49. static int find_substring_reverse (const char *text, size_t text_len, const char *word, size_t word_len, const size_t *table, size_t *out_position)
  50. {
  51. ASSERT(word_len > 0)
  52. size_t x = 0;
  53. for (size_t i = 0; i < text_len; i++) {
  54. while (x > 0 && text[text_len - 1 - i] != word[word_len - 1 - x]) {
  55. x = table[x];
  56. }
  57. if (text[text_len - 1 - i] == word[word_len - 1 - x]) {
  58. if (x + 1 == word_len) {
  59. *out_position = (text_len - 1 - i);
  60. return 1;
  61. }
  62. x++;
  63. }
  64. }
  65. return 0;
  66. }