kmp.ml 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. (*Vérifie que x appartient au mot t, il faut trouver l'entièreté de x*)
  2. let recherche_iterative (t:string) (x:string) : bool = let i = ref 0 and j = ref 0 in
  3. while !i < String.length t && !j < String.length x do
  4. if t.[!i] = x.[!j] then
  5. begin
  6. j := !j + 1;
  7. i := !i + 1
  8. end
  9. else
  10. begin
  11. j := 0;
  12. i := !i + 1
  13. end
  14. done;
  15. !j = String.length x
  16. ;;
  17. (*Trouver le bord strict d'un mot*)
  18. let border_length (t:string) : int =
  19. let i = ref 1 and j = ref 0 in
  20. while !i < String.length t && t.[!i] = t.[!j] do
  21. i := !i + 1;
  22. j := !j + 1
  23. done;
  24. !j
  25. ;;
  26. let rec est_prefixe_recursif (t:char list) (x:char list) (copy_x: char list) :bool = match (t,x) with
  27. | [],[] -> true
  28. | [],_ -> false
  29. | _,[] -> true
  30. | t1::q1,t2::q2 -> if t1 = t2 then est_prefixe_recursif q1 q2 copy_x else est_prefixe_recursif q1 copy_x copy_x
  31. ;;
  32. (*monpapimamamanmonpapamamaman*)
  33. (*Recherche d'un mot en récursif, en utilisant est_prefixe_recursif*)
  34. (*let rec recherche_recursif t x = match t with
  35. | [] -> false
  36. | t1::q1 -> if est_prefixe_recursif t1 x then true else recherche_recursif q1 x;;
  37. *)
  38. (*Renvoie le plus grand entier j tel que toute les lettres de entre vk et v(k+j-1) soient égales à wl ... w(l+j-1)*)
  39. let compare_sub_strings (v:string) (k:int) (w:string) (l:int) (s:int) : int =
  40. let j = ref 0 in
  41. while !j < s && !j < String.length v -k + (!j) && !j < String.length w -l + (!j) && v.[k + !j] = w.[l + !j] do
  42. j := !j + 1
  43. done;
  44. !j
  45. ;;
  46. compare_sub_strings "monpapimamamanmonpapamamaman" 0 "monpsdnv" 0 2;;
  47. let test_egalite_sub_strings (v:string) (k:int) (w:string) (l:int) (s:int) : bool =
  48. s = compare_sub_strings v k w l s
  49. ;;
  50. (*En testant les préfixes stricts du mot w un par un*)
  51. (*Calcule la longueur du bord d'un mot w*)
  52. (*Un bord est un préfixe et un suffixe*)
  53. let border_length (w:string) : int =
  54. let n = String.length w in
  55. let k = ref (n-1) in
  56. while !k > 0 && not (test_egalite_sub_strings w 0 w (n - !k) !k) do
  57. k := !k - 1
  58. done;
  59. !k
  60. ;;
  61. border_length "maacadamaa";;
  62. let borders_naif w : int array =
  63. let n = String.length w in
  64. let b = Array.make (n+1) (-1) in
  65. for i = 1 to n do
  66. b.(i) <- border_length (String.sub w 0 i)
  67. done;
  68. b
  69. ;;
  70. borders_naif "ababaa";;
  71. let kmp (t:string) (x:string) : bool =
  72. let deb = ref 0 and i = ref 0 and j = ref 0 in
  73. while !i < String.length t && !j < String.length x do
  74. if t.[!i] = x.[!j] then
  75. begin
  76. i := !i + 1;
  77. j := !j + 1
  78. end
  79. else
  80. begin
  81. j := 0;
  82. deb := !i + 1;
  83. i := !i + 1
  84. end
  85. done;
  86. !j = String.length x
  87. ;;