Как обрабатывать вложенные выражения соответствия - PullRequest
0 голосов
/ 12 января 2019

Я реализую метод в Ocaml, чтобы выполнить сжатие данных кодирования по длине прогона списка случайного типа 'a. Последовательные элементы, которые совпадают в списке, сжимаются в тип, определенный в начале предоставленного кода. Мой предоставленный код не работает. Одна из причин, по которой я думаю, что это не сработает, заключается в том, что если вы посмотрите на новую строку между большим патроном первых вариантов совпадения, совпадающие наблюдения после новой строки должны принадлежать верхним совпадениям. Тем не менее, компилятор в Learn Ocaml не может распознать это. Он автоматически сгруппировал оставшиеся сопоставленные операторы (которые должны были быть для первого совпадения) с вложенным оператором сопоставления.

Это один из акцизов на учебном сайте Ocaml (Вопрос 13): «Реализуйте так называемый метод сжатия данных кодирования по длине прогона напрямую. Т.е. не создавайте явно списки, содержащие дубликаты, как в задаче« Упакуйте последовательные дубликаты элементов списка в списки », а только подсчитайте их. Как в проблеме» Изменено кодирование длин серий ", упростите список результатов, заменив одноэлементные списки (1 X) на X."

type 'a rle =
  | One of 'a
  | Many of int * 'a;;

let encodeDirect (l: 'a list)=
  let rec helper current acc ll=
    match ll with
    |[] -> current::acc
    |[a]-> match current with
      |None -> (Some(One a))::acc 
      |Some(One q) -> (Some(Many(2,q)))::acc
      |Some(Many(t,y)) -> (Some(Many(t+1,y)))::acc 

      |a::(m::ls as e) -> if a=m then match current with 
      |None -> helper (Some(One a)) acc e
      |Some(One q) -> helper (Some(Many(2,q)))  acc e
      |Some(Many(t,y)) -> helper (Some(Many(t+1,y))) acc e
      else match current with 
        |None -> helper None (Some(One a)::acc) e
        |Some(One q) -> helper None (Some(Many(2,q))::acc)  e
        |Some(Many(t,y)) ->helper None (Some(Many(t+1,y))::acc) e
  in helper None [] l

Вот пример того, как это должно работать: закодировать ["a"; "a"; "a"; "a"; "b"; "c"; "c"; "a"; "a"; "d"; "e"; "e"; "е"; "е"] ;; -: string rle list = [Многие (4, «а»); Один "б"; Многие (2, "с"); Многие (2, «а»); Один D"; Многие (4, «е»)]

1 Ответ

0 голосов
/ 12 января 2019

Я часто сталкиваюсь с этой же проблемой с вложенным match. Вы можете решить эту проблему, заключив в скобки внутреннее совпадение.

type 'a rle =
| One of 'a
| Many of int * 'a;;

let rec helper current acc ll=
  match ll with
  |[] -> current::acc
  |[a]->
    (match current with
    |None -> (Some(One a))::acc 
    |Some(One q) -> (Some(Many(2,q)))::acc
    |Some(Many(t,y)) -> (Some(Many(t+1,y)))::acc 
    )
  |a::(m::ls as e) ->
    if a=m then
      match current with 
      |None -> helper (Some(One a)) acc e
      |Some(One q) -> helper (Some(Many(2,q)))  acc e
      |Some(Many(t,y)) -> helper (Some(Many(t+1,y))) acc e
    else
      match current with 
      |None -> helper None (Some(One a)::acc) e
      |Some(One q) -> helper None (Some(Many(2,q))::acc)  e
      |Some(Many(t,y)) ->helper None (Some(Many(t+1,y))::acc) e
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...