首页 > 解决方案 > 动态列表中不同元素的总和并制作降序列表

问题描述

于是有了这个功课,基本思路就是模拟卖书。我有:- 动态书/4。书('作者','标题','城市',销售)。在我的 dat 文件中。作者 可以 拥有 多 本书 , 1 本书 可以 在 多个 城市 销售 . 我 可以 模拟 购买 书籍 . 我的问题是我必须根据整体销量写出最畅销的作者和最畅销的城市,并制作一个降序列表,该列表将根据销量按降序写出作者、标题、销量。

我尝试使用 findall 和 forall 方法,但我无法让它像那样工作。

bestsellingauthor:- book(_,_,_,Sale), max(Eladas,All),
    writef('Most popular author is:\n'),
    forall(book(Auth,_,_,All), writef('%w - %w-db\n',[Auth,All])),menu.

stat:- forall(book(Auth,Title,_,Sale),(
              Sale > 0,
        writef('%w - %w - \t%w db \n',[Auth,Title,Sale]))).

所以基本上我希望能够获得一位作者的所有销售额,该作者可能拥有或不超过一本书,并且在统计代码中,我想根据销售额按降序写出该列表。提前谢谢你的帮助。

标签: prolog

解决方案


使用数据库中的这三个事实,使用bagof, 每个作者的每个条目销售:

?- bagof(Sold, Title^City^book(Author, Title, City, Sold), Sales).
Author = 'Authone',
Sales = [235, 225] ;
Author = 'Authtwo',
Sales = [135].

您现在可以对销售进行求和以获得总数并使用外部收集这些bagof

?- bagof(Total-Author, Sales^( bagof(Sold, Title^City^book(Author, Title, City, Sold), Sales), sum_list(Sales, Total) ), Totals), sort(1, @>=, Totals, [Total_sold-Author|_]).
Author = 'Authone',
Totals = [460-'Authone', 135-'Authtwo'],
Total_sold = 460.

我使用了 4 参数版本的排序,以便我可以对第一个参数进行反向排序。

要获取按作者/标题分组的列表:

?- bagof(Sold, City^book(Author, Title, City, Sold), Sales).

并获得按销量降序排列的书籍列表:

?- bagof(Total-book(Author, Title), Sales^( bagof(Sold, City^book(Author, Title, City, Sold), Sales), sum_list(Sales, Total) ), R), sort(1, @>=, R, Result).
R = Result, Result = [235-book('Authone', 'Titleone'), 225-book('Authone', 'Titlethree'), 135-book('Authtwo', 'Titletwo')].

library(aggregate)如果你习惯了这个,你会让你的生活更轻松。然后是这样的:

?- aggregate(sum(Sold), City^Title^book(Author, Title, City, Sold), Total).
Author = 'Authone',
Total = 460 ;
Author = 'Authtwo',
Total = 135.

推荐阅读