#include <stdlib.h>
#include <limits.h>
#include <ctype.h>
#include <string.h>
#include <assert.h>
#include <stdio.h> /* nur für printf nötig */
#include <malloc.h> /* wegen alloca; nicht C-Standard! */
/*** mysql Zeugs, ohne das es hier nicht geht; muss natürlich wieder raus ***/
#define UDF_INIT void
typedef long longlong;
typedef struct {
int arg_count;
void ** args;
int * lengths;
} UDF_ARGS;
/************************************************/
longlong levenshtein_k_base( UDF_INIT * initid, char * str1, char * str2, int distance, char * is_null, char * error)
{
return 1 ; /* hier deine Implementierung; ich ging davon aus, dass hier für "beste" Übereinstimmung 0 geliefert wird, sonst >0 */
}
longlong abweichung( UDF_INIT * initid, char * suche, char * in, const char * e, int distance, char * is_null, char * error)
{
#define MINDESTLAENGE 4
longlong r= LONG_MAX; /* "schlechteste" Übereinstimmung annehmen */
while ( in!= e ) /* im zu durchsuchenden char-Array alle "Worte" durchsuchen, also z.B. "abcd" in "xyz\0qwer\0usw\0" */
{
if ( strlen ( suche
) >= MINDESTLAENGE
&& strlen ( in
) >= MINDESTLAENGE
) /* nur ab MINDESTLAENGE Zeichen die Suche durchführen */ {
if ( ! strcoll ( in
, suche
) ) return 0 ; /* falls identisch (inkl. locale), dann "beste" Übereinstimmung liefern + Ende */ if ( strstr ( in
, suche
) ) return 0 ; /* falls enthalten, dann "beste" Übereinstimmung liefern + Ende */ {
longlong tmp= levenshtein_k_base( initid, suche, in, distance, is_null, error) ;
assert ( tmp
>= 0 ) ; /* Code geht davon aus, dass keine neg. Werte geliefert werden */ if ( 0 == tmp )
return 0 ; /* falls <lv> "beste" Übereinstimmung liefert => Ende */
if ( tmp< r ) r= tmp; /* sonst den besten Wert merken */
}
}
}
return r;
}
longlong relevance( UDF_INIT * initid, UDF_ARGS * args, char * is_null, char * error)
{
longlong r= LONG_MAX; /* "schlechteste" Übereinstimmung annehmen */
/* Such-Array bilden z.B. "C Entwickler" => "c\0entwickler\0centwickler\0" */
char * s0
= alloca
( 2 + 2 * ( args
-> lengths
[ 0 ] ) ) ,* c
= s0
? s0
: ( abort ( ) , NULL
) ,* e
= c
; memcpy ( c
, args
-> args
[ 0 ] , args
-> lengths
[ 0 ] ) ; c
[ args
-> lengths
[ 0 ] ] = 0 ; while ( * e
) * e
= tolower ( ( unsigned char ) * e
) , e
++; c= s0;
while ( * c) { if ( * c== ' ' ) * c= 0 ; ++ c; }
/***************************************************************************/
/* Inserattitel-Wörter durchsuchen und Ende, falls "beste" Übereinstimmung hier schon gefunden */
c= s0;
{
char * s1
= alloca
( 1 + args
-> lengths
[ 1 ] ) ,* x
= s1
? s1
: ( abort ( ) , NULL
) ; memcpy ( x
, args
-> args
[ 1 ] , args
-> lengths
[ 1 ] ) ; x
[ args
-> lengths
[ 1 ] ] = 0 ; while ( * x
) * x
= tolower ( ( unsigned char ) * x
) , x
++; x= s1;
while ( * x) { if ( * x== ' ' ) * x= 0 ; ++ x; } ++ x;
while ( c!= e ) /* alle Such-Wörter durchlaufen */
{
longlong tmp= abweichung( initid, c, s1, x,* ( int * ) args-> args[ 3 ] , is_null, error) ;
if ( 0 == tmp )
return 0 ;
if ( tmp< r ) r= tmp;
}
}
/* Inserattext-Wörter durchsuchen und Ende, falls "beste" Übereinstimmung hier gefunden */
c= s0;
{
char * s1
= alloca
( 1 + args
-> lengths
[ 2 ] ) ,* x
= s1
? s1
: ( abort ( ) , NULL
) ; memcpy ( x
, args
-> args
[ 2 ] , args
-> lengths
[ 2 ] ) ; x
[ args
-> lengths
[ 2 ] ] = 0 ; while ( * x
) * x
= tolower ( ( unsigned char ) * x
) , x
++; x= s1;
while ( * x) { if ( * x== ' ' ||* x== '|' ) * x= 0 ; ++ x; } ++ x;
while ( c!= e )
{
longlong tmp= abweichung( initid, c, s1, x,* ( int * ) args-> args[ 3 ] , is_null, error) ;
if ( 0 == tmp )
return 0 ;
if ( tmp< r ) r= tmp;
}
}
return r; /* "besten" d.h. minimalen Wert vom lev.algo. rückliefern */
}
int main( )
{
int i= 1 ;
void * s[ ] = { "C Entwickler" , "Software Developer" , "Software Entwickler|C Entwickler|Programmierer" ,& i} ;
int l[ ] = { 12 , 18 , 46 , 0 } ;
UDF_ARGS u= { 4 , s, l} ;
printf ( "%ld" , relevance
( 0 ,& u
, 0 , 0 ) ) ; return 0 ;
}
I2luY2x1ZGUgPHN0ZGxpYi5oPgojaW5jbHVkZSA8bGltaXRzLmg+CiNpbmNsdWRlIDxjdHlwZS5oPgojaW5jbHVkZSA8c3RyaW5nLmg+CiNpbmNsdWRlIDxhc3NlcnQuaD4KCiNpbmNsdWRlIDxzdGRpby5oPiAvKiBudXIgZsO8ciBwcmludGYgbsO2dGlnICovCgojaW5jbHVkZSA8bWFsbG9jLmg+IC8qIHdlZ2VuIGFsbG9jYTsgbmljaHQgQy1TdGFuZGFyZCEgKi8KCi8qKiogbXlzcWwgWmV1Z3MsIG9obmUgZGFzIGVzIGhpZXIgbmljaHQgZ2VodDsgbXVzcyBuYXTDvHJsaWNoIHdpZWRlciByYXVzICoqKi8KI2RlZmluZSBVREZfSU5JVCB2b2lkCnR5cGVkZWYgbG9uZyBsb25nbG9uZzsKCnR5cGVkZWYgc3RydWN0IHsKaW50IGFyZ19jb3VudDsKdm9pZCAqKmFyZ3M7CmludCAqbGVuZ3RoczsKfSBVREZfQVJHUzsKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCgpsb25nbG9uZyBsZXZlbnNodGVpbl9rX2Jhc2UoVURGX0lOSVQgKmluaXRpZCwgY2hhciAqc3RyMSwgY2hhciAqc3RyMiwgaW50IGRpc3RhbmNlLCBjaGFyICppc19udWxsLCBjaGFyICplcnJvcikKewogIHJldHVybiAxOyAvKiBoaWVyIGRlaW5lIEltcGxlbWVudGllcnVuZzsgaWNoIGdpbmcgZGF2b24gYXVzLCBkYXNzIGhpZXIgZsO8ciAiYmVzdGUiIMOcYmVyZWluc3RpbW11bmcgMCBnZWxpZWZlcnQgd2lyZCwgc29uc3QgPjAgKi8KfQoKbG9uZ2xvbmcgYWJ3ZWljaHVuZyhVREZfSU5JVCAqaW5pdGlkLGNoYXIgKnN1Y2hlLGNoYXIgKmluLGNvbnN0IGNoYXIgKmUsaW50IGRpc3RhbmNlLGNoYXIgKmlzX251bGwsY2hhciAqZXJyb3IpCnsKI2RlZmluZSBNSU5ERVNUTEFFTkdFIDQKICBsb25nbG9uZyByPUxPTkdfTUFYOyAgLyogInNjaGxlY2h0ZXN0ZSIgw5xiZXJlaW5zdGltbXVuZyBhbm5laG1lbiAqLwogIHdoaWxlKCBpbiE9ZSApICAvKiBpbSB6dSBkdXJjaHN1Y2hlbmRlbiBjaGFyLUFycmF5IGFsbGUgIldvcnRlIiBkdXJjaHN1Y2hlbiwgYWxzbyB6LkIuICJhYmNkIiBpbiAieHl6XDBxd2VyXDB1c3dcMCIgKi8KICB7CiAgICBhc3NlcnQoIChwcmludGYoIiVzID8gJXNcbiIsc3VjaGUsaW4pLDEpICk7CiAgICBpZiggc3RybGVuKHN1Y2hlKT49TUlOREVTVExBRU5HRSAmJiBzdHJsZW4oaW4pPj1NSU5ERVNUTEFFTkdFICkgICAvKiBudXIgYWIgTUlOREVTVExBRU5HRSBaZWljaGVuIGRpZSBTdWNoZSBkdXJjaGbDvGhyZW4gKi8KICAgIHsKICAgICAgaWYoICFzdHJjb2xsKGluLHN1Y2hlKSApIHJldHVybiAwOyAvKiBmYWxscyBpZGVudGlzY2ggKGlua2wuIGxvY2FsZSksIGRhbm4gImJlc3RlIiDDnGJlcmVpbnN0aW1tdW5nIGxpZWZlcm4gKyBFbmRlICovCiAgICAgIGlmKCAgc3Ryc3RyKGluLHN1Y2hlKSApIHJldHVybiAwOyAgLyogZmFsbHMgZW50aGFsdGVuLCBkYW5uICJiZXN0ZSIgw5xiZXJlaW5zdGltbXVuZyBsaWVmZXJuICsgRW5kZSAqLwogICAgICB7CiAgICAgICAgbG9uZ2xvbmcgdG1wPWxldmVuc2h0ZWluX2tfYmFzZShpbml0aWQsc3VjaGUsaW4sZGlzdGFuY2UsaXNfbnVsbCxlcnJvcik7CiAgICAgICAgYXNzZXJ0KCB0bXA+PTAgKTsgIC8qIENvZGUgZ2VodCBkYXZvbiBhdXMsIGRhc3Mga2VpbmUgbmVnLiBXZXJ0ZSBnZWxpZWZlcnQgd2VyZGVuICovCiAgICAgICAgaWYoIDA9PXRtcCApCiAgICAgICAgICByZXR1cm4gMDsgLyogZmFsbHMgPGx2PiAiYmVzdGUiIMOcYmVyZWluc3RpbW11bmcgbGllZmVydCA9PiBFbmRlICovCiAgICAgICAgaWYoIHRtcDxyICkgcj10bXA7IC8qIHNvbnN0IGRlbiBiZXN0ZW4gV2VydCBtZXJrZW4gKi8KICAgICAgfQogICAgfQogICAgaW4rPXN0cmxlbihpbikrMTsKICB9CiAgcmV0dXJuIHI7Cn0KCmxvbmdsb25nIHJlbGV2YW5jZShVREZfSU5JVCAqaW5pdGlkLCBVREZfQVJHUyAqYXJncywgY2hhciAqaXNfbnVsbCwgY2hhciAqZXJyb3IpCnsKICBsb25nbG9uZyByPUxPTkdfTUFYOyAgLyogInNjaGxlY2h0ZXN0ZSIgw5xiZXJlaW5zdGltbXVuZyBhbm5laG1lbiAqLwoKICAvKiBTdWNoLUFycmF5IGJpbGRlbiB6LkIuICJDIEVudHdpY2tsZXIiID0+ICJjXDBlbnR3aWNrbGVyXDBjZW50d2lja2xlclwwIiAqLwogIGNoYXIgKnMwPWFsbG9jYSgyKzIqKGFyZ3MtPmxlbmd0aHNbMF0pKSwqYz1zMD9zMDooYWJvcnQoKSxOVUxMKSwqZT1jOyAgbWVtY3B5KGMsYXJncy0+YXJnc1swXSxhcmdzLT5sZW5ndGhzWzBdKTtjW2FyZ3MtPmxlbmd0aHNbMF1dPTA7CiAgd2hpbGUoKmUpICplPXRvbG93ZXIoKHVuc2lnbmVkIGNoYXIpKmUpLGUrKzsKICBzdHJjcHkoKytlLHMwKTsgIHMwW3N0cmxlbihzMCldPScgJzsKICB3aGlsZSgqZSkge2lmKCplPT0nICcpIG1lbW1vdmUoZSxlKzEsc3RybGVuKGUpKTsgKytlO30gKytlOwogIGM9czA7CiAgd2hpbGUoKmMpIHtpZigqYz09JyAnKSAqYz0wOyArK2M7fQogIC8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgogIC8qIEluc2VyYXR0aXRlbC1Xw7ZydGVyIGR1cmNoc3VjaGVuIHVuZCBFbmRlLCBmYWxscyAiYmVzdGUiIMOcYmVyZWluc3RpbW11bmcgaGllciBzY2hvbiBnZWZ1bmRlbiAqLwogIGM9czA7CiAgewogICAgY2hhciAqczE9YWxsb2NhKDErYXJncy0+bGVuZ3Roc1sxXSksKng9czE/czE6KGFib3J0KCksTlVMTCk7IG1lbWNweSh4LGFyZ3MtPmFyZ3NbMV0sYXJncy0+bGVuZ3Roc1sxXSk7eFthcmdzLT5sZW5ndGhzWzFdXT0wOwogICAgd2hpbGUoKngpICp4PXRvbG93ZXIoKHVuc2lnbmVkIGNoYXIpKngpLHgrKzsKICAgIHg9czE7CiAgICB3aGlsZSgqeCkge2lmKCp4PT0nICcpICp4PTA7ICsreDt9ICsreDsKICAgIHdoaWxlKCBjIT1lICkgLyogYWxsZSBTdWNoLVfDtnJ0ZXIgZHVyY2hsYXVmZW4gKi8KICAgIHsKICAgICAgbG9uZ2xvbmcgdG1wPWFid2VpY2h1bmcoaW5pdGlkLGMsczEseCwqKGludCAqKSBhcmdzLT5hcmdzWzNdLGlzX251bGwsZXJyb3IpOwogICAgICBpZiggMD09dG1wICkKICAgICAgICByZXR1cm4gMDsKICAgICAgaWYoIHRtcDxyICkgcj10bXA7CiAgICAgIGMrPXN0cmxlbihjKSsxOwogICAgfQogIH0KCiAgLyogSW5zZXJhdHRleHQtV8O2cnRlciBkdXJjaHN1Y2hlbiB1bmQgRW5kZSwgZmFsbHMgImJlc3RlIiDDnGJlcmVpbnN0aW1tdW5nIGhpZXIgZ2VmdW5kZW4gKi8KICBjPXMwOwogIHsKICAgIGNoYXIgKnMxPWFsbG9jYSgxK2FyZ3MtPmxlbmd0aHNbMl0pLCp4PXMxP3MxOihhYm9ydCgpLE5VTEwpOyBtZW1jcHkoeCxhcmdzLT5hcmdzWzJdLGFyZ3MtPmxlbmd0aHNbMl0pO3hbYXJncy0+bGVuZ3Roc1syXV09MDsKICAgIHdoaWxlKCp4KSAqeD10b2xvd2VyKCh1bnNpZ25lZCBjaGFyKSp4KSx4Kys7CiAgICB4PXMxOwogICAgd2hpbGUoKngpIHtpZigqeD09JyAnfHwqeD09J3wnKSAqeD0wOyArK3g7fSArK3g7CiAgICB3aGlsZSggYyE9ZSApCiAgICB7CiAgICAgIGxvbmdsb25nIHRtcD1hYndlaWNodW5nKGluaXRpZCxjLHMxLHgsKihpbnQgKikgYXJncy0+YXJnc1szXSxpc19udWxsLGVycm9yKTsKICAgICAgaWYoIDA9PXRtcCApCiAgICAgICAgcmV0dXJuIDA7CiAgICAgIGlmKCB0bXA8ciApIHI9dG1wOwogICAgICBjKz1zdHJsZW4oYykrMTsKICAgIH0KICB9CgogIHJldHVybiByOyAvKiAiYmVzdGVuIiBkLmguIG1pbmltYWxlbiBXZXJ0IHZvbSBsZXYuYWxnby4gcsO8Y2tsaWVmZXJuICovCn0KCmludCBtYWluKCkKewogIGludCBpPTE7CiAgdm9pZCAqc1tdPXsiQyBFbnR3aWNrbGVyIiwiU29mdHdhcmUgRGV2ZWxvcGVyIiwiU29mdHdhcmUgRW50d2lja2xlcnxDIEVudHdpY2tsZXJ8UHJvZ3JhbW1pZXJlciIsJml9OwogIGludCBsW109ezEyLDE4LDQ2LDB9OwogIFVERl9BUkdTIHU9ezQscyxsfTsKICBwcmludGYoIiVsZCIscmVsZXZhbmNlKDAsJnUsMCwwKSk7CiAgcmV0dXJuIDA7Cn0KCg==