| ... | ... | @@ -850,29 +850,38 @@ pub fn indexOfAnyPos(comptime T: type, slice: []const T, start_index: usize, val |
| 850 | 850 | pub fn indexOf(comptime T: type, haystack: []const T, needle: []const T) ?usize { |
| 851 | 851 | return indexOfPos(T, haystack, 0, needle); |
| 852 | 852 | } |
| 853 | | |
| 854 | 853 | /// Find the index in a slice of a sub-slice, searching from the end backwards. |
| 855 | 854 | /// To start looking at a different index, slice the haystack first. |
| 856 | | /// TODO is there even a better algorithm for this? |
| 855 | // Reverse boyer-moore-horspool algorithm |
| 857 | 856 | pub fn lastIndexOf(comptime T: type, haystack: []const T, needle: []const T) ?usize { |
| 858 | | if (needle.len > haystack.len) return null; |
| 859 | | |
| 860 | | var i: usize = haystack.len - needle.len; |
| 861 | | while (true) : (i -= 1) { |
| 862 | | if (mem.eql(T, haystack[i .. i + needle.len], needle)) return i; |
| 863 | | if (i == 0) return null; |
| 857 | if (needle.len > haystack.len or needle.len == 0) return null; |
| 858 | |
| 859 | var i: usize = needle.len - 1; |
| 860 | while (i < haystack.len) { |
| 861 | const reverseIndex = haystack.len - i - 1; |
| 862 | if (indexOfScalar(T, needle, haystack[reverseIndex])) |index| { |
| 863 | const haystackIndex = reverseIndex - index; |
| 864 | if (haystackIndex + needle.len <= haystack.len and mem.eql(T, haystack[haystackIndex .. haystackIndex + needle.len], needle)) return haystackIndex; |
| 865 | } |
| 866 | i += needle.len; |
| 864 | 867 | } |
| 868 | |
| 869 | return null; |
| 865 | 870 | } |
| 866 | 871 | |
| 867 | | // TODO boyer-moore algorithm |
| 872 | // Boyer-moore-horspool algorithm |
| 868 | 873 | pub fn indexOfPos(comptime T: type, haystack: []const T, start_index: usize, needle: []const T) ?usize { |
| 869 | | if (needle.len > haystack.len) return null; |
| 874 | if (needle.len > haystack.len or needle.len == 0) return null; |
| 870 | 875 | |
| 871 | | var i: usize = start_index; |
| 872 | | const end = haystack.len - needle.len; |
| 873 | | while (i <= end) : (i += 1) { |
| 874 | | if (eql(T, haystack[i .. i + needle.len], needle)) return i; |
| 876 | var i: usize = start_index + needle.len - 1; |
| 877 | while (i < haystack.len) { |
| 878 | if (lastIndexOfScalar(T, needle, haystack[i])) |index| { |
| 879 | const haystackIndex = i - index; |
| 880 | if (haystackIndex + needle.len <= haystack.len and mem.eql(T, haystack[haystackIndex .. haystackIndex + needle.len], needle)) return haystackIndex; |
| 881 | } |
| 882 | i += needle.len; |
| 875 | 883 | } |
| 884 | |
| 876 | 885 | return null; |
| 877 | 886 | } |
| 878 | 887 | |