OCaml - Возвращение списка, который имеет наибольшее число по указанному c индексу во входной переменной - список списка - PullRequest
0 голосов
/ 04 апреля 2020

Новичок ie здесь! Я пытаюсь создать программу, которая возвращает список с наибольшим числом по указанному c индексу. Я пробовал так много вещей, и это выглядит самым простым кодом, который я могу найти.

В приведенном ниже примере я ожидал список ["2"; "4"; "6"; "7 ";" 8 ";" 4 "] подлежит возврату. Однако я столкнулся с этой ошибкой:

Файл "blablabla.ml", строка 7, символы 63-74: Ошибка: это выражение имеет тип int, но ожидалось выражение типа 'список

Кто-нибудь может помочь?

let a = [["1";"2";"3";"4";"5";"6"];["2";"5";"6";"1";"5";"7"];["1";"2";"3";"4";"5";"6"];["2";"4";"6";"7";"8";"4"]];;


let rec max lista i = match lista with
    | [] -> 0
    | x::xs ->
        let best_list = max xs i in
                if (int_of_string(List.nth x i)) > (int_of_string(List.nth best_list i)) then 
                    x
                else
                    best_list
;;

let result = max a 4;;

result;;

РЕДАКТИРОВАТЬ: Все еще не удалось, благодаря @ G4143 и @glennsl мне удалось go с другим подходом, но знаю, жалуется с синтаксической ошибкой.

let max l i = match l with
    | [] -> []
    | x::xs ->
            let rec compare_lists x xs i =
                if i < (List.length xs) then
                    if (List.nth x i) > (List.nth xs i) then
                        x
                    else
                        xs
                else
                    failwith "Position too large for list"
;;

Ответы [ 2 ]

0 голосов
/ 05 апреля 2020

Вот как я бы подошел к этой проблеме. Примечание: я оставил решение для ветви многих списков.

let get_max_at_pos l1 l2 pos =
  if (pos < List.length l1) && (pos < List.length l2)
  then
    if (List.nth l1 pos) < (List.nth l2 pos)
    then
      l2
    else
      l1
  else
    failwith "Position too large for list"

let get_max l pos =
  match l with
  | [] -> None
  | hd::[] -> Some hd(*should check position against hd length*)
  | hd1::hd2::[] -> Some (get_max_at_pos hd1 hd2 pos)
  | hd::tl -> (*now you have to solve the branch for many lists*)

Это лучшее и более чистое решение, поскольку оно у вас работает сейчас:

let a =
  [
    [1; 2; 3; 4; 5; 6];
    [2; 5; 6; 1; 5; 7];
    [1; 2; 3; 4; 5; 6];
    [2; 4; 6; 7; 8; 4]
  ]

let get_max_of_pos l1 l2 pos =
  if (pos < List.length l1) && (pos < List.length l2)
  then
    if (List.nth l1 pos) < (List.nth l2 pos)
    then
      l2
    else
      l1
  else
    failwith "List too short"

let get_max l pos =
  match l with
  | [] -> failwith "Empty list of list"
  | hd::tl ->
    List.fold_left (fun a d -> get_max_of_pos a d pos) hd tl

let ans = get_max a 5

Вы можете переписать сложите часть вручную, если хотите.

0 голосов
/ 04 апреля 2020

Вы пытались разбить проблему на более простые шаги? Как насчет создания функции, которая принимает 2 списка четной длины и возвращает список с наивысшим элементом в обоих списках по позиции. Как то так.

let rec get_max_at_position l1 l2 pos =
  if pos < (List.length l1)
  then
    if (List.nth l1 pos) > (List.nth l2 pos)
    then
      l1
    else
      l2
  else
    failwith "Position too large for list"
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...