/* search.c -- search for ELS's spelling out the given word */ #include #include #include "ios.h" /* using the input/output service module */ #include "book.h" /* using the text keeper module */ /* min and max macros */ #define max(a,b) (((a) > (b)) ? (a) : (b)) #define min(a,b) (((a) < (b)) ? (a) : (b)) #define ERR_MODE 1 #define ERR_LONG_WORD 2 #define ERR_SHORT_WORD 3 #define ERR_WORD_ILLEGAL 4 #define NORMALIZATION 10 static FILE * outfile; static char Word [15]; static float LetterTab [256]; static int WordLength; static long int TextLen; static long Search ( long maxsk, int mode ); static int Word_is_symetric ( void ); void main ( int argc, char * argv [] ) { char c; int k, n, mode; long int N, max_skip; char * from; double prob, fwl, faux; if ( argc < 4 ) err_command_line ( "search mode infile outfile" ); mode = -1; c = argv [1] [0]; if ( c == '0' ) mode = 0; if ( c == '1' ) mode = 1; if ( c == '2' ) mode = 2; if ( argv [1] [1] != 0 ) mode = -1; if ( mode < 0 ) { printf ( "mode \"%s\" is neither 0 nor 1 nor 2\n", argv [1] ); exit ( ERR_MODE ); } open_input_file ( argv [2] ); WordLength = get_line_sure ( & from ); if ( WordLength > 15 ) { printf ( "word length exceeds 15\n" ); exit ( ERR_LONG_WORD ); } if ( WordLength < 5 ) { printf ( "word length %d is less than 5\n", WordLength ); exit ( ERR_SHORT_WORD ); } for ( k=0; k= 0 ) { c = from [n]; if ( c == '.' ) { toBOOK ( TextLen++, 0 ); continue; } k = c - 'a' + 1; if ( ( 0 < k ) && ( k < 16 ) ) toBOOK ( TextLen++, k ); } } for ( k=0; k<256; k++ ) LetterTab [k] = 0.0F; for ( N=0; N= 0 ) max_skip = (long int) ( ( 2.0 * (double) TextLen - fwl - sqrt (faux) ) / ( 2.0 * fwl ) ); else max_skip = (long int) ( (double) TextLen / fwl ); max_skip += 2; outfile = open_output_file ( argv [3] ); fprintf ( outfile, "[%3d%7ld%7ld]\n", WordLength, TextLen, max_skip ); Search ( max_skip, mode); exit (0); } static long Search ( long maxsk, int mode) { long int Letter2_min, Letter2_max, Letter2_pnt; long int pn, p, pnx, pny, pnz; char *lp, *lpx, *lpy, *lpz; long int sk; int llen,lenl,x,y,z; long int times; long int minsk; if ( Word_is_symetric () ) { printf("word is symetric, search only for positive skips\n"); minsk = 0; } else minsk = -maxsk; times=0; llen=WordLength; lenl=llen-1; lpx=Word+llen-3; lpy=lpx+1; lpz=lpx+2; p = 0; /* lower bound for the first letter occurrence */ do { /*** LOOP on the first letter ***/ /* find an occurrence of the first letter */ p = searchBOOK ( p, TextLen, Word[0] ); if ( p < 0 ) break; /* if not found - BREAK THE LOOP */ /* upper bound for the second letter occurrence */ Letter2_max = min ( p + maxsk, p + (TextLen-1-p)/lenl ); /* lower bound for the second letter occurrence */ Letter2_min = max ( p + minsk, p - p/lenl ); Letter2_pnt = Letter2_min; do { /*** LOOP on the second letter ***/ /* find an occurrence of the second letter */ Letter2_pnt = searchBOOK ( Letter2_pnt, Letter2_max+1, Word[1] ); if ( Letter2_pnt < 0 ) break; /* if not found - BREAK THE LOOP */ sk = Letter2_pnt - p; lp = Word + 1; pn = p + sk; while (++lp < lpx) { pn += sk; if ( fromBOOK (pn) != *lp ) break; } if (lp == lpx) { pnx = pn + sk - mode; x = - mode; do { while ( (int)*lpx != fromBOOK (pnx) ) { x++; pnx++; if (x > mode) break; } if (x > mode) break; pny = pnx + sk - mode; y = -mode; do { while ( (int)*lpy != fromBOOK (pny) ) { y++; pny++; if (y > mode) break; } if (y > mode) { x++; pnx++; break; } pnz =pny + sk - mode; z = -mode; do { while ( (int)*lpz != fromBOOK (pnz) ) { z++; pnz++; if (z > mode) break; } if (z > mode ) { y++; pny++; break; } if (labs(sk) > 1) { fprintf ( outfile, "[ %2d %2d %2d ", x,y,z ); fprintf ( outfile, "%6ld ", p); fprintf ( outfile, "%5d ]\n", sk ); times++; } z++; pnz++; } while (1); } while (1); } while (1); } ++Letter2_pnt; } while (1); /*** END OF LOOP on the second letter ***/ ++p; } while (1); /*** END OF LOOP on the first letter ***/ printf("times= %d\n",times); return times; } static int Word_is_symetric ( void ) { int k; for ( k=0; k