我在理解递归方面遇到了麻烦,我无法解决以下问题。
输入:对象(f.e。字段)和整数n
所需输出:包含n个字段的列表
我编写了一个方法,它将一个简单的对象分成两部分,并且工作正常。但我无法处理递归。
createFields(field,5)的最小示例:
Input:
**********************************
* *
* *
* *
**********************************
1st iteration (after divide(field))
**********************************
* * *
* * *
* * *
**********************************
2nd iteration
**********************************
* * *
**********************************
* * *
**********************************
3rd last iteration
**********************************
* * * *
**********************************
* * *
**********************************
你能帮我解决这个问题吗?
谢谢!
答案 0 :(得分:0)
算法的高级描述是:
divide_recursively (fields, n)
args:
input/output fields : List of fields
input n : integer (number of fields)
precondition:
head of list is largest available field
body:
if (fields.size() == n) return
f = fields.front()
fields.pop_front()
fsplit[] = split_field(f)
fields.push_back(fsplit[0])
fields.push_back(fsplit[1])
divide_recursively(fields, n)
只要split_field
将输入分成两半,就可以在此算法中满足前提条件。
使用递归来呈现算法,因为这是问题中的标记之一。这使用尾递归,许多编译器/解释器将转换为常规循环作为tail call优化的特殊情况。
上面的算法使用贪婪的方法。下面是一种使用分而治之的方法的替代算法。
divide_recursively (fields, n)
precondition:
fields contains exactly one element
body:
if (n == 1) return
f = fields.front()
fields.pop_front()
fpslit[] = split_field(f)
subfields1 = new list + fsplit[0]
subfields2 = new list + fsplit[1]
divide_recursively(subfields1, n/2)
divide recursively(subfields2, n - n/2)
fields = subfields1 + subfields2
答案 1 :(得分:0)
您应该能够迭代地使用当前函数。您从1字段开始并调用您的函数,它会为您提供2个字段的列表。将它们添加到临时列表中。现在只需在这些字段上调用split函数。一旦您用完了一定大小的字段,就可以先拆分较小的字段。
下面的代码应该为您提供大小为x和x / 2的n个字段(存储在fields
和fields2
中)。
Field startField=...
ArrayList<Field> fields=new ArrayList<Field>();
ArrayList<Field> fields2=new ArrayList<Field>();
fields.add(startField);
nrFields=1;
outerlabel:
while(nrFields<n){
while((!fields.isEmpty()){
Field fieldToSplit = fields.remove(0);
List<Field> splitFields=splitt(fieldToSplit);
fields2.addAll(splitFields);
nrFields++;
if(nrFields==n)break outerlabel;
}
fields=fields2;
fields2=new ArrayList<Field>();
}
答案 2 :(得分:0)
根据我的一条评论,这是一个非递归解决方案的提案(伪代码):
split(field, n) {
queue = new Queue()
queue.addLast(field)
while (queue.size() < n) {
f = queue.removeFirst()
pair = f.split()
queue.addLast(pair.a)
queue.addLast(pair.b)
}
return queue
}