计算字符串中字符串的出现次数

时间:2014-05-06 10:01:27

标签: prolog

所以我想给出一个关键字列表,每当字符串中遇到一个单词时,我都会递增我的计数器。所以我已经玩了一段时间,但我不能让它发挥作用。这就是我所做的。每当我运行问题时,我都会收到此类错误:ERROR: score/3: Arguments are not sufficiently instantiated

score([],0,document(Title,_)).

score([H|T],Acc,document(Title,_)):-
    sub_string(case_insensitive,H,Title),
    Acc1 is Acc + 1,
    score(T,Acc1,document(Title,_)).

我的查询是这样写的:?- document(T,_),score([rule],Acc,document(T,_)).

1 个答案:

答案 0 :(得分:2)

当您查询score([rule],Acc,document(T,_))时,变量Acc未被实例化(没有值),因此Acc1 is Acc + 1失败,因为没有任何内容可以添加到1参数没有充分实例化)。此外,您的累加器在递归中不断增加,但是当累加器变为零时,您的基本情况会触发(,您的递归基本情况假定累加器减少到零)。

看起来您之前已经看过使用过累加器,但是您正在混合两种不同的方法来使用它们(向上计数或向下计数),并且您没有启动累加器的初始谓词,所以你试图从初始查询中做到这一点。

这是一个带注释的工作版本。你需要从初始累加器开始为零,然后计数。

score(Tags, Count, Document) :-
    score(Tags, 0, Count, Document).      % Start accumulator at zero

% No more tags, so the current accumulator is what our resulting count is
%   and we don't care what the document argument is at this point
score([], A, A, _).

score([Tag|Tags], Acc, Count, document(Title,_)) :-
    sub_string(case_insensitive, Tag, Title),     % Check for Tag in Title
    Acc1 is Acc + 1,                              % Increment acc if found
    score(Tags, Acc1, Count, document(Title,_)).  % Score remaining tags

但还有一个问题:如果sub_string/3失败(找不到一个Tag),那么score/4将完全失败。因此,如果找不到Tag但是没有递增累加器,则需要继续递归。最简单的方法是在递归score/4谓词中使用Prolog if-then-else 构造:

score([Tag|Tags], Acc, Count, document(Title,_)) :-
    (   sub_string(case_insensitive, Tag, Title)  % Check for Tag in Title
    ->  Acc1 is Acc + 1                           % Increment acc if found
    ;   Acc1 = Acc                                % Otherwise, no increment
    ),
    score(Tags, Acc1, Count, document(Title,_)).  % Score remaining tags

使用上述内容,您的查询?- document(T, _), score([rule], Acc, document(T,_)).应该有效。由于只有一个代码,因此结果可能是Acc = 0Acc = 1