Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- --drop function meta_form_map.COMPARE_STRINGS(text, text, boolean, boolean);
- -- определить степень похожести строк
- CREATE OR REPLACE FUNCTION meta_form_map.COMPARE_STRINGS
- (
- S1 text, -- первая строка
- S2 text, -- вторая строка
- IGNORE_CASE boolean = FALSE, -- игнорировать регистр
- RELATIVE_LENGTH boolean = FALSE -- если задано, возвращает относительную разницу строк
- )
- RETURNS real LANGUAGE plpgsql
- AS $FUNCTION$
- declare
- valueOfReplace real = 1.0; -- цена замены символа строки
- valueOfDelete real = 1.0; -- цена удаления символа строки
- valueOfInsert real = 1.0; -- цена вставки символа строки
- L1 integer; -- длина первой строки
- L2 integer; -- длина второй строки
- C1 integer;
- C2 integer;
- DIFFERENCE real;
- D real[][];
- BEGIN
- IF IGNORE_CASE THEN
- -- игнорируем регистр
- S1 := upper(S1);
- S2 := upper(S2);
- END IF;
- -- длины строк
- L1 := length(S1);
- L2 := length(S2);
- -- создаем массив
- D := array_fill(0, array[L1 + 1, L2 + 1]);
- -- начальная инициализация
- FOR i IN 1..L1 + 1 LOOP
- D[i][1] := (i - 1)::real;
- END LOOP;
- FOR j IN 1..L2 + 1 LOOP
- D[1][j] := (j - 1)::real;
- END LOOP;
- -- главный цикл
- FOR i IN 2..L1 + 1 LOOP
- FOR j IN 2..L2 + 1 LOOP
- -- если символы совпадают то ничего делать не надо
- C1 := ascii(substring(S1 from i - 1 for 1));
- C2 := ascii(substring(S2 from j - 1 for 1));
- DIFFERENCE := case when C1 = C2 then 0 else 1 end::real;
- D[i][j] := least
- (
- D[i - 1][j] + valueOfDelete,
- D[i][j - 1] + valueOfInsert,
- D[i - 1][j - 1] + valueOfReplace * DIFFERENCE
- );
- END LOOP;
- END LOOP;
- -- отладочный вывод
- --RAISE NOTICE 'D: %', D;
- IF RELATIVE_LENGTH THEN
- RETURN D[L1 + 1][L2 + 1] / greatest(L1, L2)::real;
- ELSE
- RETURN D[L1 + 1][L2 + 1];
- END IF;
- END;
- $FUNCTION$
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement