当前位置: 首页 > 知识库问答 >
问题:

Prolog-3个元素的第N个排列

宦子琪
2023-03-14

我想得到3个元素的第n个排列。如。

列表=[1,2,3]n=5

输出 [1,2,3,1,2] [1,2,3,2,1] ...

我不想要任何连续的相同元素,例如[1,1,1,1,1] [1,2,3,3,2]...

我尝试了几个可以获得完整排列的方法,无法弄清楚如何获得我需要的东西。

varia_repp(N,RVaria):-varia_rep(N,[1,2,3],RVaria).

varia_rep(0,_,[]).
varia_rep(N,[H|L],RVaria):-N>0,N1 is N-1,delete(H,[H|L],_),varia_rep(N1,[H|L],RVaria).

perm(List,[H|Perm]):-delete(H,List,Rest),perm(Rest,Perm).
perm([],[]).

共有2个答案

谭铭
2023-03-14

从您的示例来看,您不需要K个元素的第N次排列(在您的示例中K = 3),但是需要N个元素的排列,其中N的列表是用模板列表中的元素填充构建的,然后进行过滤以排除连续的相等元素:

varia_rep(N, L, P) :-
  build_rep(L, N, P0),
  permutation(P0, P),
  \+ append(_, [X,X|_], P).

build_rep(L, N, P0) :-
  length(L, K),
  findall(X, (between(1, N, I), J is ((I-1) mod K) + 1, nth1(J, L, X)), P0).

测试

?- build_rep([1,2,3],5,P).
P = [1, 2, 3, 1, 2].

?- varia_rep(5,[1,2,3],P).
P = [1, 2, 3, 1, 2] ;
P = [1, 2, 3, 2, 1] ;
P = [1, 2, 1, 3, 2] ...
施凡
2023-03-14

这样做的一种方法(请注意,排列是按词典顺序排列的)是明确声明两个连续的元素不能相同:

perm(1, Input, [Last]) :-
    member(Last, Input).
perm(N, Input, [First,Second|Perm]) :-
    N > 1, N0 is N-1,
    member(First, Input),
    dif(First, Second),
    perm(N0, Input, [Second|Perm]).

?- perm(3,[a,b,c],R).
R = [a, b, a] ;
R = [a, b, c] ;
R = [a, c, a] ;
R = [a, c, b] ;
R = [b, a, b] ;
R = [b, a, c] ;
R = [b, c, a] ;
R = [b, c, b] ;
R = [c, a, b] ;
R = [c, a, c] ;
R = [c, b, a] ;
R = [c, b, c] ;
false.

您已经用swi-prolog标记了这个问题。它有一个谓词dif/2,就像其他主要的Prolog实现一样。您还可以在StackOverflow上找到一些关于dif/2的有趣讨论,包括优点和缺点。总而言之,它提出了一个约束,它的两个参数无法统一。它可以用于非实例化变量,在这种情况下,可以防止大量不必要的回溯,而无需任何明确的切割或额外的参数。

此外,不推荐使用 delete/3,取而代之的是 select/3。但是,在这里您只需要成员/ 2(因为您想重用元素)。

编辑

正如评论中指出的,虽然dif/2使内容更短,但它可能会有点混乱。这是一个几乎相同的版本,没有dif/2(对于较大的N来说,它的运行速度也快得多)。

p(N, Input, [First|Rest]) :-
    N >= 1, N0 is N-1,
    member(First, Input),
    p(N0, Input, First, Rest).

p(0, _, _, []).
p(N, Input, Prev, [This|Rest]) :-
    N > 0, N0 is N-1,
    member(This, Input), This \= Prev,
    p(N0, Input, This, Rest).
 类似资料:
  • 返回数组的第n个元素。 使用 Array.slice() 获取数组的第 n 个元素。如果索引超出范围,则返回 [] 。省略第二个参数 n ,将得到数组的第一个元素。 const nthElement = (arr, n = 0) => (n > 0 ? arr.slice(n, n + 1) : arr.slice(n))[0]; nthElement(['a', 'b', 'c'], 1);

  • 返回数组中的每个第 n 个元素。 使用 Array.filter() 创建一个包含给定数组的每个第 n 个元素的新数组。 const everyNth = (arr, nth) => arr.filter((e, i) => i % nth === nth - 1); everyNth([1, 2, 3, 4, 5, 6], 2); // [ 2, 4, 6 ]

  • 本文向大家介绍Elm从列表中获取第n个元素,包括了Elm从列表中获取第n个元素的使用技巧和注意事项,需要的朋友参考一下 示例 List不支持“随机访问”,这意味着要从列表中获取第五个元素要比第一个元素花费更多的工作,因此没有任何List.get nth list功能。必须从头开始(1 -> 2 -> 3 -> 4 -> 5)。 如果您需要随机访问,则使用随机访问数据结构(例如)可能会获得更好的结果

  • 问题内容: 假设我有一个这样的Python清单: 我想在每个第n个元素后插入一个“ x”,比方说该列表中的三个字符。结果应为: 我知道我可以通过循环和插入来做到这一点。我实际上正在寻找的是Pythonish方式,也许是单线? 问题答案: 我有两个一线客轮。 鉴于: 使用获得指数,增加每3次字母, 如 :,然后连接成字符串和它。 [‘a’, ‘b’, ‘c’, ‘x’, ‘d’, ‘e’, ‘f’,

  • 问题内容: 我想找到相应的span元素。我想使用css选择器检查span元素的顺序。因此,当我使用Selenium IDE时,我将按照以下方式进行验证(使用第n个子概念)。 verifyText | css = .title:nth(0)| 首页 verifyText | css = .title:nth(1)| 帖子 verifyText | css = .title:nth(2)| 事件 ve

  • 问题内容: 想知道如何编写SQL函数以查找表中的第N个最大元素,如果没有第N个最大元素,则返回Null。 使用MySQL / MySQL工作台。 顺便说一句,我的问题与第N个最高薪水问题不同,因为我还有一个附加要求,如果第N个最大元素不存在,则返回Null。任何想法表示赞赏。 预先感谢林 问题答案: 您可以这样做: