FGK ºÎÈ£


ÇÔ¼ö¸í
enFGK  FGK ºÎÈ£
deFGK  FGK ºÎÈ£·ÎºÎÅÍÀÇ º¹È£
Çü½Ä
FGK ºÎÈ£
    long enFGK(unsigned char *code, long clen,
               unsigned char *text, long tlen);

FGK ºÎÈ£·ÎºÎÅÍÀÇ º¹È£
    long deFGK(unsigned char *text, long tlen,
               unsigned char *code, long clen);
Àμö
FGK ºÎÈ£ ÇÔ¼ö¿¡ ´ëÇØ
    code  (ÀÔÃâ·Â) FGK ºÎÈ£¸¦ °Ý³³ÇÏ´Â ¹è¿­
    clen  (ÀÔ·Â) ¹è¿­ codeÀÇ ±æÀÌ
    text  (ÀÔ·Â) ÅؽºÆ®¸¦ °Ý³³ÇÏ´Â ¹è¿­
    tlen  (ÀÔ·Â) ¹è¿­ textÀÇ ±æÀÌ

FGK ºÎÈ£·ÎºÎÅÍÀÇ º¹È£ ÇÔ¼ö¿¡ ´ëÇØ
    text  (ÀÔÃâ·Â) ÅؽºÆ®¸¦ °Ý³³ÇÏ´Â ¹è¿­
    tlen  (ÀÔ·Â) ¹è¿­ textÀÇ ±æÀÌ
    code  (ÀÔ·Â)  FGK ºÎÈ£¸¦ °Ý³³ÇÏ´Â ¹è¿­
    clen  (ÀÔ·Â) ¹è¿­ codeÀÇ ±æÀÌ
ÇÔ¼öÄ¡
FGK ºÎÈ£ ÇÔ¼ö¿¡ ´ëÇØ
    FGK ºÎÈ£ÀÇ ±æÀÌ. encode¿¡ ½ÇÆÐÇßÀ» ¶§´Â -1L.

FGK ºÎÈ£·ÎºÎÅÍÀÇ º¹È£ ÇÔ¼ö¿¡ ´ëÇØ
    ÅؽºÆ®ÀÇ ±æÀÌ. º¹È£¿¡ ½ÇÆÐÇßÀ» ¶§´Â -1L.
ÁÖÀÇ »çÇ×

¿ë·Ê(fgk-test.c )

ÇÁ·Î±×·¥(fgk.c )
typedef struct {
    int  chr;            /* ¹®ÀÚ */
    long count;          /* ÀÚ ³ëµåÀÇ ÃâÇö ºóµµÀÇ È­ */
    int  parent;         /* Ä£³ëµå¿¡ */
    int  left;           /* ÁÂÃøÀÇ ¾ÆÀÌ ³ëµå¿¡ */
    int  right;          /* ¿ìÃøÀÇ ¾ÆÀÌ ³ëµå¿¡ */
} NODE;

#define ROOT         0                /* ·çÆ® */
#define EOF_NODE     1                /* EOF ³ëµå */
#define CHAR_SIZE    256
#define NODE_SIZE    (2*CHAR_SIZE+2)  /* ³ëµåÀÇ ÃÖ´ë °³¼ö */

