我在试图解决Prolog中的2个问题时遇到了麻烦。
这是第一个: 我需要计算列表元素的de gcd
期望:
gdc([3, 9, 6], G).
G=3
这是我尝试这样做的方式:
gdcs(1, _, 1) :- !.
gdcs(_, 1, 1) :- !.
gdcs(0, B, B) :- !.
gdcs(B, 0, B) :- !.
gdcs(X, X, X) :- !.
gdcs(A, B, L) :- A < B, !, L1 = B mod A, gdc(A, L1, L).
gdcs(A, B, L) :- L1 = A mod B, gdcs(B, L1, L).
gdc([], 0).
gdc([H|T], C) :- gdc(T, D), gdcs(D, H, C).
问题是它只在我只引入0或1时有效,对于其他数字,它不起作用。
第二个: 旋转Prolog中的列表,这就是我需要的:
rot([1, 2, 1, 4, 5, 3, 5], Dir, Nr, Res). // Dir = direction(lft,rght), Nr = nr. of elements to shift, Res = List of elements
Res=[1, 4, 5, 3, 5, 1, 2] // in this case Dir = lft, Nr = 1.
这个我不知道如何实现,在互联网上找到如何只使用一个方向,但这一个,我无法想象。
答案 0 :(得分:-1)
gcd(a,b,c)= gcd(gcd(a,b),c)。这意味着,为了计算超过2个元素的gcd,您可以先计算两个第一个元素的gcd,然后将其用作递归调用列表中的元素:
% GCD calculation for two numbers
gcd2(A, 0, A).
gcd2(A, B, C) :-
A > B,
A1 is mod(A,B),
gcd2(A1, B, C).
gcd2(A, B, C) :- gcd2(B,A,C).
% GCD of a list (the list contains at least two elements)
gcd([A,B], G) :- gcd2(A,B,G).
gcd([A,B|T], G) :-
gcd2(A,B,A1),
gcd([A1|T], G).
关于旋转......好的是旋转有效地将列表拆分到某个位置,然后以相反的顺序粘合它。左旋转的位置正好是所需的旋转数,而右边是列表的长度减去数字。解决方案分为拆分规则和两个不同的旋转:
% splitAt (List, Position, Leftpart, Rightpart)
splitAt([],_,[], []).
splitAt(L, 0, [], L).
splitAt([H|T], N, [H|Tleft], Right) :-
N1 is N-1,
splitAt(T, N1, Tleft, Right).
rotateLeft(L, N, Res) :-
splitAt(L, N, Left, Right),
append(Right, Left, Res).
rotateRight(L, N, Res) :-
length(L, Len),
N1 is Len-N,
splitAt(L, N1, Left, Right),
append(Right, Left, Res).
% rot(list, Dir, Nr, Res)
rot(L, lft, N, Res) :- rotateLeft(L, N, Res).
rot(L, rght, N, Res) :- rotateRight(L, N, Res).