我有一个任务在Java中实现以下方法:如果列表S是列表L的子列表,则SubList(S,L)返回true。
当我将列表作为递归关系中的抽象对象处理时,我需要使用以下表示法。给定一个列表L,我们写L = [H | R],其中H是列表的头部,R是列表的其余部分。对于空列表L,我们写L = []。例如,如果L = [1,2,3,4,5],则H = 1,并且R = [2,3,4,5]。
因此我的任务是:
a)使用上面的列表符号为SubList(S,L)提供递归关系。
b)使用递归关系在Java中实现递归算法。
现在被困在这项任务上一天半,但仍然无法做到这一点。感谢,如果有人能帮我解决这个问题。
这是我用过的java代码。
class SLLNode {
public Object info; // This is the data
public SLLNode next; // this is the address of the next node
public SLLNode() { // Here's how we construct an empty list.
next = null;
}
public SLLNode(Object el) {
info = el; next = null;
}
public SLLNode(Object el, SLLNode ptr) {
info = el; next = ptr;
}
}
class SLList {
protected SLLNode head = null;
public SLList() {
}
public void setToNull() {
head = null;
}
public boolean isEmpty() {
return head == null;
}
public Object first() {
return head.info;
}
public SLLNode head() {
return head;
}
public void printAll() {
for (SLLNode tmp = head; tmp != null; tmp = tmp.next)
System.out.print(tmp.info.toString());
}
public void add(Object el) {
head= new SLLNode(el,head);
}
public Object find(Object el) {
SLLNode tmp = head;
for ( ; tmp != null && !el.equals(tmp.info); tmp = tmp.next);
if (tmp == null)
return null;
else return tmp.info;
}
public boolean member(Object el) {
SLLNode tmp = head;
for ( ; tmp != null && !el.equals(tmp.info); tmp = tmp.next);
if (tmp == null)
return false;
else return true;
}
public Object deleteHead() { // remove the head and return its info;
Object el = head.info;
head = head.next;
return el;
}
public void delete(Object el) { // find and remove el;
if (head != null) // if non-empty list;
if (el.equals(head.info)) // if head needs to be removed;
head = head.next;
else {
SLLNode pred = head, tmp = head.next;
for ( ; tmp != null && !(tmp.info.equals(el));
pred = pred.next, tmp = tmp.next);
if (tmp != null) // if found
pred.next = tmp.next;
}
}
}
答案 0 :(得分:0)
SubList([], L) = true (1)
SubList(H|[], H|*) = true (2)
SubList(H|[], []) = false (3)
SubList(SH|[], H|R) = SubList(SH|[], H|[]) OR SubList(SH|[], R) (4)
SubList(SH|SR, L) = SubList(SH|[], L) AND SubList(SR, L) (5)
在英语中,这意味着如果L包含子列表S的第一个元素并且它包含子列表的其余元素,那么您的SubList方法将返回true。
此处的递归在第4行和第5行可见,您可以看到我们一次又一次地调用相同的函数,直到SR只包含一个元素。
例如:
L = [1,2,5]
S = [1,5]
SubList(S, L) = SubList([1,5], [1,2,5])
= SubList(1|[5], 1|[2,5]) (4+5)
= SubList(1|[], 1|[2,5]) AND SubList([5], 1|[2,5])
= SubList(1|[], 1|[2,5]) AND (SubList(5|[], 1|[]) OR SubList(5|[], [2,5]))
= SubList(1|[], 1|[2,5]) AND (SubList(5|[], 1|[]) OR (SubList(5|[], 2|[]) OR SubList(5|[], [5])))
= SubList(1|[], 1|[2,5]) AND (SubList(5|[], 1|[]) OR (SubList(5|[], 2|[]) OR SubList(5|[], 5|[])))
= true AND (false OR (false OR true))
= true AND true
= true
可能的Java实现:
public SLList(SLNode h) {
this.head = h;
}
public SLList singletonList(SLNode n) {
return new SLList(new SLNode(n.info));
}
public SLList remainingList(SLNode n) {
if(n == null) return new SLList();
return new SLList(n);
}
private static boolean subList(SLList s, SLList l) {
if(s.isEmpty()) return true;
if(l.isEmpty()) return false;
if(s.head.next == null && l.first().equals(s.first())) return true;
return (subList(singletonList(s.head), singletonList(l.head)) ||
subList(singletonList(s.head), remainingList(l.head.next))) &&
subList(remainingList(s.head.next), l);
}
我还没有对代码进行测试,可能会遗漏一些空检查,但重要的是你可以了解递归是如何工作的。