简体   繁体   English

PROLOG:如何在 prolog 中创建 KMP 算法?

[英]PROLOG: How can I create a KMP algorithm in prolog?

I would like to create KMP in prolog and started working like this.我想在 prolog 中创建 KMP 并开始像这样工作。 Unfortunately, I am unable to create prefix table required for Prolog?不幸的是,我无法创建 Prolog 所需的前缀表? Am i doing it right, considering prolog a logical language?考虑到序言是一种逻辑语言,我做得对吗?

compare(CharAtStartPos,CharAtNextPos,StartPos,NextPos,PrefixList,S,N,P):-
    CharAtStartPos=CharAtNextPos,write('Equal'),
    N is NextPos+1,
    string_chars(N,Element),
    write("Element is"), write(Element),
    S is StartPos+1,!;
    CharAtStartPos\=CharAtNextPos,NextPos\=0,write('Not equal'),
    value is NextPos-1,
    nth0(value,PrefixList, N),!;
    write('Else'),
    string_chars(0,Element),
    P = Element,write("Element is"),
    write(Element),
    S is StartPos+1.

loop(CharAtStartPos,CharAtNextPos,StartPos,NextPos,TextLength,PrefixList):-
    StartPos<TextLength,
    write('Start position is: '),write(StartPos),nl,
    compare(CharAtStartPos,CharAtNextPos, StartPos,NextPos,PrefixList,S,N,P),
    loop(CharAtStartPos,CharAtNextPos,S,N,TextLength,P),!;
    StartPos=TextLength,
    write("Loop end"),
    write(PrefixList).

createPrefixTable(Text,TextLength, PrefixList):-
    getTextAsList(Text,ListText),
    getTextLength(Text,TextLength),
    StartPos=1,NextPos=0,
    nth0(0,ListText,CharAtStartPos), nth0(1,ListText,CharAtNextPos),
    write(StartPos),write(NextPos),nl,
    write(CharAtStartPos),write(CharAtNextPos),nl,
    loop(CharAtStartPos,CharAtNextPos,StartPos, NextPos,TextLength, PrefixList),
    write(PrefixList),
    write("Finish").

Your use of ;您的使用; to implement disjunction is not idiomatic, and it is not correct.实现析取不是惯用的,也不正确。 Even though ;即使; exists you should almost always use separate clauses instead.如果存在,您几乎应该总是使用单独的子句。 This will make it clearer what's going wrong:这将更清楚地说明出了什么问题:

loop(CharAtStartPos,CharAtNextPos,StartPos,NextPos,TextLength,PrefixList):-
    StartPos<TextLength,
    write('Start position is: '),write(StartPos),nl,
    compare(CharAtStartPos,CharAtNextPos, StartPos,NextPos,PrefixList,S,N,P),
    loop(CharAtStartPos,CharAtNextPos,S,N,TextLength,P).
loop(CharAtStartPos,CharAtNextPos,StartPos,NextPos,TextLength,PrefixList):-
    StartPos=TextLength,
    write("Loop end"),
    write(PrefixList).

The second clause does not bind PrefixList in any way.第二个子句不以任何方式绑定PrefixList A caller will never be able to get information out of this predicate!调用者永远无法从这个谓词中获取信息!

I think you probably want to add an "accumulator" argument which "builds up" the prefix list over recursive calls.我想你可能想添加一个“累加器”参数,它通过递归调用“建立”前缀列表。 When the recursion stops, the final result should be the accumulator value.当递归停止时,最终结果应该是累加器值。 Something like this (not tested in any way):像这样(未以任何方式测试):

loop(CharAtStartPos, CharAtNextPos, StartPos, NextPos, TextLength, PrefixList0, PrefixList) :-
    StartPos < TextLength,
    write('Start position is: '), write(StartPos), nl,
    compare(CharAtStartPos, CharAtNextPos, StartPos, NextPos, PrefixList0, S, N, PrefixList1),
    loop(CharAtStartPos, CharAtNextPos, S, N, TextLength, PrefixList1, PrefixList).
loop(CharAtStartPos, CharAtNextPos, StartPos, NextPos, TextLength, PrefixList, PrefixList):-
    StartPos = TextLength,
    write("Loop end"),
    write(PrefixList).

The initial call from "outside" needs to pass a suitable initial accumulator value, something like:来自“外部”的初始调用需要传递一个合适的初始累加器值,例如:

loop(CharAtStartPos, CharAtNextPos, StartPos, NextPos, TextLength, [], PrefixList)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM