今天我要实现一种方法来遍历任意深度图并将其展平为单个可枚举.相反,我先做了一点搜索,发现了这个:
public static IEnumerable<T> Traverse<T>(this IEnumerable<T> enumerable, Func<T, IEnumerable<T>> recursivePropertySelector)
{
foreach (T item in enumerable)
{
yield return item;
IEnumerable<T> seqRecurse = recursivePropertySelector(item);
if (seqRecurse == null) continue;
foreach (T itemRecurse in Traverse(seqRecurse, recursivePropertySelector))
{
yield return itemRecurse;
}
}
}
Run Code Online (Sandbox Code Playgroud)
从理论上讲,这看起来很不错,但实际上我发现它比使用等效的手写代码(如果出现的情况)执行图表并做任何需要做的事情要差得多.我怀疑这是因为在这个方法中,对于它返回的每个项目,堆栈必须放松到某个任意深度的水平.
我还怀疑如果递归被消除,这种方法会更有效地运行.我也不太擅长消除递归.
有谁知道如何重写此方法以消除递归?
谢谢你的帮助.
编辑:非常感谢所有详细的回复.我已尝试对原始解决方案与Eric的解决方案进行基准测试,而不是使用枚举器方法,而是递归遍历一个lambda,奇怪的是,lambda递归明显快于其他两种方法.
class Node
{
public List<Node> ChildNodes { get; set; }
public Node()
{
ChildNodes = new List<Node>();
}
}
class Foo
{
public static void Main(String[] args)
{
var nodes = new List<Node>(); …Run Code Online (Sandbox Code Playgroud) 我正在编写一个小函数来检查列表中的所有元素是否小于或等于限制。这仅是为了练习,不应使用任何循环来完成。
def small_enough(a, limit):
return all(x <= limit for x in a)
small_enough([66, 101], 200)
Run Code Online (Sandbox Code Playgroud)
已经有一段时间了,但我找不到任何替代代码来代替for循环。此代码可以正常使用-但是,我试图在不使用循环的情况下获得结果。尝试写一些更“ pythonic”的东西。
我正在编写一个递归泛洪填充算法来查找图像中的连接组件,我的代码编译并运行良好的MSVC 2008编译器; 但是mingw编译的二进制文件在运行时崩溃了.
在我使用std :: stack将算法转换为非递归后,一切顺利.
但是,如果我必须在某些情况下使用递归算法,并且mingw无法处理呢?
如何增加二进制文件的堆栈大小,是否有任何编译选项?
谢谢
假设我有一个如下列表:
mylist = ['a','b','c','d']
Run Code Online (Sandbox Code Playgroud)
是否可以从此列表中创建以下dict 而不使用递归/递归函数?
{
'a': {
'b': {
'c': {
'd': { }
}
}
}
}
Run Code Online (Sandbox Code Playgroud) 我写了一个存储的FUNCTION,递归地调用自己.
但是,当我在查询中运行它时,我得到了这个无耻的错误:
错误:1424 SQLSTATE:HY000(ER_SP_NO_RECURSION)
消息:递归存储函数和触发器不允许的.
"不允许"?
对.为什么我们不只是禁用WHILE循环,而我们在它呢?
我可以以任何方式启用递归函数吗?
我发现了一个错误报告,但是有任何变通方法吗?
我在Windows XP(XAMPP Server)上运行MySQL 5.1.41.
mysql recursion stored-procedures user-defined-functions stored-functions
考虑到标签出现的次数,我需要打印打印有效标签"<"和">"的不同变体,下面是使用递归的python中的解决方案.
def genBrackets(c):
def genBracketsHelper(r,l,currentString):
if l > r or r == -1 or l == -1:
return
if r == l and r == 0:
print currentString
genBracketsHelper(r,l-1, currentString + '<')
genBracketsHelper(r-1,l, currentString + '>')
return
genBracketsHelper(c, c, '')
#display options with 4 tags
genBrackets(4)
Run Code Online (Sandbox Code Playgroud)
我很难真正理解这一点,并希望尝试将其转换为迭代版本,但我没有取得任何成功.
根据这个线程:每个递归都可以转换成迭代吗? - 它看起来应该是可能的,唯一的例外似乎是Ackermann功能.
如果有人有关于如何查看Eclipse中维护的"堆栈"的任何提示 - 这也将不胜感激.
PS.这不是一个功课问题 - 我只是想更好地理解递归到迭代转换.
由Matthieu M.编辑,提供更好的可视化输出示例:
>>> genBrackets(3)
<<<>>>
<<><>>
<<>><>
<><<>>
<><><>
Run Code Online (Sandbox Code Playgroud) 这是python中的合并排序逻辑:(这是第一部分,忽略函数merge())问题点是将递归逻辑转换为while循环.代码礼貌:Rosettacode Merge Sort
def merge_sort(m):
if len(m) <= 1:
return m
middle = len(m) / 2
left = m[:middle]
right = m[middle:]
left = merge_sort(left)
right = merge_sort(right)
return list(merge(left, right))
Run Code Online (Sandbox Code Playgroud)
是否有可能在while循环中使它成为一种动态,而每个左右数组都分成两个,一种指针根据左右数组的数量不断增加并打破它们直到只剩下单个长度的列表?因为每当下一次分割进入左右两侧时,阵列就会不断分解,直到只剩下单个长度列表,因此左侧(左 - 左,右 - 右)和右侧(右 - 左,右 - 右)中断将增加,直到达到所有大小为1的列表.
我一直在关注 OpenMesh 教程的第一步 -通过一些修改构建一个立方体,我使用的是 TriMesh 而不是 PolyMesh 并且正在构建金字塔而不是立方体。
不知何故,PolymeshT::add_face:complex edge我的第二张脸和第三张脸都出现了错误。这些面应该在点 (0,0,0)、(0,1,0) 和 (0,0,1) 以及点 (0,0,0)、(0,0,1) 和(1,0,0)。
当每个面被构造为 (0,0,0) 到 (0,1,0) 和 (0,0,0) 到 (0,0,1) 时,两条边已经存在,但我应该能够在其中创建面一些边缘已经存在,不是吗?
到目前为止我尝试过的解决方案
我无法发现我正在做的与教程不同的任何其他事情。
#include <OpenMesh/Core/IO/MeshIO.hh>
#include <OpenMesh/Core/Mesh/TriMesh_ArrayKernelT.hh>
typedef OpenMesh::TriMesh_ArrayKernelT<> MyTriMesh;
// Make a pyramid
int main()
{
MyTriMesh tin;
// generate vertices
MyTriMesh::VertexHandle vhandle[4];
vhandle[0] = tin.add_vertex(MyTriMesh::Point(0, 0, 0));
vhandle[1] = tin.add_vertex(MyTriMesh::Point(0, 1, 0));
vhandle[2] = tin.add_vertex(MyTriMesh::Point(1, 0, 0));
vhandle[3] = tin.add_vertex(MyTriMesh::Point(0, 0, 1));
// …Run Code Online (Sandbox Code Playgroud) 几天前有人对我说,递归会比迭代更好,如果可能的话,应该总是使用.
所以,我进入递归并尝试编写一个简单的程序来获得一个数字的阶乘.这是递归:
def fact(n):
if n == 1:
return 1
return n * fact(n - 1)
Run Code Online (Sandbox Code Playgroud)
虽然这样可以正常工作,但RuntimeError: maximum recursion depth exceeded只要n达到997以上就会得到.
所以我写了一个简单的函数,完全相同,但有一个for loop.
def fact(n):
a = 1
for x in range (0, n, 1):
a = a * (n - x)
return a
Run Code Online (Sandbox Code Playgroud)
而n < 10000它在150毫秒内给出答案.
所以,我虽然可能递归速度较快,但数字较少,但不是.这需要更长时间:

所以我的问题是:
在Python中编写程序时是否有任何理由使用递归?
并且:
有任何问题只能通过递归来解决吗?
最近对于编程类,我们被赋予了用任何语言编写程序的赋值,给定n,将产生大小为n的数组p的所有可能的紊乱,使得对于所有i:0的p [i]!= i <= i <n.我们必须使用迭代器,例如.yield
示例:n = 3,[0,1,2]不是紊乱,但[2,0,1]和[1,2,0]一样.
我提出了一个可以工作的伪代码解决方案,但问题是它需要电源循环(即n个嵌套循环,其中n仅在运行时已知).为此,我在一个字符串中生成了Ruby代码中的n个嵌套循环,然后eval是字符串.我的解决方案有效,但是我的教授认为使用少量gotos比动态代码生成更好的解决方案(至少更容易阅读).
我的印象goto总是一个糟糕的选择.为什么运行时评估动态生成的代码比选择更糟糕goto呢?生成的代码简洁明了,对于给定的问题似乎相当有效.代码生成所依赖的唯一用户输入是n,检查它以确保它是预先的整数值.这应该yield是唯一的紊乱.
我不是要求我的编程任务的解决方案,我只是想知道使用goto过度动态代码评估的原因,反之亦然.
编辑: 澄清一下,赋值包括使用迭代器编写程序和使用递归编写另一个程序,因此迭代版本不一定意味着高效.