Browse code

Simplify Match Algorithm

Binh Tran authored on 18/01/2025 13:38:38
Showing 1 changed files

... ...
@@ -28,8 +28,6 @@ int has_match(const char *needle, const char *haystack) {
28 28
 	return 1;
29 29
 }
30 30
 
31
-#define SWAP(x, y, T) do { T SWAP = x; x = y; y = SWAP; } while (0)
32
-
33 31
 #define max(a, b) (((a) > (b)) ? (a) : (b))
34 32
 
35 33
 struct match_struct {
... ...
@@ -81,6 +79,8 @@ static inline void match_row(const struct match_struct *match, int row, score_t
81 79
 	score_t prev_score = SCORE_MIN;
82 80
 	score_t gap_score = i == n - 1 ? SCORE_GAP_TRAILING : SCORE_GAP_INNER;
83 81
 
82
+	score_t prev_M, prev_D;
83
+
84 84
 	for (int j = 0; j < m; j++) {
85 85
 		if (lower_needle[i] == lower_haystack[j]) {
86 86
 			score_t score = SCORE_MIN;
... ...
@@ -88,14 +88,18 @@ static inline void match_row(const struct match_struct *match, int row, score_t
88 88
 				score = (j * SCORE_GAP_LEADING) + match_bonus[j];
89 89
 			} else if (j) { /* i > 0 && j > 0*/
90 90
 				score = max(
91
-						last_M[j - 1] + match_bonus[j],
91
+						prev_M + match_bonus[j],
92 92
 
93 93
 						/* consecutive match, doesn't stack with match_bonus */
94
-						last_D[j - 1] + SCORE_MATCH_CONSECUTIVE);
94
+						prev_D + SCORE_MATCH_CONSECUTIVE);
95 95
 			}
96
+			prev_D = last_D[j];
97
+			prev_M = last_M[j];
96 98
 			curr_D[j] = score;
97 99
 			curr_M[j] = prev_score = max(score, prev_score + gap_score);
98 100
 		} else {
101
+			prev_D = last_D[j];
102
+			prev_M = last_M[j];
99 103
 			curr_D[j] = SCORE_MIN;
100 104
 			curr_M[j] = prev_score = prev_score + gap_score;
101 105
 		}
... ...
@@ -131,24 +135,13 @@ score_t match(const char *needle, const char *haystack) {
131 135
 	 * D[][] Stores the best score for this position ending with a match.
132 136
 	 * M[][] Stores the best possible score at this position.
133 137
 	 */
134
-	score_t D[2][MATCH_MAX_LEN], M[2][MATCH_MAX_LEN];
135
-
136
-	score_t *last_D, *last_M;
137
-	score_t *curr_D, *curr_M;
138
-
139
-	last_D = D[0];
140
-	last_M = M[0];
141
-	curr_D = D[1];
142
-	curr_M = M[1];
138
+	score_t D[MATCH_MAX_LEN], M[MATCH_MAX_LEN];
143 139
 
144 140
 	for (int i = 0; i < n; i++) {
145
-		match_row(&match, i, curr_D, curr_M, last_D, last_M);
146
-
147
-		SWAP(curr_D, last_D, score_t *);
148
-		SWAP(curr_M, last_M, score_t *);
141
+		match_row(&match, i, D, M, D, M);
149 142
 	}
150 143
 
151
-	return last_M[m - 1];
144
+	return M[m - 1];
152 145
 }
153 146
 
154 147
 score_t match_positions(const char *needle, const char *haystack, size_t *positions) {
... ...
@@ -187,17 +180,9 @@ score_t match_positions(const char *needle, const char *haystack, size_t *positi
187 180
 	M = malloc(sizeof(score_t) * MATCH_MAX_LEN * n);
188 181
 	D = malloc(sizeof(score_t) * MATCH_MAX_LEN * n);
189 182
 
190
-	score_t *last_D = NULL, *last_M = NULL;
191
-	score_t *curr_D, *curr_M;
192
-
193
-	for (int i = 0; i < n; i++) {
194
-		curr_D = &D[i][0];
195
-		curr_M = &M[i][0];
196
-
197
-		match_row(&match, i, curr_D, curr_M, last_D, last_M);
198
-
199
-		last_D = curr_D;
200
-		last_M = curr_M;
183
+	match_row(&match, 0, D[0], M[0], D[0], M[0]);
184
+	for (int i = 1; i < n; i++) {
185
+		match_row(&match, i, D[i], M[i], D[i - 1], M[i - 1]);
201 186
 	}
202 187
 
203 188
 	/* backtrace to find the positions of optimal matching */