Simplify Match Algorithm
| ... | ... |
@@ -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 */ |