long enFGK(unsigned char *code, long clen,
           unsigned char *text, long tlen)
{
    int    i, j, k;
    long   c, len;
    int    curChar;
    int    zeroNode, thisNode, maxid;
    int    node2id[NODE_SIZE];         /* ³ëµå·ÎºÎÅÍ ±× ³ëµå ¹øÈ£ */
    int    char2node[CHAR_SIZE];
    NODE   node[NODE_SIZE]; int freeNode;
    char   bit[NODE_SIZE];  char *bitp;
    static unsigned char bit0[8] = {~128,~64,~32,~16,~8,~4,~2,~1};
    static unsigned char bit1[8] = { 128, 64, 32, 16, 8, 4, 2, 1};

    if (tlen <= 0) return -1L;

    for (i = 0; i < CHAR_SIZE; i++) char2node[i] = 0;

    /* Ãʱâ ÇÏÇÁ¸Ç³ª¹« */
    zeroNode = 2;
    node[2]. count = 0;
    node[2]. parent = ROOT;

    node[EOF_NODE]. count = 1;
    node[EOF_NODE]. parent = ROOT;

    node[ROOT]. count = 0x7FFFFFFFL;
    node[ROOT]. parent = 0;
    node[ROOT]. left = zeroNode;
    node[ROOT]. right = EOF_NODE;

    node2id[zeroNode] = 0;
    node2id[EOF_NODE] = 1;
    node2id[ROOT]     = 2;

    freeNode = 3;

    /* °¢ ¹®ÀÚ¸¦ encode */
    for (i = 0, c = 0, len = 0, bitp = bit; ; c++) {
        /* ÀÔ·Â ¹®ÀÚ¿¡ ´ëÀÀÇÏ´Â ³ëµå */
        if (c >= tlen) thisNode = EOF_NODE;
        else if ((thisNode = char2node[curChar = text[c]]) == 0) {
            thisNode = zeroNode;
            for (j = 7; j >= 0; j--) *bitp++ = curChar & bit1[j];
        }

        /* ºÎÈ£¾î¸¦ ¾ò´Â´Ù */
        k = thisNode;
        do {
            int parent = node[k]. parent;
            *bitp++ = (node[parent]. left == k) ?  0 : 1;
            k = parent;
        } while (k ! = ROOT);

        /* ¿ª¼ø¼­¿¡ Ãâ·Â */
        do {
            if (*--bitp) *code |= bit1[i];
            else         *code &= bit0[i];
            if (++i == 8) {
                code++;
                if (++len > clen) return -1L;
                i = 0;
            }
        } while (bitp ! = bit);

        if (c == tlen) break;    /* EOF */

        /* ÇÏÇÁ¸Ç³ª¹«¸¦ °»½Å */
        while (thisNode ! = ROOT) {
            if (thisNode == zeroNode) {
                for (j = 0; j < freeNode; j++) node2id[j] += 2;
                node[zeroNode]. left  = freeNode;
                node[freeNode]. count = 0;
                node[freeNode]. parent = zeroNode;
                node2id[freeNode] = 0;
                freeNode++;

                node[zeroNode]. right = freeNode;
                node[freeNode]. count = 1;
                node[freeNode]. parent = zeroNode;
                node2id[freeNode] = 1;
                char2node[curChar] = freeNode;     /* ½Å¹®ÀÚ */
                freeNode++;

                thisNode = zeroNode;
                zeroNode = freeNode - 2;
            } else {
                if (node[thisNode]. count == 1 &&
                    node[k = node[thisNode]. parent]. count == 1) {
                    /* 0-³ëµåÀÇ ÇüÁ¦ */
                    for (j = 0, maxid = thisNode; j < freeNode; j++)
                        if (node[j]. count == 1 && j ! = k &&
                            node2id[j] > node2id[maxid]) maxid = j;
                } else {
                    for (j = 0, maxid = thisNode; j < freeNode; j++)
                        if (node[thisNode]. count == node[j]. count &&
                            node2id[j] > node2id[maxid]) maxid = j;
                }
                if (maxid ! = thisNode) {
                    int maxidP = node[maxid]. parent;
                    int thisP  = node[thisNode]. parent;
                    int id = node2id[maxid];

                    if (node[maxidP]. left == maxid)
                         node[maxidP]. left  = thisNode;
                    else node[maxidP]. right = thisNode;
                    if (node[thisP]. left  == thisNode)
                         node[thisP]. left  = maxid;
                    else node[thisP]. right = maxid;
                    node[maxid]. parent = thisP;
                    node[thisNode]. parent = maxidP;
                    
                    node2id[maxid] = node2id[thisNode];
                    node2id[thisNode] = id;
                }
                node[thisNode]. count++;
                thisNode = node[thisNode]. parent;
            }
        }
    }
    if (i > 0) len++;
    return (len > clen) ?  -1L : len;
}

