28
Oct

"Zmenšení" pole

Před pár týdny jsem do jednoho projektu potřeboval “zmenšit” pole. Šlo o to, že čísla v poli se posílala poměrně omezeným kanálem (mail+url) a vzhledem k tomu, že to byla IDčka záznamů z DB, která byla plus mínus “za sebou” a rostla s časem chtělo to mít alespoň trochu konstatní velikost výsledku (až budou IDčka v řádu tisíců zbytečně plýtváme). Udělal jsem proto triviální “pack” a “unpack”.

// the array SHOULD be sorted< ?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

static int[] Pack(int[] input)

{

//we need at least 2 items in array

if (!(input.Length > 1))

throw new ArgumentException();

int[] result = new int[input.Length];

result[0] = input[0];

for (int i = 1; i < input.Length; i++)

{

result[i] = input[i] – input[i - 1];

}

return result;

}

static int[] Unpack(int[] input)

{

//we need at least 2 items in array

if (!(input.Length > 1))

throw new ArgumentException();

int[] result = new int[input.Length];

result[0] = input[0];

for (int i = 1; i < input.Length; i++)

{

result[i] = result[i - 1] + input[i];

}

return result;

}

Pokud jsou ID přibližně za sebou (což jsem já měl) a nejsou tam velké skoky, můžeme tímto poměrně dost znaků ušetřit.

Pozn.: Nakonec se tento postup stejně nepoužil, takže to byla práce do šuplíku na blog. V případě použití doporučuji pořádně otestovat. :)

Ukázka:
Input:
1000
1001
1002
1003
1010

Pack:
1000
1
1
1
7

Unpack:
1000
1001
1002
1003
1010

  • Twitter
  • Facebook
  • Share/Bookmark

There's 10 Comments So Far

  • Martin Hassman
    October 28th, 2007 at 13:10

    Ten kod v clanku bude o neco prehledensi, kdyz se v nem vypne generovani smajliku 8-)

  • cincura.net
    October 28th, 2007 at 13:33

    Kdybych vedel jak to udelat, tak bych to vypnul. Ale nemam sajnu. :)

  • Brano
    October 29th, 2007 at 09:12

    Nezabera int v pameti rovnaku velkost bez ohladu na to aka hodnota je v nom ulozena?

  • cincura.net
    October 29th, 2007 at 09:17

    Tady nejde o pamet, ale o to, jak “dlouhy” bude vypis, kdyz se to zapise napr. pomoci CSV na radek.

  • bst
    October 29th, 2007 at 09:24

    V pameti sice zabira stejne (i v DB), ale po serializaci je velikost rozdilna podle poctu cifer (tedy pokud se to neposila serializovane binarne).

  • P_V
    October 29th, 2007 at 20:31

    Než vymýšlet kompresi šitou na míru jednomu konkrétnímu výpisu, zdá se mi lepší celý serializovaný obsah zazipovat.

  • cincura.net
    October 29th, 2007 at 20:47

    To nebylo mozne. Posilalo (Melo) se to mailem jako soucast URL. Muselo by se to prevest do tr. Base64 a to by se zase natahlo.

  • janb
    October 29th, 2007 at 23:46

    I tak by se dala udelat mnohem lepsi komprese … treba si staci uchovat 1000 az 1003, 1007. Pricemz 1003 je vhodne zapsat jen jako prirustek od 1000 a cele to rovnou vyjadrovat ve znacich base64 (tedy napr. cca v 60kove soustave + zbytek na oddelovace).

  • cincura.net
    October 29th, 2007 at 23:54

    Ja netvrdim, ze je to nejlepsi komprese. Proste to jen usetri znaky, kdyz je tam 12345,12346,12347,… treba.

  • Pavel Stehule
    November 13th, 2007 at 23:47

    Tohle musi teoreticky fungovat. Je to v podstate diskretni derivace a integrace. Prakticky pouze v textu nebo ve formatu s pohyblivou sirkou. Jinak sikovny napad. V podstate ucinnost teto komprese stoupa s sirkou slova (poctem cislic), a vlastně tato komprimovana rada by sla prohnat napred rle, pokud by se casto zvysovalo o jednicku a to jeste huffmanem, pokud by vysledek nemusel byt binarni.

Share your thoughts, leave a comment!