Skip to content

Instantly share code, notes, and snippets.

@pioz
Created April 13, 2011 14:22
Show Gist options
  • Select an option

  • Save pioz/917630 to your computer and use it in GitHub Desktop.

Select an option

Save pioz/917630 to your computer and use it in GitHub Desktop.
Fuzzy searching
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <stdio.h>
const char *
bitap_fuzzy_search (const char *text, const char *pattern, int errors)
{
const char *result = NULL;
int m = strlen (pattern);
unsigned long *R;
unsigned long bitmasks[CHAR_MAX + 1];
int i, d;
if (pattern[0] == '\0') return text;
if (m > 31) return "The pattern is too long!";
/* Initialize the bit array R */
R = malloc ((errors + 1) * sizeof (*R));
for (i = 0; i <= errors; ++i)
R[i] = ~1;
/* Initialize the pattern bitmaskss */
for (i = 0; i <= CHAR_MAX; ++i)
bitmasks[i] = ~0;
for (i = 0; i < m; ++i)
bitmasks[pattern[i]] &= ~(1UL << i);
for (i = 0; text[i] != '\0'; ++i)
{
/* Update the bit arrays */
unsigned long old_Rd1 = R[0];
R[0] |= bitmasks[text[i]];
R[0] <<= 1;
for (d = 1; d <= errors; ++d)
{
unsigned long tmp = R[d];
/* Substitution is all we care about */
R[d] = (old_Rd1 & (R[d] | bitmasks[text[i]])) << 1;
old_Rd1 = tmp;
}
if (0 == (R[errors] & (1UL << m)))
{
result = (text + i - m) + 1;
break;
}
}
free (R);
return result;
}
int
main (int argc, char *argv[])
{
if (argv[1] && argv[2])
printf ("%s\n", bitap_fuzzy_search(argv[1], argv[2], argv[3] ? atoi (argv[3]) : 3));
else
printf ("Usage: %s TEXT PATTERN [ERRORS]\n", argv[0]);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment