Инструменты пользователя

Инструменты сайта


cp:obx-lcs

Наибольшая общая подпоследовательность

Данная реализация основана на реализации C++.

Отличие состоит в том, что вместо строки возвращаются начальная позиция подстроки в строке a и её длина.

MODULE DemoLCS;
 
IMPORT Log, Strings;
 
(* Longest Common Substring (LCS) *)
 
PROCEDURE FindLCS* (IN a, b: ARRAY OF CHAR; OUT start, len: INTEGER);
VAR
    max_len: POINTER TO ARRAY OF ARRAY OF INTEGER;
    i, j, alen, blen: INTEGER;
    on: BOOLEAN;
 
BEGIN
    alen := LEN(a$);
    blen := LEN(b$);
    (* Important: we use arrays of size (|A|+1) x (|B|+1) *)
    NEW(max_len, alen + 1, blen + 1);
 
    FOR i := alen - 1 TO 0 BY -1 DO
        FOR j := blen - 1 TO 0 BY -1 DO
            IF a[i] = b[j] THEN
                max_len[i, j] := 1 + max_len[i + 1, j + 1]
            ELSE
                max_len[i, j] := MAX(max_len[i + 1, j], max_len[i, j + 1])
            END
        END
    END;
 
    i := 0; j := 0; len := 0; on := FALSE;
    WHILE (max_len[i, j] # 0) & (i < alen) & (j < blen) DO
        IF a[i] = b[j] THEN
            IF ~on THEN
                on := TRUE; start := i
            END;
            INC(len);
            INC(i);
            INC(j)
        ELSIF max_len[i, j] = max_len[i + 1, j] THEN
            INC(i)
        ELSE
            INC(j)
        END
    END
END FindLCS;
 
(* Пример использования *)
PROCEDURE Do*;
VAR
    start, len: INTEGER;
    s1, s2, s: ARRAY 128 OF CHAR;
BEGIN
    s1 := "sccdeffou";
    s2 := "hrtfjjcdefy";
    FindLCS(s1, s2, start, len);
    Strings.Extract(s1, start, len, s);
    Log.String("Longest common substring: " + s); Log.Ln
END Do;
 
END DemoLCS.
cp/obx-lcs.txt · Последнее изменение: 2024/05/24 17:47 — iadenisov