大家好,这是我的第一篇文章,所以如果你对如何提出问题有任何建议,我会全力以赴。所以我的问题是我尝试使用递归对数字列表进行排序,我有一个<div class="wrapper">
<span class="block1">23</span>
<span class="block2">Quote</span>
</div>
谓词返回列表的最大值,所以在返回后我从列表中选择该值然后再添加它到我的排序列表。然后我用新列表递归。
我的问题是谓词似乎工作并找到了正确的列表,但是当谓词退出时,它将所有列表恢复到原始状态,基本上撤消了谓词所做的所有工作。我认为这与Prolog如何回溯有关?
my_max/2
我添加了写只是为了表明它对列表进行了排序。输出应为%finds the max of a list, if the list is empty return int_min
my_max([],-2147483647).
my_max(L,M):-select(M,L,Rest), \+ (member(E,Rest),E>M).
%calls the my_max predicate store it in X, combines x and sorted and appends
%it to sorted2,then it takes X out of unsorted and creates Unsorted2 then
%recurse with unsorted2 and sorted2 should stop and output when unsorted is
%empty or []
my_sort([],S).
%my_sort([],S):-write(S). for test
my_sort(Unsorted,Sorted):-
my_max(Unsorted,X),
append(Sorted,[X],Sorted2),
select(X,Unsorted,Unsorted2),
my_sort(Unsorted2,Sorted2).
。
答案 0 :(得分:2)
首先,在加载文件时,我得到:
Warning: Singleton variables: [S]
由于基本情况:
my_sort([],S).
问题是基本情况表明空列表与单例变量S匹配,因此请尝试:
?- my_sort([],[1,2]).
true ;
false.
?- my_sort([],hello).
true ;
false.
在任何情况下my_sort/2
都不应该成功。所以你的基本情况应该是空列表:
my_sort([],S).
而不是在基本情况下构建完整的排序列表,而不是通过递归构建它,并在基本情况下留下一个空列表:
my_sort([],[]).
my_sort(Unsorted,Sorted):-
my_max(Unsorted,X),
select(X,Unsorted,Unsorted2),
my_sort(Unsorted2,Sorted2), % <- continue to find the sorted sublist
append(Sorted2,[X],Sorted). % <-place max at the end of sorted
在上面,Sorted2是Sorted的子列表,因此您可以递归地找到子问题的列表Sorted2,然后添加max。这是在每个步骤中递归完成的,在基本情况下,您将有空列表。
所以更好地理解它是一个例子 - 解释:
假设您要对[2,1,3]
列表进行排序。
max = 3
查找为[2,1]
排序(将在稍后的所有递归调用后添加3)max = 2
[1]
max = 1
查找已排序为[]
,即[] max = 1
- &gt; Sorted = [1]
max = 2
- &gt; Sorted = [2]
最后添加max = 3
- &gt; Sorted = [1,2,3]
例如:
? - my_sort([4,1,3,2],L)。 L = [1,2,3,4]; 假
一些优化
在每个步骤中,您可以通过遍历未排序的列表找到O(n)步的最大值,其中n是未排序列表的长度。再次附加O(n)。再次选择O(n)。因此,在每个步骤中总共执行3次O(n)计算。
为了避免你可以按降序构建列表,所以你不需要在O(n)中使用append。
此外,您的最大谓词可以返回Rest列表,这样您就可以避免排序谓词中的select / 3来减少另外N个步骤:
my_sort([],[]).
my_sort(Unsorted,[X|Sorted]):-
my_max(Unsorted,X,Unsorted2),
my_sort(Unsorted2,Sorted).
示例:
?- my_sort([4,1,3,2],L).
L = [4, 3, 2, 1] ;
false.
现在要升序使用reverse / 2:
?- my_sort([4,1,3,2],L),reverse(L,L1).
L = [4, 3, 2, 1],
L1 = [1, 2, 3, 4] ;
false.
O(N)步骤反转列表,但每次递归调用只有一次!!