【问题标题】:PROLOG: How can I create a KMP algorithm in prolog?PROLOG:如何在 prolog 中创建 KMP 算法?
【发布时间】:2020-08-23 17:36:51
【问题描述】:

我想在 prolog 中创建 KMP 并开始像这样工作。不幸的是,我无法创建 Prolog 所需的前缀表?考虑到 prolog 是一种逻辑语言,我做得对吗?

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").

【问题讨论】:

    标签: prolog knuth-morris-pratt


    【解决方案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).
    loop(CharAtStartPos,CharAtNextPos,StartPos,NextPos,TextLength,PrefixList):-
        StartPos=TextLength,
        write("Loop end"),
        write(PrefixList).
    

    第二个子句不以任何方式绑定PrefixList。调用者将永远无法从该谓词中获取信息!

    我认为您可能想要添加一个“累加器”参数,它通过递归调用“构建”前缀列表。当递归停止时,最终结果应该是累加器的值。像这样的东西(未经任何测试):

    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).
    

    来自“外部”的初始调用需要传递一个合适的初始累加器值,例如:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-03-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多