从列表中删除前N个素数(Prolog)

时间:2017-01-13 21:44:42

标签: prolog primes

基本上我想从列表中删除第一个N数字,检查数字是否为素数的函数似乎运行良好,但程序本身并不是

例如,对于输入[2,4,5,7,6,9,11]N = 3,我应该[4, 6, 9, 11],但我只获得[4, 6, 9]

divisible(X,Y) :- 
    0 is X mod Y, !.
divisible(X,Y) :- 
    X > Y+1, 
    divisible(X, Y+1).

%isPrime function check whether or not the argument is a prime number
isPrime(2) :- true,!.
isPrime(X) :- X < 2,!,false.
isPrime(X) :- not(divisible(X, 2)).

%delFunction (input_list, N, output_list)
delFunction([],_,_).
delFunction(_,0,_).
delFunction([H|T], N, [H|Res]):-
    not(isPrime(H)), !,
    delFunction(T, N, Res).
delFunction([_|T], N, Res):-
    N1 is N-1,
    delFunction(T,N1,Res).

delFunction([2,4,5,7,6,9,11],3,X) - &gt; [4,6,9](这不是正确答案)

老实说,我不知道自己哪里出错了,实现的想法看起来非常简单直接,代码也是如此。

此外,当我运行它时会停在[4]并且我必须继续单击下一步以使我到执行结束(因此结果)。知道怎么解决吗?我想也许我需要一些削减但不确定在哪里。

P.S:我宁愿不使用内置函数(如果在这种情况下有任何帮助)

1 个答案:

答案 0 :(得分:2)

所有人的拳头,而不是

delFunction([],_,_).

你应该写

delFunction([],_,[]).

因为当输入列表(左侧)为空时,您必须构造输出列表的基础:空列表;使用delFunction([], _, _),您不会将输出列表与空列表统一,因此结果将以非统一变量结束。

二。而不是

delFunction(_,0,_).

你应该写

delFunction(L,0,L).

问题是一样的:当数字为零时,你可以“复制”输出中的输入;也就是说,你可以统一他们;那是delFunction(L,0,L)。使用delFunction(_,0,_)时,您不会统一,结果会以非统一变量结束。

第三。在is-prime条款中

delFunction([_|T], N, Res):-
    N1 is N-1,
    delFunction(T,N1,Res).

您应该检查N是否大于零

delFunction([_|T], N, Res):-
    N > 0,
    N1 is N-1,
    delFunction(T,N1,Res).

或者,如果您愿意,您应该在零条款

中添加剪切(!
delFunction(L,0,L) :- !.

为了避免Prolog,通过回溯,可以提供多个不受欢迎的答案。

---编辑---

作为Guy Coder,我避免像瘟疫那样的削减;所以我提出以下解决方案,以避免不必要的重复。

delFunction([], _, []).

delFunction([H | T], 0, [H | T]).

delFunction([H | T], N, [H | Res]) :-
    N > 0,
    not(isPrime(H)),
    delFunction(T, N, Res).

delFunction([H | T], N, Res):-
    N > 0,
    isPrime(H),
    N1 is N-1,
    delFunction(T, N1, Res).