所以我正在阅读Java,我遇到了一个例子。我不知道它是如何工作的。您将在下面看到sortByTime()
课程中的方法ConsLoRunner
。我的问题是它是如何输出一些东西的,它不会一遍又一遍地递归那种方法,而且永远不会达到insertByTime(this.first)
方法?
旁注:示例是马拉松的跑步者,并根据他们的时间(最快到最慢)对他们进行排序。
class Runner {
String name;
int age;
int bib;
boolean isMale;
int pos;
int time;
Runner(String name, int age, int bib, boolean isMale, int pos, int time) {
this.name = name;
this.age = age;
this.bib = bib;
this.isMale = isMale;
this.pos = pos;
this.time = time;
}
public boolean finishesBefore(Runner r) {
return this.time < r.time;
}
}
interface ILoRunner {
ILoRunner sortByTime();
ILoRunner insertByTime(Runner r);
}
class MtLoRunner implements ILoRunner {
public ILoRunner sortByTime() {
return this;
}
public ILoRunner insertByTime(Runner r) {
return new ConsLoRunner(r, this);
}
}
class ConsLoRunner implements ILoRunner {
Runner first;
ILoRunner rest;
ConsLoRunner(Runner first, ILoRunner rest) {
this.first = first;
this.rest = rest;
}
/*******HOW DOES IT DO THIS?????**********/
public ILoRunner sortByTime() {
return this.rest.sortByTime().insertByTime(this.first);
}
public ILoRunner insertByTime(Runner r) {
if (this.first.finishesBefore(r)) {
return new ConsLoRunner(this.first, this.rest.insertByTime(r));
}
else {
return new ConsLoRunner(r, this);
}
}
}
class ExamplesRunners {
MtLoRunner empty = new MtLoRunner();
Runner tim = new Runner ("Tim", 1, 2, true, 5, 6);
Runner bob = new Runner ("Bob", 5, 6, true, 9, 50);
Runner jim = new Runner ("Jim", 5, 6, true, 10, 40);
ILoRunner list1 = new ConsLoRunner(this.tim, new ConsLoRunner(this.bob, new ConsLoRunner(this.jim, this.empty)));
boolean testSort(Tester t) {
return t.checkExpect(this.list1.sortByTime(), new ConsLoRunner(this.tim, new ConsLoRunner(this.jim, new ConsLoRunner(this.bob, this.empty))));
}
}
答案 0 :(得分:0)
不会一遍又一遍地递归那种方法
不,它根本没有使用递归,因为它在类成员rest
上调用方法:
返回此。休息 .sortByTime()。insertByTime(this.first);
答案 1 :(得分:0)
我不知道它是如何运作的。
我会试着回答这个问题。
您正在查看List Data Structure的(非常令人困惑的)Java版本,该版本通常位于LISP等语言中。
我们的案例中的“列表”可以递归定义。它是:
()
或nil
或(first, rest)
正如您所看到的,您可以清楚地将Java类映射到这些概念:
ILoRunner -> An abstract List, the root type
MtLoRunner -> An empty list: () or nil
ConsLoRunner -> A non-empty list: (first, rest)
线索位于名称ConsLoRunner
的开头。在LISP中,cons
是一个“构造函数”,它创建一个包含另外两个对象的对象。 cons
通常用于创建列表。但它也可以用于创建非列表结构。对不起,我离题了。
将您的示例重写为列表表示,\ n \ n list1
的列表看起来大致如此(为简单起见省略其他字段):
(Tim <-- first: Tim, rest: (Bob ...)
(Bob <-- first: Bob, rest: (Jim ())
(Jim ()))) <-- first: Jim, rest: () // rest of the list is empty, no more elements.
ExamplesRunners
正在做什么。
现在是令人困惑的部分。代码按照完成时间对跑步者进行排序。这个想法非常简单,对这样的列表进行排序,我们
这是ConsLoRunner.sortByTime
正在做的事情。但请注意,它正在返回一个新的排序列表。 因此原始列表永远不会更改。
将元素x
插入到排序列表中也很简单:
x
与列表的第一个元素进行比较x
较小,请在整个列表x
x
插入列表的其余部分请记住,插入是通过创建一个具有适当元素顺序的新cons
对象来完成的。同样,保留原始列表。
IMO,如果代码是针对实际的列表界面编写的,那么代码将更容易阅读,而不是与内部表示和新列表的构造混合在一起。
// The list interface
interface List<T extends Comparable<T>> {
boolean isEmpty();
T first();
List<T> rest();
}
// Instances of this class represents an empty list: ()
class Empty<T extends Comparable<T>> implements List<T> {
@Override
public boolean isEmpty() {
return true;
}
@Override
public T first() {
return null;
}
@Override
public List<T> rest() {
return null;
}
@Override
public String toString() {
return "()";
}
}
// A non-empty list, composed of the first element and the rest.
class Cons<T extends Comparable<T>> implements List<T> {
private final T first;
private final List<T> rest;
public Cons(T first, List<T> rest) {
this.first = first;
this.rest = rest;
}
@Override
public boolean isEmpty() {
return false;
}
@Override
public T first() {
return first;
}
@Override
public List<T> rest() {
return rest;
}
@Override
public String toString() {
return "(" + first +", " + rest + ")";
}
}
public class Lisp {
// Creates and returns a sorted list from the given list
// The original list is never changed.
public static <T extends Comparable<T>> List<T> sort(List<T> list) {
if (list.isEmpty()) {
// Empty lists are already sorted.
return list;
} else {
// We first sort the rest of the list
List<T> sortedRest = sort(list.rest());
// Then insert the first element into the sorted list
return insert(list.first(), sortedRest);
}
}
// Creates and returns a sorted list with x inserted into a proper position in the already sorted list
private static <T extends Comparable<T>> List<T> insert(T x, List<T> list) {
if (list.isEmpty() || x.compareTo(list.first()) < 0) {
return new Cons<>(x, list);
} else {
// Recursive call return a sorted list containing x
return new Cons<>(list.first(),
insert(x, list.rest()));
}
}
public static void main(String [] args) {
List<Integer> alist = new Cons<>(7, new Cons<>(1, new Cons<>(4, new Empty<>())));
System.out.println("Sorted: " + sort(alist));
System.out.println("Original: " + alist);
}
}
<强>输出强>
Sorted: (1, (4, (7, ())))
Original: (7, (1, (4, ())))