Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Функциональные языки: общие вопросы > [Ocaml] Работа со списками


Автор: ywaw 4.7.2011, 08:24
На днях начал изучать Ocaml. Подскажите как получить значение к произвольного элемента списка, удалить произвольный
элемент списка или вставить новый элемент в  произвольную позицию. Это возможно?

Автор: Void 5.7.2011, 20:04
Возможно, только с линейной сложностью, как и полагается для односвязного списка.
Цитата(ywaw @  4.7.2011,  10:24 Найти цитируемый пост)
получить значение к произвольного элемента списка

List.nth
Цитата(ywaw @  4.7.2011,  10:24 Найти цитируемый пост)
удалить произвольный элемент списка или вставить новый элемент в  произвольную позицию.

Введём сначала вспомогательную функцию:
Код
let split_at lst n =
    let rec loop lst acc = function
        | 0 -> List.rev acc, lst
        | i -> match lst with
            | (x :: xs) -> loop xs (x :: acc) (i - 1)
            | [] -> failwith "split_at"
    in loop lst [] n

А потом:
Код
let remove_at lst n =
    let (head, tail) = split_at lst n in
    match tail with
    | [] -> failwith "remove_at"
    | x :: xs -> head @ xs

let insert_at lst n elt =
    let (head, tail) = split_at lst n in
    head @ [elt] @ tail

Автор: ywaw 6.7.2011, 05:44
Цитата(Void @ 5.7.2011,  20:04)
Возможно, только с линейной сложностью, как и полагается для односвязного списка.
Цитата(ywaw @  4.7.2011,  10:24 Найти цитируемый пост)
получить значение к произвольного элемента списка

List.nth
Цитата(ywaw @  4.7.2011,  10:24 Найти цитируемый пост)
удалить произвольный элемент списка или вставить новый элемент в  произвольную позицию.

Введём сначала вспомогательную функцию:
Код
let split_at lst n =
    let rec loop lst acc = function
        | 0 -> List.rev acc, lst
        | i -> match lst with
            | (x :: xs) -> loop xs (x :: acc) (i - 1)
            | [] -> failwith "split_at"
    in loop lst [] n

А потом:
Код
let remove_at lst n =
    let (head, tail) = split_at lst n in
    match tail with
    | [] -> failwith "remove_at"
    | x :: xs -> head @ xs

let insert_at lst n elt =
    let (head, tail) = split_at lst n in
    head @ [elt] @ tail

Спасибо за код. Буду тестировать на скорость. Вопрос не праздный, т.к. пишу логическую игру Таблут.
Ранее писал на с#, а прототипы на питоне - если интересно - загляните на страничку chess-11.narod.ru\

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)