итерация для построения функции между двумя массивами в ocamlre - PullRequest
2 голосов
/ 08 марта 2011

У меня есть вопрос относительно построения такой функции.

Здесь у меня есть два списка, оба имеют одинаковую длину (скажем, длина n, и мне нужен случай, который выполняет это требование:

list1.(0) -> list2.(0)
list1.(1) -> list2.(1)
...
list1.(n-1) -> list2.(n-1)

Как это сделать? Должен ли я сделать итерацию внутри функции (и как)? Или добавление двух функций (и как)? Должен быть хитрый способ ответить на подобные вещи.

Извините, должен ответить на этот вопрос сам. Я просто нахожу, что это на самом деле довольно легко. Я легко могу создать функцию f, которая написана nlucaroni гораздо короче.

let rec f domain range x =
match (List.hd domain) = x with
    | true -> (List.hd range)
    | false -> f (List.tl domain) (List.tl range) x;;

Ответы [ 2 ]

2 голосов
/ 09 марта 2011

Вы знаете выражение if, сохраните выражение match для списков и других структур данных, чтобы вам не приходилось использовать небезопасные функции List.hd и List.tl!Например, ваш код переписывается в (ETA: упс, забыл рекурсивный вызов):

let rec f domain range x =
match domain, range with
  | k::_, v::_ when k = x -> v
  | _::ks, _::vs -> f ks vs x
  | _ -> raise Not_found;;

Другой подход заключается в использовании стандартных функций библиотеки:

let f domain range =
  let map = List.combine domain range in
  fun x -> List.assoc x map;;
2 голосов
/ 08 марта 2011

Насколько я понимаю, у вас есть два массива. Один определяет область функции, другой диапазон. И вы хотите написать функцию ocaml, которая представляет эту функцию. Здесь я предполагаю, что функция биективна. Недостающая часть, meat, - это функция для поиска индекса элемента в массиве. В духе List.find я решил передать функцию для определения этого сравнения.

let find_index p array =
    let rec find_index idx =
        if idx = (Array.length array) then raise Not_found
        else if (p array.(idx)) then idx
        else find_index (idx+1)
    in
    find_index 0

Отсюда создание функции тривиально, и наоборот,

let f domain range x = range.(find_index (fun y -> 0 = compare x y) domain)
let f' domain range y = domain.(find_index (fun x -> 0 = compare x y) range)

Есть лучший способ, если вы планируете использовать это не только для небольшого набора данных. Действительно, это плохая реализация для Map - у этого есть O (n) поиск, в то время как у карты будет O (log (N)). Я понимаю, что вас могут не интересовать альтернативы, поэтому я оставлю свои рекомендации на этом.

...