Skip to content

Commit b49635b

Browse files
committed
implemented index function and compute_LPS function
1 parent 88adb9f commit b49635b

File tree

2 files changed

+85
-6
lines changed

2 files changed

+85
-6
lines changed

src/Makefile.manual

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,8 @@ stdlib_stats_distribution_PRNG.o: \
126126
stdlib_kinds.o \
127127
stdlib_error.o
128128
stdlib_string_type.o: stdlib_ascii.o \
129-
stdlib_kinds.o
129+
stdlib_kinds.o
130130
stdlib_strings.o: stdlib_ascii.o \
131-
stdlib_string_type.o
131+
stdlib_string_type.o \
132+
stdlib_optval
132133
stdlib_math.o: stdlib_kinds.o

src/stdlib_strings.f90

Lines changed: 82 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,15 @@
44
!>
55
!> The specification of this module is available [here](../page/specs/stdlib_strings.html).
66
module stdlib_strings
7-
use stdlib_ascii, only : whitespace
8-
use stdlib_string_type, only : string_type, char, verify
7+
use stdlib_ascii, only: whitespace
8+
use stdlib_string_type, only: string_type, char, verify
9+
use stdlib_optval, only: optval
910
implicit none
10-
private
11+
private :: compute_LPS
1112

1213
public :: strip, chomp
1314
public :: starts_with, ends_with
14-
public :: slice
15+
public :: slice, find
1516

1617

1718
!> Remove leading and trailing whitespace characters.
@@ -67,6 +68,15 @@ module stdlib_strings
6768
module procedure :: slice_char
6869
end interface slice
6970

71+
!> Finds the starting index of substring 'pattern' in the input 'string'
72+
!>
73+
!> Version: experimental
74+
interface find
75+
module procedure :: find_string_string
76+
module procedure :: find_string_char
77+
module procedure :: find_char_string
78+
module procedure :: find_char_char
79+
end interface find
7080

7181
contains
7282

@@ -366,5 +376,73 @@ pure function slice_char(string, first, last, stride) result(sliced_string)
366376
end do
367377
end function slice_char
368378

379+
pure function find_char_char(string, pattern, occurrence, consider_overlapping) result(res)
380+
character(len=*), intent(in) :: string
381+
character(len=*), intent(in) :: pattern
382+
integer, intent(in), optional :: occurrence
383+
logical, intent(in), optional :: consider_overlapping
384+
integer :: LPS_array(len(pattern))
385+
integer :: res, i, j, length_string, length_pattern, occurrence_
386+
logical :: consider_overlapping_
387+
388+
consider_overlapping_ = optval(consider_overlapping, .false.)
389+
occurrence_ = max(1, optval(occurrence, 1))
390+
res = -1
391+
length_string = len(string)
392+
length_pattern = len(pattern)
393+
394+
if (length_pattern > 0 .and. length_pattern <= length_string) then
395+
LPS_array = compute_LPS(pattern)
396+
397+
i = 1
398+
j = 1
399+
do while(i <= length_string)
400+
if (string(i:i) == pattern(j:j)) then
401+
if (j == length_pattern) then
402+
occurrence_ = occurrence_ - 1
403+
if (occurrence_ == 0) then
404+
res = i - length_pattern + 1
405+
exit
406+
else if (consider_overlapping_) then
407+
i = i - length_pattern + 1
408+
end if
409+
j = 0
410+
end if
411+
i = i + 1
412+
j = j + 1
413+
else if (j > 1) then
414+
j = LPS_array(j - 1) + 1
415+
else
416+
i = i + 1
417+
end if
418+
end do
419+
end if
420+
421+
end function find_char_char
422+
423+
pure function compute_LPS(string) result(LPS_array)
424+
character(len=*), intent(in) :: string
425+
integer :: LPS_array(len(string))
426+
integer :: i, j, length_string
427+
428+
length_string = len(string)
429+
LPS_array = 0
430+
431+
i = 2
432+
j = 1
433+
do while (i <= length_string)
434+
if (string(j:j) == string(i:i)) then
435+
LPS_array(i) = j
436+
i = i + 1
437+
j = j + 1
438+
else if (j > 1) then
439+
j = LPS_array(j - 1) + 1
440+
else
441+
i = i + 1
442+
end if
443+
end do
444+
445+
end function compute_LPS
446+
369447

370448
end module stdlib_strings

0 commit comments

Comments
 (0)