仅使用基本构造通过方案创建 n 大小的排列
是否可以仅使用基本方案构造来生成列表的 n 大小排列?
Is it possible to generate n-sized permutations of a list using only the basic scheme constructs?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
使用
define
,你可以这样做(如果没有define
,答案是否定的,因为你需要使用递归):首先定义一个函数,它接受一个列表列表和一个值,并返回一个列表列表,其中给定的项目已添加到原始列表列表中的每个列表中。
这可以通过编写一个简单的递归函数来完成,该函数使用
cons
将项目添加到第一个列表(使用car
获取第一个列表),然后使用cons
再次将扩展列表添加
到在其他列表(即列表列表的cdr
)上调用该函数的结果。如果列表为空(因此没有car
和cdr
),则返回空列表。您还需要一个从列表中删除给定项目的函数。这也可以通过定义一个接受项目和列表的简单递归函数来完成。在每一步中,如果给定列表的“car”不等于要删除的项目,则应将其添加到递归调用的结果之前。如果相等,则直接返回递归调用的结果。
此外,您还需要一个函数来连接列表。这也可以递归实现,不会太麻烦。
然后定义一个函数,给定一个列表列表和一个项目,以该项目和每个子列表作为其参数调用前一个函数。
现在定义创建 n 大小排列的函数。该函数应采用数字
n
和一个列表。如果n
是0,它应该返回空列表。否则,它应该为列表中的每个项目x
递归调用自身,并使用(- n 1)
作为n
的新值以及以下结果:从列表中删除x
作为列表的新值。然后应该连接递归调用的结果。With
define
you can do it like this (withoutdefine
the answer would be no, because you'll need to use recursion):First define a function that takes a list of lists and a value and returns a list of lists where the given item has been prepended to each list in the original list of lists.
This can be done by writing a simple recursive function that uses
cons
to prepend the item to the first list (usingcar
to get the first list) and then usescons
again toprepend
the extended list to the result of calling the function on the other lists (i.e. on thecdr
of the list of lists). If the list is empty (and thus doesn't have acar
andcdr
), return the empty list.You'll also need a function that removes a given item from a list. This can also be done by defining a simple recursive function that takes an item and a list. At each step the `car´ of the given list should be prepended to the result of the recursive call if it is not equal to the item that is to be deleted. If it is equal, the result of the recursive call should be returned directly.
Further you'll need a function to concatenate lists. This can also be implemented recursively without too much trouble.
Then define a function that given a list of lists and an item calls the previous function with the item and each sublist as its argument.
Now define the a function that creates n-sized permutations. This function should take the number
n
and a list. Ifn
is 0, it should return the empty list. Otherwise it should call itself recursively for each itemx
in the list with(- n 1)
as the new value forn
and the result of removingx
from the list as the new value for the list. Then the results of the recursive calls should be concatenated.这是对 Rosetta 中代码的解释,不过,我更改了变量名称以提供帮助使其更具可读性,并添加了我对下面代码的解释。我确实检查了代码在 DrRacket 中是否有效,并且确实有效。
在定义permute之前,需要两个辅助函数,即seq和insert。
seq 构建一个包含数字序列的列表。例如(seq 0 3)-> (0 1 2 3)。
列表中的元素(数字)在insert函数中使用,以将carItem插入到“cdr<”中的各个位置。 /strong>' 列表。
insert 生成一个列表,其中 carItem 插入到 cdrList 的第“n”个位置。例如,(insert '(bc) 0 'a) -> '(abc) 和 (插入 '(bc) 2 'a) -> '(BCA)。
最后,主函数permute,以递归的方式使用了insert和seq。
例如,当 plist = '(b,c) 时,lambda 的值如下:
如果上面的嵌套 lambda 让你头晕(对我来说就是如此),请在下面找到,恕我直言,一个更具可读性的“定义”版本,感谢 Matthias Felleisen:
This is an explanation of the code found in Rosetta, although, I have changed the variable names to help make it more readable, and added my explanation of the code below. I did check to see if the code works in DrRacket, and it does.
Before defining permute, two helper functions are required namely, seq and insert.
seq builds a list containing a sequence of numbers. For example (seq 0 3) -> (0 1 2 3).
The elements (numbers) in the list are used in the insert function to insert the carItem at various positions in the 'cdr' list.
insert generates a list with the carItem inserted in the "n"th position of the cdrList. For example, (insert '(b c) 0 'a) -> '(a b c) and (insert '(b c) 2 'a) -> '(b c a).
Finally, as for the main function permute, it uses insert and seq in a recursive manner.
For example, when plist = '(b,c) the lambda evals to the following:
If the above nested lambdas makes your head spin (it did for me), find below, IMHO, a more readable "define" version, thanks to Matthias Felleisen: