fork download
  1. #include <stdlib.h>
  2. #include <limits.h>
  3. #include <ctype.h>
  4. #include <string.h>
  5. #include <assert.h>
  6.  
  7. #include <stdio.h> /* nur für printf nötig */
  8.  
  9. #include <malloc.h> /* wegen alloca; nicht C-Standard! */
  10.  
  11. /*** mysql Zeugs, ohne das es hier nicht geht; muss natürlich wieder raus ***/
  12. #define UDF_INIT void
  13. typedef long longlong;
  14.  
  15. typedef struct {
  16. int arg_count;
  17. void **args;
  18. int *lengths;
  19. } UDF_ARGS;
  20. /************************************************/
  21.  
  22.  
  23. longlong levenshtein_k_base(UDF_INIT *initid, char *str1, char *str2, int distance, char *is_null, char *error)
  24. {
  25. return 1; /* hier deine Implementierung; ich ging davon aus, dass hier für "beste" Übereinstimmung 0 geliefert wird, sonst >0 */
  26. }
  27.  
  28. longlong abweichung(UDF_INIT *initid,char *suche,char *in,const char *e,int distance,char *is_null,char *error)
  29. {
  30. #define MINDESTLAENGE 4
  31. longlong r=LONG_MAX; /* "schlechteste" Übereinstimmung annehmen */
  32. while( in!=e ) /* im zu durchsuchenden char-Array alle "Worte" durchsuchen, also z.B. "abcd" in "xyz\0qwer\0usw\0" */
  33. {
  34. assert( (printf("%s ? %s\n",suche,in),1) );
  35. if( strlen(suche)>=MINDESTLAENGE && strlen(in)>=MINDESTLAENGE ) /* nur ab MINDESTLAENGE Zeichen die Suche durchführen */
  36. {
  37. if( !strcoll(in,suche) ) return 0; /* falls identisch (inkl. locale), dann "beste" Übereinstimmung liefern + Ende */
  38. if( strstr(in,suche) ) return 0; /* falls enthalten, dann "beste" Übereinstimmung liefern + Ende */
  39. {
  40. longlong tmp=levenshtein_k_base(initid,suche,in,distance,is_null,error);
  41. assert( tmp>=0 ); /* Code geht davon aus, dass keine neg. Werte geliefert werden */
  42. if( 0==tmp )
  43. return 0; /* falls <lv> "beste" Übereinstimmung liefert => Ende */
  44. if( tmp<r ) r=tmp; /* sonst den besten Wert merken */
  45. }
  46. }
  47. in+=strlen(in)+1;
  48. }
  49. return r;
  50. }
  51.  
  52. longlong relevance(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error)
  53. {
  54. longlong r=LONG_MAX; /* "schlechteste" Übereinstimmung annehmen */
  55.  
  56. /* Such-Array bilden z.B. "C Entwickler" => "c\0entwickler\0centwickler\0" */
  57. 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;
  58. while(*e) *e=tolower((unsigned char)*e),e++;
  59. strcpy(++e,s0); s0[strlen(s0)]=' ';
  60. while(*e) {if(*e==' ') memmove(e,e+1,strlen(e)); ++e;} ++e;
  61. c=s0;
  62. while(*c) {if(*c==' ') *c=0; ++c;}
  63. /***************************************************************************/
  64.  
  65. /* Inserattitel-Wörter durchsuchen und Ende, falls "beste" Übereinstimmung hier schon gefunden */
  66. c=s0;
  67. {
  68. 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;
  69. while(*x) *x=tolower((unsigned char)*x),x++;
  70. x=s1;
  71. while(*x) {if(*x==' ') *x=0; ++x;} ++x;
  72. while( c!=e ) /* alle Such-Wörter durchlaufen */
  73. {
  74. longlong tmp=abweichung(initid,c,s1,x,*(int *) args->args[3],is_null,error);
  75. if( 0==tmp )
  76. return 0;
  77. if( tmp<r ) r=tmp;
  78. c+=strlen(c)+1;
  79. }
  80. }
  81.  
  82. /* Inserattext-Wörter durchsuchen und Ende, falls "beste" Übereinstimmung hier gefunden */
  83. c=s0;
  84. {
  85. 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;
  86. while(*x) *x=tolower((unsigned char)*x),x++;
  87. x=s1;
  88. while(*x) {if(*x==' '||*x=='|') *x=0; ++x;} ++x;
  89. while( c!=e )
  90. {
  91. longlong tmp=abweichung(initid,c,s1,x,*(int *) args->args[3],is_null,error);
  92. if( 0==tmp )
  93. return 0;
  94. if( tmp<r ) r=tmp;
  95. c+=strlen(c)+1;
  96. }
  97. }
  98.  
  99. return r; /* "besten" d.h. minimalen Wert vom lev.algo. rückliefern */
  100. }
  101.  
  102. int main()
  103. {
  104. int i=1;
  105. void *s[]={"C Entwickler","Software Developer","Software Entwickler|C Entwickler|Programmierer",&i};
  106. int l[]={12,18,46,0};
  107. UDF_ARGS u={4,s,l};
  108. printf("%ld",relevance(0,&u,0,0));
  109. return 0;
  110. }
  111.  
  112.  
Success #stdin #stdout 0s 1832KB
stdin
Standard input is empty
stdout
c ? software
c ? developer
entwickler ? software
entwickler ? developer
centwickler ? software
centwickler ? developer
c ? software
c ? entwickler
c ? c
c ? entwickler
c ? programmierer
entwickler ? software
entwickler ? entwickler
0