📜  移至前端数据转换算法

📅  最后修改于: 2022-05-13 01:57:05.557000             🧑  作者: Mango

移至前端数据转换算法

什么是 MTF 变换?
MTF(移至前端)是一种数据转换算法,它以使转换后的消息更可压缩的方式重组数据,因此用作压缩中的额外步骤。从技术上讲,它是将输入字符序列可逆转换为输出数字数组。

为什么是MTF?
1. 在很多情况下,输出数组给出了频繁重复字符的下位索引,这在数据压缩算法中很有用。

2. 它是在实现构成 Unix 压缩实用程序 bzip2 基础的 Burrows – Wheeler 数据压缩算法时连续执行的三个步骤中的第一个。

MTF背后的主要思想:

1. MTF 背后的主要思想是维护合法符号的有序列表(在我们的示例中为 a 到 z)。

2. 从输入字符串中一次读取一个字符。

3. 打印出该字符出现在列表中的位置。

4. 将该字符移动到列表的前面并重复该过程,直到获得所有输入字符的索引。

Illustration for "panama".  
List initially contains English alphabets in order. 
We one by one characters of input to front.

input_str chars   output_arr       list
  p              15               abcdefghijklmnopqrstuvwxyz
  a              15 1             pabcdefghijklmnoqrstuvwxyz
  n              15 1 14          apbcdefghijklmnoqrstuvwxyz
  a              15 1 14 1        napbcdefghijklmoqrstuvwxyz
  m              15 1 14 1 14     anpbcdefghijklmoqrstuvwxyz
  a              15 1 14 1 14     manpbcdefghijkloqrstuvwxyz

推理:
1. 如果字母在输入中出现多次,那么很多输出值将是小整数,例如 0、1、2 等。

2. 因此,对这些字母进行极高频率的编码是霍夫曼编码的理想方案。

例子:

Input : panama
Output : 15 1 14 1 14 1

Input : geeksforgeeks
Output : 6 5 0 10 18 8 15 18 6 6 0 6 6 

以下是上面解释的想法代码:

// C program to find move to front transform of
// a given string
#include 
#include 
#include 
  
// Returns index at which character of the input text
// exists in the list
int search(char input_char, char* list)
{
    int i;
    for (i = 0; i < strlen(list); i++) {
        if (list[i] == input_char) {
            return i;
            break;
        }
    }
}
  
// Takes curr_index of input_char as argument
// to bring that character to the front of the list
void moveToFront(int curr_index, char* list)
{
    char* record = (char*)malloc(sizeof(char) * 26);
    strcpy(record, list);
  
    // Characters pushed one position right
    // in the list up until curr_index
    strncpy(list + 1, record, curr_index);
  
    // Character at curr_index stored at 0th position
    list[0] = record[curr_index];
}
  
// Move to Front Encoding
void mtfEncode(char* input_text, int len_text, char* list)
{
    int i;
    int* output_arr = (int*)malloc(len_text * sizeof(int));
  
    for (i = 0; i < len_text; i++) {
  
        // Linear Searches the characters of input_text 
        // in list
        output_arr[i] = search(input_text[i], list);
  
        // Printing the Move to Front Transform
        printf("%d ", output_arr[i]);
  
        // Moves the searched character to the front 
        // of the list
        moveToFront(output_arr[i], list);
    }
}
  
// Driver program to test functions above
int main()
{
    char* input_text = "panama";
    int len_text = strlen(input_text);
  
    // Maintains an ordered list of legal symbols
    char* list = (char*)malloc(sizeof(char) * 26);
    strcpy(list, "abcdefghijklmnopqrstuvwxyz");
  
    printf("Input text: %s", input_text);
    printf("\nMove to Front Transform: ");
  
    // Computes Move to Front transform of given text
    mtfEncode(input_text, len_text, list);
    
    return 0;
}

输出:

Input text: panama
Move to Front Transform: 15 1 14 1 14 1

时间复杂度: O(n^2)

练习:实现移到前变换的逆。