我试图找出这两种递归策略之间的区别.
我被告知的定义如下:
尾递归:如果在调用返回后没有必要进行调用,则调用是尾递归的,即当调用返回时,返回的值立即从调用函数返回
Head Recursion:当函数的第一个语句是递归调用时,调用是头递归的.
如果给出了编程问题中的上述条件并且我使用递归来解决它,那么我是否违反了约束条件?这可能是因为递归也使用堆栈?这样对吗?
我需要将java中的String从"aaaaaaaa"增加到"aaaaaab"到"aaaaaac"直到字母表,然后最终到"aaaaaaba"到"aaaaaabb"等.
这有诀窍吗?
我一直在努力找到一个有效的填充算法.在许多算法中,我只尝试过"递归线填充",其中一个行为完全符合它应该的主要警告,它偶尔会打击堆栈.:(
我已经尝试了很多我发现的非递归实现,并且它们都非常温和:要么在奇怪的地方留下空隙,要么泛滥整个区域(当它们应该被封闭时).
任何人都有一个用C语言编写的非递归填充工作源代码(或者c ++不是太大的OOP而且我可以很容易地解开)?
我有以下代码:
#include <stdio.h>
void SingSongFor(int numberOfBottles){
if (numberOfBottles == 0){
printf("There are simply no more bottles of beer on the wall.\n\n");
} else {
printf("%d bottles of beer on the wall. %d bottles of beer.\n", numberOfBottles, numberOfBottles);
int oneFewer = numberOfBottles - 1;
printf("Take one down, pass it around, %d bottles of beer on the wall.\n\n", oneFewer);
SingSongFor(oneFewer); // This function calls itself!
// Print a message just before the function ends
printf("Put a bottle in the recycling, %d empty …Run Code Online (Sandbox Code Playgroud) 标题说明了一切,真的; 迭代集合同时保持循环之间的状态和基于终止条件的完成迭代以及简单地耗尽元素可能是在命令式编程中完成任何事情的最常见模式.在我看来,像但它的东西功能gentleprogrammers同意不谈,至少我从来没有遇到过的成语,或一个半标化的名称,如用map,fold,reduce等.
我经常在scala中使用followinig代码:
implicit class FoldWhile[T](private val items :Iterable[T]) extends AnyVal {
def foldWhile[A](start :A)(until :A=>Boolean)(op :(A, T)=>A) :A = {
if (until(start)) start
else {
var accumulator = start
items.find{ e => accumulator = op(accumulator, e); until(accumulator) }
accumulator
}
}
}
Run Code Online (Sandbox Code Playgroud)
但它很难看.每当我尝试一种更具声明性的方法时,我会使用更长,几乎肯定更慢的代码,类似于:
Iterator.iterate((start, items.iterator)){
case (acc, i) if until(acc) => (acc, i)
case (acc, i) if i.hasNext => (op(acc, i.next()), i)
case x => x
}.dropWhile {
case (acc, i) => !until(acc) …Run Code Online (Sandbox Code Playgroud) 因此我在使用递归进行空闲处理时,我注意到使用递归的循环比常规循环慢得多,我想知道是否有人知道原因.我已经包含了我在下面进行的测试:
>>> import timeit
>>> setu="""def test(x):
x=x-1
if x==0:
return x
else:
test(x)
"""
>>> setu2="""
x=10
while x>0:
x=x-1
"""
>>> timeit.timeit(stmt="test(10)",setup=setu,number=100)
0.0006629826315997432
>>> timeit.timeit(stmt=setu2,number=100)
0.0002488750590750044
>>> setu="""def test(x):
x=x-1
if x==0:
return x
test(x)
"""
>>> timeit.timeit(stmt="test(10)",setup=setu,number=100)
0.0006419437090698921
Run Code Online (Sandbox Code Playgroud)
然而,在上一次测试中,我注意到如果我拿出else声明,它显示速度略有提高,所以我想知道if语句是否是这个循环速度差异的原因?
可能重复:
最大递归深度?
我的代码有另一个问题.我正在研究我在Vpython中的第一个程序,我必须模拟混合两种气体.首先我遇到了边界问题,但现在当球(代表气体粒子)留在边界内时,存在不同的错误.几秒钟后,我收到一个错误,该错误显示在我的函数的源代码下面.码:
def MovingTheBall(listOfBalls,position,numCell,flagOfExecution):
flag = 0
if flagOfExecution==0:
positionTmp = position
else:
positionTmp = (position[0]+choice([-1,0,1]),position[1]+choice([-1,0,1]),0)
for i in range( 0, len(listOfBalls) ):
if positionTmp==listOfBalls[i].pos:
flag=1
if flag==1:
return MovingTheBall(lista,(position[0]+choice([-1,0,1]),position[1]+choice([-1,0,1]),0),numCell,1)
else:
if positionTmp[0]==0 or positionTmp[0]>=numCell or positionTmp[0]<=-numCell or positionTmp[1]>=numCell or positionTmp[1]<=-numCell:
return MovingTheBall(lista,(position[0]+choice([-1,0,1]),position[1]+choice([-1,0,1]),0),numCell,1)
return positionTmp
Run Code Online (Sandbox Code Playgroud)
错误是:
return MovingTheBall(listOfBalls,(position[0]+choice([-1,0,1]),position[1]+choice([-1,0,1]),0),numCell,1)
File "gaz.txt", line 138, in MovingTheBall
return MovingTheBall(listOfBalls,(position[0]+choice([-1,0,1]),position[1]+choice([-1,0,1]),0),numCell,1)
File "gaz.txt", line 138, in MovingTheBall
return MovingTheBall(listOfBalls,(position[0]+choice([-1,0,1]),position[1]+choice([-1,0,1]),0),numCell,1)
File "gaz.txt", line 138, in MovingTheBall
return MovingTheBall(listOfBalls,(position[0]+choice([-1,0,1]),position[1]+choice([-1,0,1]),0),numCell,1)
File "gaz.txt", line 138, in MovingTheBall
return …Run Code Online (Sandbox Code Playgroud) Python具有最大递归深度,但没有最大迭代深度.为什么递归受限制?像迭代这样处理递归是不是更自然,而不是限制递归调用的数量?
我只想说这个问题的根源来自于尝试实现一个流(有关流的更多详细信息,请参阅此问题).例如,假设我们要编写一个流来生成自然数:
def stream_accum(s, n): # force the stream to a list of length n
def loop(s, acc):
if len(acc) == n:
return acc
hd, tl = s()
return loop(tl, acc + [hd])
return loop(s, [])
def nats():
def loop(n):
return n, lambda: loop(n+1)
return loop(1)
Run Code Online (Sandbox Code Playgroud)
流的递归定义非常吸引人.但是,我想更好/更pythonic的方法是使用发电机.
我正在尝试实现一个返回200万以下所有素数之和的代码.我有一个isPrime(int x)方法,如果数字是素数,则返回true.这里是:
public static boolean isPrime(int x) {
for (int i = 2; i < x; i++) {
if (x % i == 0) {
return false;
}
}
return true;
}
Run Code Online (Sandbox Code Playgroud)
另一种方法,我试图以递归方式实现,只能工作到一定数量,超过该数字,我得到堆栈溢出错误.我得到的最高代码是10,000.
这里是:
public static int sumOfPrimes(int a) {
if (a < 2000000) { //this is the limit
if (isPrime(a)) {
return a + sumOfPrimes(a + 1);
} else {
return sumOfPrimes(a + 1);
}
}
return -1;
}
Run Code Online (Sandbox Code Playgroud)
那么为什么当数字变大时我会得到堆栈溢出错误,我该如何处理呢?另外,你通常如何处理为这么大的数字编写代码?IE:像这样的正常数字操作但是对于更大的数字?我递归地写了这个,因为我认为它会更有效但它仍然无法工作.
recursion ×6
java ×3
python ×3
algorithm ×2
c ×2
stack ×2
difference ×1
flood-fill ×1
overflow ×1
performance ×1
python-2.7 ×1
scala ×1
simulation ×1
string ×1
vpython ×1