home *** CD-ROM | disk | FTP | other *** search
- /**** Einfache Levenshtein-Distanz (p0=q0=r0=1) ****/
- /**** mit Berƒcksichtigung von Wildcards ****/
- /**** (geschwindigkeitsoptimiertes C-Programm) ****/
- /**** Autor : JÜrg Michael, Hannover ****/
- /**** Datum : 22. Dezember 1993 ****/
-
- /**** modus = ╒ ╒: normale Levenshtein-Distanz ****/
- /**** modus = ╒+╒: keine Unterscheidung ****/
- /**** Klein-/Groºschreibung ****/
- /**** modus = ╒*╒: wie ╒+╒, aber zusètzlich ****/
- /**** "symmetrisches" Verhalten ****/
- /**** gemèº der im Text beschrie- ****/
- /**** benen Vorformatierung ****/
-
- #define maxlen 51
- char *strchr();
-
- int formatierung (char ziel[], char wort[], int n, char modus)
-
- /**** Wandelt "wort" in GROSSschreibung ****/
- /**** um und expandiert Umlaute ****/
- /**** (n = Zeichenzahl von "ziel") ****/
- /**** Zurƒckgegeben wird: strlen (ziel) ****/
- {
- int i,k;
- char c,*s;
-
- i = 0;
- k = 0;
- while ((c = wort[i++]) != 0 && k < n-1)
- {
- if (isupper (c) || isdigit (c))
- {
- ziel [k++] = c;
- }
- else if (islower (c))
- {
- ziel [k++] = c -╒a╒+╒A╒;
- }
-
- else
- {
- s = strchr ("ÇAEèAEàOEÜOEåUEƒUEºSS", c);
- if (*s != NULL)
- {
- ziel [k++] = *(s+1);
- if (k < n-1)
- {
- ziel [k++] = *(s+2);
- }
- }
- else if (modus == ╒*╒ && c != ╒?╒)
- {
- /**** Aufeinanderfolgende ╒*╒ ****/
- /**** zu einem zusammenziehen ****/
- if (k == 0 || ziel [k-1] != ╒*╒)
- {
- ziel [k++] = ╒*╒;
- }
- }
- else
- {
- ziel [k++] = c;
- }
- }
- }
- ziel[k] = 0;
- return (k);
- }
-
- int WLD (char *wort, char *muster, char modus, int limit)
- {
- register int spmin,
- p,q,r,
- lm,lw,
- d1,d2,
- i,k,
- x1,x2,x3;
- char c,
- mm[maxlen],
- ww[maxlen];
- int d[maxlen];
-
- if (modus == ╒+╒ || modus == ╒*╒)
- {
- lw = formatierung (ww, wort, maxlen,modus);
- lm = formatierung (mm,muster,maxlen,modus);
-
- if (modus == ╒*╒ && lw < lm-1
- && strchr (ww,╒*╒) != NULL)
- {
- /**** Wort und Muster tauschen ****/
- wort = mm;
- muster = ww;
- strcpy (ww+lw, "*");
- i = lw;
- lw = lm;
- lm = i+1;
- /**** Limit neu setzen ****/
- i = (int)(i/3);
- if (i < limit)
- {
- limit = i;
- }
- }
- else
- {
- wort = ww;
- muster = mm;
- }
- }
- else
- {
- lw = strlen (wort);
- lm = strlen (muster);
- if (lw >= maxlen) lw = (maxlen-1);
- if (lm >= maxlen) lm = (maxlen-1);
- }
-
- /**** Anfangswerte berechnen ****/
- if (*muster == ╒*╒)
- {
- for (k=0; k<=lw; k++)
- {
- d[k] = 0;
- }
- }
- else
- {
- d[0] = (*muster == 0) ? 0 : 1;
- i = (*muster == ╒?╒) ? 0 : 1;
- for (k=1; k<=lw; k++)
- {
- if (*muster == *(wort+k-1))
- {
- i = 0;
- }
- d[k] = k-1 + i;
- }
- }
-
- spmin = (d[0] == 0 || lw == 0) ? d[0] : d[1];
- if (spmin > limit)
- {
- return (maxlen);
- }
-
- /**** Distanzmatrix durchrechnen ****/
- for (i=2; i<=lm; i++)
- {
- c = *(muster+i-1);
- p = (c == ╒*╒ || c == ╒?╒) ? 0 : 1;
- q = (c == ╒*╒) ? 0 : 1;
- r = (c == ╒*╒) ? 0 : 1;
- d2 = d[0];
- d[0] = d2 + q;
- spmin = d[0];
-
- for (k=1; k<=lw; k++)
- {
- /**** d[k] = Minimum dreier Zahlen ****/
- d1 = d2;
- d2 = d[k];
- x1 = d1 + ((c == *(wort+k-1)) ? 0 : p);
- x2 = d2 + q;
- x3 = d[k-1] + r;
-
- if (x1 < x2)
- {
- x2 = x1;
- }
- d[k] = (x2 < x3) ? x2 : x3;
-
- if (d[k] < spmin)
- {
- spmin = d[k];
- }
- }
-
- if (spmin > limit)
- {
- return (maxlen);
- }
- }
- return ((d[lw] <= limit) ? d[lw] : maxlen);
- }
-