long deFGK(unsigned char *text, long tlen,
           unsigned char *code, long clen)
{
    int    i, j, k;
    long   c, len;
    int    curChar;
    int    zeroNode, thisNode, maxid;
    int    node2id[NODE_SIZE];         /* ³ëµå·ÎºÎÅÍ ±× ³ëµå ¹øÈ£ */
    NODE   node[NODE_SIZE]; int freeNode;
    static unsigned char bit1[8] = { 128, 64, 32, 16, 8, 4, 2, 1};

    if (clen <= 0) return -1L;

    /* Ãʱâ ÇÏÇÁ¸Ç³ª¹« */
    zeroNode = 2;
    node[2]. chr = CHAR_SIZE+1;
    node[2]. count = 0;
    node[2]. parent = ROOT;

    node[EOF_NODE]. chr = CHAR_SIZE;
    node[EOF_NODE]. count = 1;
    node[EOF_NODE]. parent = ROOT;

    node[ROOT]. count = 0x7FFFFFFFL;
    node[ROOT]. parent = 0;
    node[ROOT]. left = zeroNode;
    node[ROOT]. right = EOF_NODE;

    node2id[zeroNode] = 0;
    node2id[EOF_NODE] = 1;
    node2id[ROOT]     = 2;

    freeNode = 3;

    /* º¹È£È­ */
    for (i = 0, c = 0, len = 0; ; ) {
        /* ºÎÈ£¾î¿¡ ´ëÀÀÇÏ´Â ¹®ÀÚ ³ëµå¸¦ ¾ò´Â´Ù */
        thisNode = ROOT;
        do {
            thisNode = (*code & bit1[i]) ?
                 node[thisNode]. right : node[thisNode]. left;
            if (thisNode >= freeNode) return -1L;
            if (++i == 8) {
                code++;
                if (++c > clen) return -1L;
                i = 0;
            }
        } while (node[thisNode]. chr < 0);

        if (thisNode == EOF_NODE) break;     /* EOF */

        if (thisNode == zeroNode) {          /* ½Å¹®ÀÚ */
            curChar = 0;
            for (j = 0; j < 8; j++) {
                if (*code & bit1[i]) curChar |= bit1[j];
                if (++i == 8) {
                    code++;
                    if (++c > clen) return -1L;
                    i = 0;
                }
            }
        } else curChar = node[thisNode]. chr;

        if (++len > tlen) return -1L;
        *text++ = curChar;                  /* ¹®ÀÚÀÇ Ãâ·Â */

        /* ÇÏÇÁ¸Ç³ª¹«¸¦ °»½Å */
        while (thisNode ! = ROOT) {
            if (thisNode == zeroNode) {
                for (j = 0; j < freeNode; j++) node2id[j] += 2;
                node[zeroNode]. left  = freeNode;
                node[freeNode]. count = 0;
                node[freeNode]. parent = zeroNode;
                node2id[freeNode] = 0;
                node[freeNode]. chr = CHAR_SIZE + 1;
                freeNode++;

                node[zeroNode]. right = freeNode;
                node[freeNode]. count = 1;
                node[freeNode]. parent = zeroNode;
                node2id[freeNode] = 1;
                node[freeNode]. chr = curChar;
                freeNode++;

                thisNode = zeroNode;
                node[thisNode]. chr = -1;
                zeroNode = freeNode - 2;
            } else {
                if (node[thisNode]. count == 1 &&
                    node[k = node[thisNode]. parent]. count == 1) {
                    /* 0-³ëµåÀÇ ÇüÁ¦ */
                    for (j = 0, maxid = thisNode; j < freeNode; j++)
                        if (node[j]. count == 1 && j ! = k &&
                            node2id[j] > node2id[maxid]) maxid = j;
                } else {
                    for (j = 0, maxid = thisNode; j < freeNode; j++)
                        if (node[thisNode]. count == node[j]. count &&
                            node2id[j] > node2id[maxid]) maxid = j;
                }
                if (maxid ! = thisNode) {
                    int maxidP = node[maxid]. parent;
                    int thisP  = node[thisNode]. parent;
                    int id = node2id[maxid];

                    if (node[maxidP]. left == maxid)
                         node[maxidP]. left  = thisNode;
                    else node[maxidP]. right = thisNode;
                    if (node[thisP]. left  == thisNode)
                         node[thisP]. left  = maxid;
                    else node[thisP]. right = maxid;
                    node[maxid]. parent = thisP;
                    node[thisNode]. parent = maxidP;

                    node2id[maxid] = node2id[thisNode];
                    node2id[thisNode] = id;
                }
                node[thisNode]. count++;
                thisNode = node[thisNode]. parent;
            }
        }
    }
    return len;
}
¼³¸í
ÇãÇÁ¸¸ ÄÚµù¿¡´Â 2°³ÀÇ ¹®Á¦Á¡ (ÀÌ)°¡ ÀÖ´Ù.

  1. °¢ ¹®ÀÚÀÇ ÃâÇö ºóµµ¸¦ ¿ä±¸ÇÏ·Á¸é , ÀÏ´Ü ÀÔ·Â ÅؽºÆ®¸¦ ÁÖ»ç ÇÏÁö ¾ÊÀ¸¸é ¾È µÈ´Ù. ÇÏÇÁ¸Ç³ª¹«¸¦ ÀÛ¼ºÇÑ ÈÄ, ´Ù½Ã ÀÔ·Â ÅؽºÆ®¸¦ ÁÖ»ç ÇØ, °¢ ¹®ÀÚ¸¦ ½ÇÁ¦ ¿¡ encode ÇÑ´Ù. Áï, ÀÔ·Â ÅؽºÆ®¸¦ 2¹ø ÀоîµéÀÏ ÇÊ¿ä°¡ ÀÖÀ¸¹Ç·Î, ¿Â¶óÀÌ ¿¡¼­ÀÇ ¿ëµµ¿¡´Â ÀûÇÕÇÏÁö ¾Ê´Ù.
  2. º¹È£ ÇÒ ¼ö ÀÖµµ·Ï(µíÀÌ), °¢ ¹®ÀÚ¿Í ºÎÈ£¾î(¶Ç´Â ÇÏÇÁ¸Ç³ª¹«)¿ÍÀÇ ´ëÀÀ °ü°è¸¦ ºÎÈ£ÀÇ ¼±µÎ¿¡ ºÎ°¡ÇØ¾ß ÇÑ´Ù. Áï, ºÎÈ£ ±× ÀÚü ÀÌ¿Ü¿¡ ¿À¹ÙÇí µå ºÎºÐÀÌ ÀÖ´Ù.

