【发布时间】:2018-06-23 11:11:20
【问题描述】:
我正在尝试实现快速排序算法的功能版本。 我的教授让我留下这个作为签名:
public static <T, R> List<T> myQuickSort(Function<List<T>, Boolean> trivial,
Function<List<T>, T> solve, Function<List<T>, R> divide,
Function<T, List<R>> combine, List<T> input)
我创建了一个名为 Pair 的辅助类,如下所示:
public class Pair {
List<Integer> first;
List<Integer> second;
Pair(List<Integer> f, List<Integer> s) {
first = f;
second = s;
}
public static Pair div(List<Integer> input) {
int pivot = (int) input.get(0);
List<Integer> a = new ArrayList<Integer>();
List<Integer> b = new ArrayList<Integer>();
for(int i=1; i<input.size(); i++) {
if(input.get(i) < pivot) {
a.add(input.get(i));
} else {
b.add(input.get(i));
}
}
return new Pair(a, b);
}
} 我快完成了,但我无法弄清楚如何在输入数组的单个分区上递归工作。我试着这样做:
if(trivial.apply(input)) {
solve.apply(input);
} else {
output = myQuickSort(trivial, solve, divide, combine,
(List<T>) divide.apply(input).first);
output.add(input.get(0));
output.addAll(myQuickSort(trivial, solve, divide, combine,
(List<T>) divide.apply(input).second));
return output;
}
return output;
但我现在卡住了。 你们中的任何人都可以告诉我哪里错了和/或我怎样才能更好地实施我的解决方案? 这也是主要的,如果它可以帮助:
Function<List<Integer>, Boolean> trivial = (a) -> a.size()==1;
Function<List<Integer>, Pair> divide = (a) -> Pair.div(input);
Function<Pair, List<Integer>> combine =
(a) -> Stream.concat(a.first.stream(), a.second.stream()).
collect(Collectors.toList());
Function<List<Integer>, Integer> solve = (a) -> a.get(0);
ArrayList<Integer> output = myQuickSort(trivial, solve, divide, combine, input);
【问题讨论】:
-
签名不是有bug吗?如果
combine的类型是Function<R, List<T>>,对我来说会更有意义。 -
我做了一些修改,现在这是签名:“public static
List myQuickSort(Function - , Boolean> trivial, Function
- , List
> solve, Function - , R> divide, Function
> combine, List input)" 快速排序大多有效,但有一个小错误:例如,如果我给出 {70, 100, 72, 200, 57},它会返回 {52, 700, 100, 72, 200} -
让
div返回三个列表而不是一对列表会更简单、更有效:class SplitByPivot { List<T> equal, less, greater; }(不要忘记枢轴可以在输入中多次出现。 ) 我很确定这个错误是在你隐式处理枢轴作为Pair中的一个棘手的特殊情况的方式中。equal字段将让您无需技巧地表达算法。 -
等等——你说你的教授要求你保留那个签名,现在你改了?甚至您的更改签名也存在根本问题,即 调用者 决定
R是什么,而不是方法。因此,您不能假设它始终是Pair。甚至不清楚你是如何在隐含假设R是Pair的情况下编译代码的。你应该先和你的教授讨论那个奇怪的签名。
标签: java algorithm lambda functional-programming quicksort