#include #include #include #include size_t match ( const char* string, uint64_t table[][128] ) ; int main () { const char* data[] = { "copyright", "license", "version", "commands", "commandline" }; const char* examples[] = { "copyrihgt", "liecnes", "commandline", "ver" }; const unsigned int N = 10; const unsigned int M = 4; unsigned int i, j; // prepare a table unsigned long table[10][128] = { 0 }; for ( i = 0; i < M; ++i ) for ( j = 0; j < N; ++j ) table[j][data[i][j]] |= 1 << (i * 4); for ( i = 0; i < 4; ++i ) { const char* q = examples[i]; size_t result = match ( q, table ); printf("Q(%s) -> %zd %s\n", q, result, data[result]); } } size_t match ( const char* string, uint64_t table[][128] ) { uint64_t count = 0; size_t i; // scan through string once, updating all counters at once for ( i = 0; string[i]; ++i ) count += table[i][ (size_t) string[i] ]; // find greatest sub-count within count size_t best = 0; size_t best_sub_count = count & 0xf; for ( i = 1; i < 4; ++i ) { size_t sub_count = ( count >>= 4 ) & 0xf; if ( sub_count > best_sub_count ) { best_sub_count = sub_count; best = i; } } return best; }