ÀÌ·¯ÇÑ ¹®Á¦Á¡À» ÇØ°áÇϱâ À§Çؼ­, ÀÔ·Â ÅؽºÆ®·ÎºÎÅÍ 1 ¹®ÀÚ¸¦ ÀоîµéÀÏ ¶§ ¸¶´Ù, ±× ½ÃÁ¡±îÁöÀÇ °¢ ¹®ÀÚÀÇ ÃâÇö ºóµµ¸¦ Àç°è»êÇØ, ÇÏÇÁ¸Ç³ª¹«¸¦ ´Ù½Ã ¸¸µé¾î , ¹®ÀÚ¸¦ encode ÇÏ´Â °ÍÀÌ °í¾È µÇ¾ú´Ù. ÇÏÇÁ¸Ç³ª¹«´Â ±× ½ÃÁ¡¿¡¼­ÀÇ ÃâÇö ºóµµ¿¡ ´ëÇؼ­ ÃÖÀû (À¸)·Î °è¼Ó µÇµµ·Ï(µíÀÌ) º¯È­ÇϹǷÎ, ÀûÀÀÇü ÇãÇÁ¸¸ ÄÚµùÀ̶ó°í ÇÑ´Ù. ¶Ç ÇÏÇÁ¸Ç³ª¹« ÇÏÁö¸¸ ¹®ÀÚ ¸¶´Ù ¹Ù²î¹Ç·Î, µ¿Àû ÇãÇÁ¸¸ ÄÚµùÀ̶ó°íµµ ÇÑ´Ù.

±×·¯³ª, ½ÇÁ¦·Î ÀÌ¿Í °°ÀÌ ÇØ ÇÏÇÁ¸Ç³ª¹«¸¦ ¹®ÀÚ ¸¶´Ù º¹±¸¼º ÇÏ´Â °ÍÀº, Àϱî ÀÇ °è»ê ½Ã°£ÀÌ °É¸°´Ù. ½ÇÁ¦ÀÇ ÀûÀÀÇü ÇãÇÁ¸¸ ÄÚµù ¾Ë°í¸®Áò¿¡¼­´Â, ÇÏÇÁ¸Ç ³ª¹«ÀÇ º¯ÇüÀ» ÃÖ¼ÒÇÑÀ¸·Î Çϱâ À§ÇÑ ±Ã¸®°¡ ÇÊ¿äÇÏ´Ù.

