我编写了一个递归函数,但是当我输入一个大数字时,递归会花费很多时间,例如100。
我想在代码中应用尾调用优化,以最小化计算时间,但我无法做到。
递归算法是class ClientViewSet(viewsets.ViewSet):
def list(self, request):
queryset = Client.objects.all()
serializer = ClientSerializer(queryset, many=True)
return Response(serializer.data)
def retrieve(self, request, pk=None):
queryset = Client.objects.all()
client = get_object_or_404(queryset, pk=pk)
serializer = ClientSerializer(client)
return Response(serializer.data)
def create(self, request):
serializer = ClientSerializer(data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=201)
return Response(serializer.errors, status=400)
def update(self, request, pk=None):
queryset = Client.objects.all()
client = queryset.get(pk=pk)
serializer = ClientSerializer(client, data=request.data, partial=True)
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=201)
return Response(serializer.errors, status=400)
f(n) = f(n-1) + f(n-2)
答案 0 :(得分:1)
尾部调用优化(TCO)仅在函数的最后一条指令立即返回另一个函数调用的输出(可以是递归调用)时有效。但在这种情况下情况并非如此。
TCO的全部目的是允许编译器通过多个函数调用对堆栈空间进行常量使用。 IOW,编译器可以分配一个堆栈帧(如果有的话)并反复重复使用它而不会弄乱任何东西。
您的fac()
函数调用自身两次,将返回值一起添加,然后将添加结果返回给调用者。因此,创建本地临时变量以接收这些返回值。每个函数调用都必须创建一个新的堆栈帧来保存自己的局部变量,这不是常量堆栈使用。而且,您的添加意味着该函数的 last 指令不是函数调用。所以你的代码否定了使用TCO的任何可能性。
答案 1 :(得分:0)
您的代码基本上是这样做的:
int a = fac(n - 1);
int b = fac(n - 2);
return a + b;
因此,函数返回前的最后一个操作不是函数调用,因此这里不可能使用TCO。