From bb32afb18bd06e6843921205987b23641145f51a Mon Sep 17 00:00:00 2001 From: Chen Bin Date: Sat, 14 Apr 2018 10:33:44 +1000 Subject: [PATCH] add api string-distance --- src/fns.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/src/fns.c b/src/fns.c index 94b9d98..b63d4f4 100644 --- a/src/fns.c +++ b/src/fns.c @@ -41,6 +41,8 @@ along with GNU Emacs. If not, see . */ # define gnutls_rnd w32_gnutls_rnd #endif +#define min3(a, b, c) ((a) < (b) ? ((a) < (c) ? (a) : (c)) : ((b) < (c) ? (b) : (c))) + static void sort_vector_copy (Lisp_Object, ptrdiff_t, Lisp_Object *restrict, Lisp_Object *restrict); enum equal_kind { EQUAL_NO_QUIT, EQUAL_PLAIN, EQUAL_INCLUDING_PROPERTIES }; @@ -153,6 +155,33 @@ If STRING is multibyte, this may be greater than the length of STRING. */) return make_number (SBYTES (string)); } +DEFUN ("string-distance", Fstring_distance, Sstring_distance, 2, 2, 0, + doc: /* Return Levenshtein distance of two strings. +Case is significant, but text properties are ignored. */) + (register Lisp_Object string1, Lisp_Object string2) +{ + CHECK_STRING (string1); + CHECK_STRING (string2); + + char *s1 = SSDATA (string1); + char *s2 = SSDATA (string2); + unsigned int s1len, s2len, x, y, lastdiag, olddiag; + s1len = strlen(s1); + s2len = strlen(s2); + unsigned int column[s1len+1]; + for (y = 1; y <= s1len; y++) + column[y] = y; + for (x = 1; x <= s2len; x++) { + column[0] = x; + for (y = 1, lastdiag = x-1; y <= s1len; y++) { + olddiag = column[y]; + column[y] = min3(column[y] + 1, column[y-1] + 1, lastdiag + (s1[y-1] == s2[x-1] ? 0 : 1)); + lastdiag = olddiag; + } + } + return make_number(column[s1len]); +} + DEFUN ("string-equal", Fstring_equal, Sstring_equal, 2, 2, 0, doc: /* Return t if two strings have identical contents. Case is significant, but text properties are ignored. @@ -5226,6 +5255,7 @@ this variable. */); defsubr (&Slength); defsubr (&Ssafe_length); defsubr (&Sstring_bytes); + defsubr (&Sstring_distance); defsubr (&Sstring_equal); defsubr (&Scompare_strings); defsubr (&Sstring_lessp); -- 2.16.3