ÀûÀÀÇü ÇãÇÁ¸¸ ÄÚµùÀ» ÀûÀº °è»ê·®À¸·Î ½ÇÇöµÇ´Â ¾ÆÀ̵ð¾î´Â, ÃÖÃÊ 1970 ³â´ë¿¡ N. Faller ¿Í R. G. Gallager ¿¡ ÀÇÇØ µ¶¸³¿¡ °í¾È µÇ¾ú´Ù. 1985³â¿¡ Knuth °¡ ÀÌ ¾ÆÀ̵ð¾î·Î °³·®À» ´õÇØ FGK ¾Ë°í¸®ÁòÀ» °³¹ßÇß´Ù.

¾Ë°í¸®ÁòÀÇ ±âÃÊ´Â, Gallager ¿¡ ÀÇÇØ Á¤ÀÇµÈ ÇüÁ¦ Á¶°ÇÀÌ´Ù. ÀÖ´Ù ³ª¹«°¡ ÇüÁ¦ Á¶°ÇÀ» ä¿î´Ù´Â °ÍÀº, ·çÆ® ÀÌ¿ÜÀÇ °¢ ³ëµå°¡ 1°³ÀÇ ÇüÁ¦µµ , °Ô´Ù°¡, ³ëµå¸¦ ÇüÁ¦³¢¸®°¡ ¼­·Î ÀÌ¿ôÀÌ µÇµµ·Ï(µíÀÌ) Áß·®°¨ÀÇ ºñÁõ°¡¼ø¼­¿¡ ´Ã¾î³õ´Â °Í ÇÏÁö¸¸ ÇÒ ¼ö ÀÖ´Â °æ¿ì¸¦ ¸»ÇÑ´Ù. Gallager ´Â, ¾î´À ³ª¹«°¡ ÇÏÇÁ¸Ç³ª¹«ÀÎ °ÍÀº, ±× ³ª¹«°¡ ÇüÁ¦ Á¶°ÇÀ» ä¿ì´Â °æ¿ìÀ̸ç, ÇÑÆí ±× °æ¿ì¿¡ ÇÑÁ¤ÇÏ´Â °ÍÀ» ³ªÅ¸³Â´Ù. ¿©±â¼­ ¸»ÇÑ´Ù Áß·®°¨°ú´Â ³ëµåÀÇ ¹®ÀÚ ÃâÇö ºóµµÀÇ °ÍÀ¸·Î, ³»ºÎ ³ëµåÀÇ ¹®ÀÚ ÃâÇö ºóµµ´Â ±× ¾ÆÀÌ ³ëµåÀÇ ±×°ÍÀÇ È­ÀÌ´Ù.

FGK ºÎÈ£¿¡ ´ëÇصµ, Ãʱâ ÇÏÇÁ¸Ç³ª¹«´Â ·çÆ®¿Í ±× ¾ÆÀÌ ³ëµå 2ÀÍ°í µÈ´Ù. 2»ìÀÇ ¾ÆÀÌ ³ëµå´Â, °¢°¢ ¡¸¹ÌÃâÇö ¹®ÀÚ(ÀÌÇÏ 0-³ëµå¶ó°í ºÎ¸¥´Ù)¡¹¶ó°í EOF (ºÎÈ£ÀÇ Á¾·á¸¦ ³ªÅ¸³»´Â Ưº° ±âÈ£)¿¡ ´ëÀÀÇÑ´Ù. 0-³ëµåÀÇ ÃâÇö ºóµµ¸¦ 0, EOF ³ëµåÀÇ ÃâÇö ºóµµ¸¦ 1 À¸·Î ÇÑ´Ù. ¶Ç, ³ëµå ¹øÈ£´Â 0-³ëµå°¡ 0, EOF ³ëµå ÇÏÁö¸¸ 1, ·çÆ®°¡ 2 ÀÇ ¼ø¼­·Î ÇÑ´Ù.

0-³ëµå´Â, ÇöÀç±îÁö ÃâÇöÇÏ°í ÀÖÁö ¾Ê´Â ¹®ÀÚ°¡ óÀ½À¸·Î ÀÔ·Â ÅؽºÆ®Áß¿¡ ³ªÅ¸³µ´Ù ¶§¿¡, ±× ¹®ÀÚ¸¦ encode Çϱâ À§Çؼ­ »ç¿ëÇÑ´Ù. ±× °æ¿ì,0-³ëµå¿¡ ´ëÇÑ ºÎÈ£ ¸»À» Ãâ·ÂÇÑ ÈÄ¿¡, ¹®ÀÚ ±× ÀÚüµµ Ãâ·ÂÇÑ´Ù(¿¹¸¦ µé¾î ASCII ÄÚµåµî¿¡ ÀÇÇÑ´Ù).

