mtf算法(关于该算法:https://www2.cs.duke.edu/csed/algoprobs/beta/bw1.html):
#include <stdio.h> #include <string.h> #include <stdlib.h> void mtf_encode(const char *s, unsigned len, int *code) { int pos = 0, num, trace = 0; unsigned i, j, k; int is_hav[26], stack[26]; memset(is_hav, 0, 26); while (*s) { if (!is_hav[*s - 'a']) { stack[pos] = *s - 'a' + 1; is_hav[*s - 'a'] = 1; ++pos; code[trace++] = pos; } else { j = 0; while (stack[j] != *s - 'a' + 1) j++; code[trace++] = j + 1, num = stack[j]; while (j > 0) stack[j] = stack[j - 1], j--; stack[j] = num; } s++; } } void print_mtf_encode(int*code, int len) { unsigned i; printf("["); for (i = 0; i < len; i++) { printf("%d", code[i]); if (i != len - 1) printf(", "); } printf("] "); } int main() { char s[] = "abcabcaaaaaaaab"; int len = strlen(s); int *code = (int *)malloc(sizeof(int) * len); mtf_encode(s, len, code); print_mtf_encode(code, len); free(code); return 0; }
上面算法不是错的,根据题意和不同的思考角度可以编写不同的mtf算法,按字典序排序后的mtf算法(只统计出现的字符):
void mtf_encode(const char *s, unsigned len, int *code) { int num, trace = 0; unsigned i, pos = 0; int is_hav[26], stack[26]; memset(is_hav, 0, 26); for (i = 0; i < len; i++) if (!is_hav[s[i] - 'a']) is_hav[s[i] - 'a'] = s[i] - 'a' + 1; for (i = 0; i < 26; i++) if (is_hav[i] != 0) stack[pos++] = is_hav[i]; while (*s) { pos = 0; while (stack[pos] != *s++ - 'a' + 1) pos++; code[trace++] = pos + 1, num = stack[j]; while (pos > 0) stack[pos] = stack[pos - 1], pos--; stack[pos] = num; } }
rle算法(了解该算法:https://en.wikipedia.org/wiki/Run-length_encoding):
const char*digits = "0123456789"; void comp_bit(char *rle, int *i, int num) { if (num > 9) comp_bit(rle, i, num / 10); rle[(*i)++] = digits[num%10]; } void rle_encode(const char *s, char *rle) { unsigned i = 0, j = 1; rle[i++] = *s++; while (*s) { if (rle[i - 1] != *s) { comp_bit(rle, &i, j); rle[i++] = *s, j = 1; } else j++; s++; } comp_bit(rle, &i, j); }