Prolog “如何对字符串列表进行排序”;“a”&引用;“bcd”&引用;ef";,及;“ghij”;按长度的降序排列?

Prolog “如何对字符串列表进行排序”;“a”&引用;“bcd”&引用;ef";,及;“ghij”;按长度的降序排列?,prolog,iso-prolog,Prolog,Iso Prolog,: 在您最喜欢的编程语言中,如何按长度降序排列字符串“a”、“bcd”、“ef”和“ghij”的列表 一个是: 我假设上面的代码是为ISO Prolog编写的,因为它没有使用特定于实现的特性。用法示例: ?- sort_desc_len(["a", "bcd", "ef", "ghij"], L). L = ["ghij", "bcd", "ef", "a"]. 我也会用类似的方法解决它。但是,该解决方案非常冗长(与其他编程语言的一行或两行相比),并且使用助手/辅助谓词污染程序。有没有更好的方

:

在您最喜欢的编程语言中,如何按长度降序排列字符串“a”、“bcd”、“ef”和“ghij”的列表

一个是:

我假设上面的代码是为ISO Prolog编写的,因为它没有使用特定于实现的特性。用法示例:

?- sort_desc_len(["a", "bcd", "ef", "ghij"], L).
L = ["ghij", "bcd", "ef", "a"].
我也会用类似的方法解决它。但是,该解决方案非常冗长(与其他编程语言的一行或两行相比),并且使用助手/辅助谓词污染程序。有没有更好的方法来解决ISO Prolog中的问题?

排序描述(L,S):- findall(N-T,(成员(T,L),原子长度(T,M),N是-M,LT), 键孔(左、右), 芬德尔(T,成员(T,ST),S)。 也就是说,findall/3通过member/2实现闭包。 setof/3将允许合并第一个findall和keysort调用,但它将删除重复项

请注意,atom_length/2无法与符合ISO标准的处理器配合使用。双引号字符串是代码列表,而不是原子列表


无论如何,我同意Prolog在函数式编程方面相当冗长。我认为原因在于它有一个关系数据模型。

我只是从功能上考虑:

显然是要使用的谓词。这实际上不是ISO,而是来自

所以,我做了U-Liek测试

?- run_tests(sort_desc_len).
% PL-Unit: sort_desc_len ....
ERROR: user://4:87:
        test stability: failed

ERROR: user://4:88:
        test random: failed

. done
% 2 tests failed
% 5 tests passed
遗憾的是,
predsort/3
删除了重复项。绝对应该有一个
predsort/4
来指示是否应该删除重复项

?- sort_desc_len([i,j,k],X).
X = [i].

?- sort_desc_len([a,xx,fg,hhh,jk],X).
X = [hhh, xx, a].
失败。

补遗 按照“重复评论”中的建议减少噪音

注意:
将/3
通话与交换的左右长度进行比较

my_cmp(X,L,R) :- 
   atom_length(L,Llen),
   atom_length(R,Rlen),
   compare(X,Rlen,Llen).

sort_desc_len(L,S) :- predsort(my_cmp,L,S).

我在Twitter上对paulgraham问题的回答使用了Logtalk库谓词和一个lambda表达式,该表达式调用isoprolog标准谓词和事实上的标准谓词。假设
double\u quotes
标志设置为
codes
(最可移植的设置;事实上,一些Prolog系统支持的唯一设置):

当在不提供
length/2
谓词作为内置谓词的受支持后端Prolog编译器上运行时,我们可以使用:

| ?- {types(loader)}.
yes

| ?- list::msort(
         [Order, List1, List2]>>(
             list::length(List1, N1), M1 is -N1,
             list::length(List2, N2), M2 is -N2,
             compare(Order, M1, M2)
         ),
         ["a", "bcd"",cd", "ef", "ghij"],
         Sorted
     ).
Sorted = [[98,99,100,34,44,99,100],[103,104,105,106],[101,102],[97]]
yes
有趣的是,这是迄今为止提供的最可移植的解决方案之一,可用于12个Prolog系统(即所有支持Logtalk的系统)


正如@capelical所说,与函数式语言相比,关系式语言总是提供更详细的解决方案。

在我看来,在这个层次上,“详细性”的概念只会放大噪音(另请参见:“代码高尔夫”),并可能会降低开机时的可读性。当一个人谈论一个需要几百行的问题时,它更有意义。这与“效率”不同,效率可以用#ops、时间(t)或能量(J)来衡量,即使在这个小代码块上也是如此。关键的一点是,必须有一个“足够灵活”的排序函数(实际上是一个库问题,而不是一个语言问题),您可以用“灵活的方式”指示排序顺序(这是一个语言问题)。这很好。这导致了一个扩展:在函数式编程中,使用“比较函数”(可能使用
library(yall)
和friends内联定义)执行排序,每对元素返回-1,0,+1。如何
[“z”,“a”]
排序?@false并不重要。两种都可以。只有字符串的长度才重要。根据瓦德勒的“”的精神,我们可以得出结论(即使在没有键入的情况下)“
findall/3
(或
bagof/3
)超过
member/2
”实际上是
maplist/3
?@DavidTonhofer:我认为findall+member和maplist在总体上是不可比的,他们完成非常不同的任务。例如,findall还可以过滤元素,而maplist不能,但maplist可以提供多个解决方案……您始终可以将
双引号
标记设置为
atom
,这符合ISO标准。不幸的是,一些Prolog系统只支持
代码设置
。如果您简化my_cmp/3以返回(留出一整行!),您也可以避免删除重复项,因此与主流语言相比,这是一个更好的比较(顺便说一句,在js中,您可以编写L.sort((x,y)=>y.length-x.length),这在短度方面很难击败。)使用
compare/3
而不是
((LlenX='>';(Llen>Rlen)->X='@capelical你的意思是,返回'@DavidTonhofer:。
?- sort_desc_len([i,j,k],X).
X = [i].

?- sort_desc_len([a,xx,fg,hhh,jk],X).
X = [hhh, xx, a].
my_cmp(X,L,R) :- 
   atom_length(L,Llen),
   atom_length(R,Rlen),
   compare(X,Rlen,Llen).

sort_desc_len(L,S) :- predsort(my_cmp,L,S).
?- run_tests(sort_desc_len).
% PL-Unit: sort_desc_len ....
ERROR: user://1:20:
        test stability: failed

ERROR: user://1:21:
        test random: failed

. done
% 2 tests failed
% 5 tests passed
false.
| ?- {types(loader)}.
yes

| ?- list::msort(
         [Order, List1, List2]>>(
             length(List1, N1), M1 is -N1,
             length(List2, N2), M2 is -N2,
             compare(Order, M1, M2)
         ),
         ["a", "bcd"",cd", "ef", "ghij"],
         Sorted
     ).
Sorted = [[98,99,100,34,44,99,100],[103,104,105,106],[101,102],[97]]
yes
| ?- {types(loader)}.
yes

| ?- list::msort(
         [Order, List1, List2]>>(
             list::length(List1, N1), M1 is -N1,
             list::length(List2, N2), M2 is -N2,
             compare(Order, M1, M2)
         ),
         ["a", "bcd"",cd", "ef", "ghij"],
         Sorted
     ).
Sorted = [[98,99,100,34,44,99,100],[103,104,105,106],[101,102],[97]]
yes