Bugfix: Allocate the correct amount of memory to avoid crashing
[2dmatching.git] / bm.c
bloba807f7685841adfe3c5aec98d54f2d0c74eb1c02
1 #include "code.h"
3 unsigned int *MatchJump;
5 unsigned int *BackUp;
7 void heur1( int m, unsigned int *CharJump )
9 unsigned int i;
11 for ( i = 0; i < m; i++ )
12 CharJump[i] = m - i -1;
15 void heur2( double *pattern2, int m, int n )
17 unsigned int i, ia, ib;
19 for ( i = 1; i < m; i++ )
20 MatchJump[i] = 2 * m - i;
22 i = n;
23 ia = n + 1;
25 while ( i > 0 ) {
27 BackUp[i] = ia;
29 while ( ia <= m && pattern2[i - 1] != pattern2[i -1] ) {
31 if ( MatchJump[ia] > m - i )
32 MatchJump[ia] = m - i;
33 ia = BackUp[ia];
35 i--;
36 ia--;
39 for ( i = 1; i < ia; i++) {
41 if ( MatchJump[i] > m + ia - i )
42 MatchJump[i] = m + ia - i;
45 ib = BackUp[ia];
47 while ( ia <= m ) {
48 while ( ia <= ib ) {
50 if ( MatchJump[ia] > ib - ia + m )
51 MatchJump[ia] = ib - ia + m;
52 ia++;
54 ib = BackUp[ib];
58 int jump( double *text2, double *pattern2, int m, int mark, unsigned int *CharJump )
60 unsigned int i;
62 for ( i = 0; i < m; i++ )
63 if( text2[mark] == pattern2[i] )
64 return CharJump[i];
65 return m;
68 unsigned int search_bm( double *text2, double *pattern2, int m, int n )
70 #ifndef max
71 #define max(a,b) ((a) > (b) ? (a) : (b))
72 #endif
74 unsigned int *CharJump = ( unsigned int* ) malloc( m * sizeof( unsigned int* ));
76 unsigned int matches = 0;
78 unsigned int ia, ib;
80 unsigned int pattern_marker, text_marker;
82 pattern_marker = m;
84 text_marker = m -1;
86 MatchJump = ( unsigned * ) malloc ( 2 * sizeof ( unsigned ) * ( m + 1 ) );
88 BackUp = MatchJump + m + 1;
90 /* bm uses two heuristics */
91 heur1( m, CharJump );
93 heur2( pattern2, m, n );
95 const int limit = n * n - ( n * ( m - 1 ) );
97 while ( text_marker < limit )
99 /* We have a partial match */
100 if ( text2[text_marker] == pattern2[pattern_marker -1] ) {
101 pattern_marker--;
102 text_marker--;
105 else {
106 ia = jump( text2, pattern2, m, text_marker, CharJump );
107 ib = MatchJump[pattern_marker];
108 text_marker += max( ia, ib );
109 pattern_marker = m;
112 /* We have a match */
113 if ( pattern_marker == 0 ) {
114 matches++;
115 text_marker += m + 1;
116 pattern_marker = m;
120 free( CharJump );
121 return matches;