我们有N组整数A1,A2,A3 ...... An。查找一个算法,该算法返回包含每个集合中一个元素的列表,其属性是列表中最大元素和最小元素之间的差异最小
示例:
IN: A1 = [0,4,9], A2 = [2,6,11], A3 = [3,8,13], A4 = [7,12]
OUT: [9,6,8,7]
我对这个练习有所了解,首先我们需要对一个列表中的所有元素进行排序(每个元素都需要分配给它的集合),所以使用该输入我们得到这个:
[[0,1],[2,2],[3,3],[4,1],[6,2],[7,4],[8,3],[9,1],[11,2],[12,4],[13,3]]
稍后我们创建所有可能的列表并找到这个与最小元素和最大元素之间的差异,并返回正确的列表如下:[9,6,8,7]
我是ocaml的新手所以我对编码这些东西有一些疑问:
抱歉我的英语不好,希望你能理解我想表达的意思。
答案 0 :(得分:1)
这个答案是关于算法部分的,而不是OCaml代码。
您可能希望首先实现您提出的解决方案,以便使用一个有效的解决方案,并将其结果与改进的解决方案进行比较,我现在写一下这个解决方案。
这是关于如何改进算法部分的提示。考虑排序所有集合,而不仅仅是第一个集合。现在,所有集合中所有最小元素的列表都是输出的候选者。 要考虑其他候选输出,你怎么能从那里移动?
答案 1 :(得分:0)
我只是回答你的问题,而不是评论你提出的解决方案。 (但我认为你必须在完成之前再多做一点。)
您可以编写一个带有列表列表的函数。这几乎是一样的 允许任意数量的参数。但实际上它只有一个论点 (与OCaml中的所有功能一样)。
您可以使用内置类型,例如列表和元组,您不需要创建或 明确声明它们。
这是一个示例函数,它采用列表列表并将它们组合成一个很长的列表:
let rec concat lists =
match lists with
| [] -> []
| head :: tail -> head @ concat tail
答案 2 :(得分:0)
以下是您在问题中描述的例程,以帮助您入门。注意 我没有注意效率。还添加了反向应用(管道) 操作员为了清楚起见。
let test_set = [[0;4;9];[2;6;11];[3;8;13]; [7;12]]
let (|>) g f = f g
let linearize sets =
let open List in sets
|> mapi (fun i e -> e |> map (fun x -> (x, i+1) ))
|> flatten |> sort (fun (e1,_) (e2, _) -> compare e1 e2)
let sorted = linearize test_set
答案 3 :(得分:0)
您的方法听起来效率不高,n
个数量的集合,每个集合都有x_i
个元素,您的排序列表将包含(n * x_i)
个元素,以及子列表的数量你可以生成:(n * x_i)!
(factorial)
我想提出一个不同的方法,但你必须弄清楚细节:
使用它的设置标识符标记(索引)每个元素(就像你已经完成的那样)。
单独对每个集进行排序。
与您想要的结果完全相反!
优化!
我希望你能自己弄清楚步骤3,4:...