ÇÏÇÁ¸Ç³ª¹«¸¦ ÀÌÇÏ¿Í °°ÀÌ °»½ÅÇÑ´Ù.

  1. ÀÔ·Â ¹®ÀÚ¿¡ ´ëÀÀÇÏ´Â ÀÙ³ëµå¿¡ ÁÖ¸ñÇÑ´Ù. ¸¸¾à, óÀ½À¸·Î ³ªÅ¸³­ ¹®ÀÚ À̸é,0-³ëµå¿¡ ÁÖ¸ñÇÑ´Ù.
  2. ÇöÀçÀÇ ÁÖ¸ñÇÏ°í ÀÖ´Â ³ëµå°¡ 0-³ëµåÀÎ °æ¿ì
    0-³ëµå¿¡ ´ëÇؼ­, »õ·Ó°Ô 2°³ÀÇ Áß·®°¨ 0 ÀÇ ¾ÆÀÌ ³ëµå¸¦ µ¡ºÙ¿© ±× ÁßÀÇ ÁÂÃøÀÇ ¾ÆÀÌ ³ëµå¸¦ 0-³ëµå·Î ÇØ, ¿ìÃøÀÇ ¾ÆÀÌ ³ëµå¿¡ óÀ½À¸·Î ³ªÅ¸³­ ¹®ÀÚ¸¦ ³ª´©¾î ¸ÂÈù´Ù. ÁÂÃøÀÇ ³ëµå, ¿ìÃøÀÇ ³ëµå, Áö±Ý±îÁöÀÇ ³ª¹«ÀÇ ³ëµå ¹øÈ£, ¶ó°í ÇÏ´Â ¼ø¼­·Î ³ëµå ¹øÈ£¸¦ ´Ù½Ã ¸Å±ä ÈÄ, ¿ìÃøÀÇ ¾ÆÀÌ ³ëµå¸¦ ÁÖ¸ñÇÑ´Ù.
  3. ÇöÀçÀÇ ÁÖ¸ñÇÏ°í ÀÖ´Â ³ëµå°¡ 0-³ëµåÀÇ ÇüÁ¦ÀÇ °æ¿ì
    ³ëµåÀÇ Áß·®°¨À» 1´Ã¸° ÈÄ, ±× Ä£³ëµå¸¦ ÁÖ¸ñÇÑ´Ù.
  4. ÇöÀçÀÇ ÁÖ¸ñÇÏ°í ÀÖ´Â ³ëµå°¡ »ó±âÀÇ 2. (¿Í)°ú 3. ÀÌ¿ÜÀÇ °æ¿ì
    ÇöÀçÀÇ ³ëµå¿Í °°Àº Áß·®°¨À» °¡Áö´Â ³ëµåÁß¿¡¼­, Á¦ÀÏ ³ëµå ¹øÈ£ÀÇ Å« ³ëµå (À»)¸¦ ã±â(ÀÚ±â ÀÚ½ÅÀÌ¶óµµ ÁÁ´Ù), ±× ³ëµå(¿Í ±× ÀÚ¼Õ)¿Í ÇöÀçÀÇ ³ëµå¸¦ ³Ö°í ¹Ù²Û´Ù. ´ÙÀ½¿¡, ÇöÀçÀÇ ³ëµåÀÇ Áß·®°¨À» 1´Ã¸° ÈÄ, ºÎ¸ðÀÇ ³ëµå¸¦ ÁÖ¸ñÇÑ´Ù.
  5. »ó±âÀÇ 4. ÀÇ Ã³¸®¸¦ ·çÆ®¿¡ µµ´ÞÇÒ ¶§±îÁö ¹Ýº¹ÇÑ´Ù.

°ü·Ã ÇÔ¼ö
¼¨³Í¡¤ÆÄ³ë ºÎÈ£, »ê¼ú ºÎÈ£, ÇãÇÁ¸¸ ÄÚµù, Vitter ºÎÈ£, LZ77 ºÎÈ£, LZW ºÎÈ£