OCaml - 返回列表,该列表在输入变量的特定索引上具有最高数字 - 列表列表
OCaml - Returning list which has the highest number on a specific index on a input variable - list of list
这里是新手!
我正在尝试构建一个程序,该程序 returns 一个在特定索引上具有最高数字的列表。我已经尝试了很多东西,这看起来是我能想到的最简单的代码。
在下面的示例中,我希望返回列表 ["2";"4";"6";"7";"8";"4"]。但是我遇到了这个错误:
文件 "blablabla.ml",第 7 行,字符 63-74:
错误:此表达式的类型为 int,但表达式应为 'a list
类型
有人可以帮忙吗?
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 我设法采用了另一种方法,但知道正在抱怨语法错误。
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 个长度为偶数的列表和 returns 一个列表,其中两个列表的最高元素按位置排列。像这样。
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"
这就是我解决这个问题的方法。注意:我省略了很多列表分支的解决方案。
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
您可以根据需要手动重写 fold_left 部分。
这里是新手! 我正在尝试构建一个程序,该程序 returns 一个在特定索引上具有最高数字的列表。我已经尝试了很多东西,这看起来是我能想到的最简单的代码。
在下面的示例中,我希望返回列表 ["2";"4";"6";"7";"8";"4"]。但是我遇到了这个错误:
文件 "blablabla.ml",第 7 行,字符 63-74: 错误:此表达式的类型为 int,但表达式应为 'a list
类型有人可以帮忙吗?
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 我设法采用了另一种方法,但知道正在抱怨语法错误。
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 个长度为偶数的列表和 returns 一个列表,其中两个列表的最高元素按位置排列。像这样。
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"
这就是我解决这个问题的方法。注意:我省略了很多列表分支的解决方案。
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
您可以根据需要手动重写 fold_left 部分。