1

Write with OCaml Longest Common Sottosequence (Deep Search)

Consider a finite set S of strings and an integer K. Determine, if it exists, a string x of length greater than or equal to K subsequence of each string s∈S. The problem is solved by using an in-depth search.

I tried it with two strings without k, it works! this bellow is my code:

(*trasfmorm string in list char*)
let explode s =
  let rec exp i l =
    if i < 0 then l 
    else exp (i - 1) (s.[i] :: l) 
  in
  exp (String.length s - 1) []
 
(*print list of strings*) 
let rec print_list_strings = function 
  | [] -> ()
  | e::l -> 
    print_string e; 
    print_string "\n"; 
    print_list_strings l     
 
(*print list of char*) 
let rec print_list_char = function 
  | [] -> print_string "\n"
  | e::l -> 
    print_char e; 
    print_string " "; 
    print_list_char l                      
                            
(*between the lists tell me which one is longer*)
let longest xs ys = 
  if List.length xs > List.length ys then xs 
  else ys

(*lcs deep*)
let rec lcs a b = 
  match a, b with
  | [], _ | _, [] -> []
  | x::xs, y::ys ->
    if x = y then
      x :: lcs xs ys
    else 
      longest (lcs a ys) (lcs xs b)

(* On input: "ABCBDAB", "ABCBDAB"

The LCS returned is "BDAB" *)

let a = "ABCBDAB";; let b = "ABCBDAB";;

let a = explode a;; let b = explode b;;

print_list_char (lcs a b);;

But when I start to find the solution for s strings it seems impossible. For the moment i write the code bellow:

(* function return n-elemt of a list *)
exception Nth

let rec nth n lista = 
  match (n, lista) with
  | (_, [])   -> raise Nth
  | (0, t::_) -> t
  | (n, t::c) -> nth (n-1) c;;

(* functione given input list of char output string *)
let rendi_stringa s = 
  String.of_seq (List.to_seq s)

(* delete first n-element of a string *)
let rec drop n = function
  | [] -> []
  | x::xs -> 
    if n <= 0 then x::xs
    else drop (n-1) xs ;;

(*string into a char list*)
let explode s =
  let rec exp i   l =
    if i < 0 then l 
    else exp (i - 1) (s.[i] :: l) 
  in
  exp (String.length s - 1) []

(*read k-elemt and return a list*)
let rec leggi k =
  if k=0 then []
  else 
    let x = read_line() in 
    (x) :: leggi (k-1)
            
(*print element list*)
let rec print_list = function 
  | [] -> ()
  | e::l -> 
    print_string e; 
    print_string "\n"; 
    print_list l

(*funzione lista string esplosa--> lista di lista*)
let rec explode_list n lista = 
  if n = 0 then []
  else 
    let x = List.hd lista in 
    [(explode x)] @ explode_list (n-1) (List.tl lista)

(*n-esima raw e m-column of matrix*)
let pos tabla n m =
  let lista = (List.nth tabla n) in 
  List.nth lista m;;

let subset tabella n =
  let rec aux solution tot = function
    | [] -> 
      if tot > 0 then raise NotFound
      else solution
    | x::rest -> 
      print_string x; 
      print_string "\n"; 
      aux (x::solution) (tot-1) rest
  in 
  aux [] n tabella
                                   
let subset tabella n =
  let rec aux solution = function
    | [] -> 
      if List.length solution < n then raise NotFound
      else solution
    | x::rest -> nuova_funzione (explode x) rest n
  in 
  aux [] n tabella

let nuova_funzione lista_char lista_string n = function
  | _, [] -> print_string "non posso piu fare niente, stringhe finite\n"
  | [], _ -> print_string "ho finito confronto con la lista\n"
  | [] , x::lt -> 
    if (lcs lista_char (explode x)) > n then 
    else 

let longest xs ys = 
  if List.length xs > List.length ys then xs 
  else ys

(*lcs profonda*)
let rec lcs a b = 
  match a, b with
  | [], _ | _, [] -> []
  | x::xs, y::ys ->
    if x = y then
      x :: lcs xs ys
    else 
      longest (lcs a ys) (lcs xs b)
                                    
(**)
(*let rec lcs stringhe num = function 
  | [] 
  | List.length stringhe < num -> []
  | *)
                                
(*------------------------main--------------*)

print_string "how many strings?\n";;
let m = read_int();;
print_string "please write your strings\n";;
let lista = leggi m;;
print_string "strings wrote\n";;
print_list lista;;

explode (nth 0 c);;

let a = "ABCBDAB";;
let a = explode a;;
let b = "BDCABA";;
let b = explode b;;
let c = "BADACB";;
let c = explode c;;

My idea was to use Backtracking, but i'm stuck with logical idea, I have no idea to implement it even with pseudocode!

Any idea or advise?

Chris
  • 26,361
  • 5
  • 21
  • 42
  • Why is `print_list_char` not just `let print_list_char lst = List.iter (Printf.printf "%c ") lst; print_newline ()`? – Chris Nov 12 '22 at 23:28
  • 1
    Also, `longest` can be: `let longest xs ys = if List.compare_lengths xs ys = 1 then xs else ys` – Chris Nov 12 '22 at 23:32
  • `nuova_funzione` appears to be missing some code after `else`. – Chris Nov 13 '22 at 00:18
  • @Chris for `print_list_char` and `longest` i learned it from my lessons. nuova_funzione was an idea where given a list of strings i will take the first, i explode it and i will get, a list of char and a list of strings, without the first. After that i start to take first char, explode the first strings of the list compare it, step by step that should compare with other strings and if the LCS was higher than n so return the result, otherwise print no LCS But when i start implement it i thought, it is not backtracking and is not a deep research. – Belhadj Terbagou Nov 13 '22 at 23:32

0 Answers0