Jak inicializovat poměrně složitou char pole v C?

hlasů
0

Za předpokladu, že Visual C / C ++ 6, I mají komplexní datovou strukturu 22399 prvků, které vypadá takto:

{
{ (SAME, AS, U+4E18), HILLOCK, OR, MOUND},
{ TO, LICK;, {1, 1, 0}, TASTE,, A, MAT,, BAMBOO, BARK},
{ (J), NON-STANDARD, FORM, OF, U+559C, ,, {1, 1, 0}, LIKE,, LOVE,, ENJOY;, {1, 1, 4}, JOYFUL, THING},
{ (AN, ANCIENT, {1, 2, 2}, {1, 2, 3}, U+4E94), FIVE}, 
...
}

Jaký je nejlepší způsob, jak prohlásit to? Snažil jsem se věci, jako je

char * abbrevs3[22399][] = { ... };

a

char * abbrevs3[22399][][] = { ... };

ale kompilace whinges něco chronické.

EDIT : Data je databáze popisů některých postav Unihan. Byl jsem zkoumá různé způsoby komprimaci dat. Jak to stojí máte 22399 záznamů, z nichž každý může obsahovat různý počet řetězců nebo triplety {zkráceně markeru, řádek, kde naposledy, prvek z této linie, kde naposledy}.

Mimochodem Gregově mluvit, může musím mít každý řádek obsahuje stejný počet prvků, i když některé z nich jsou prázdné řetězce. Je to tak?

EDIT # 2 : A připadá mi, že některé z číselných hodnot v trojčat jsou tak mimo limity char.

Položena 12/10/2008 v 19:10
zdroj uživatelem
V jiných jazycích...                            


6 odpovědí

hlasů
4

To bych se na ukládání dat ve formátu XML nebo nějaké jiné strukturované podobě, pak čtení a analýze jej namísto toho, aby inicializace v kódu. Trest, který platíte při inicializaci bude větší než bude skládat v snadnost porozumění a zvýšení udržovatelnost vašeho kódu. Já bych také zvážit navrhnout zvláštní datovou strukturu držet každou položku.

[EDIT] Níže uvedený příklad se pokusí replikovat následujícího popisu:

enum EntryType { string = 0, triple = 1 };

typedef struct {
   enum EntryType entry_type;
   union {
      char** string;
      int[3] *triple;
   }
} Entry;

typedef struct {
   Entry *entries;
} Abbreviation;

Abbreviation *abbrevs3;

abbrevs3 = parseAbbreviationData("path-to-abbreviations/abbrevs.xml");
Odpovězeno 12/10/2008 v 19:33
zdroj uživatelem

hlasů
3

V jazyce C, můžete ponechat pouze na první rozměr při deklarování matici:

char * abbrevs3[][22399] = { ... };

Důvodem je, že kompilátor chce vědět, jak velký každý „row“ je, aby bylo možné vyložit „sloupců“ správně. Dal jsem rozměry v uvozovkách, protože jste zatím interpretovat rozměry jakýmkoliv způsobem, který si přejete, ale to je obvyklé konvence pro dvojrozměrné pole.

To znamená, že není jasné, jaké jsou vaše datová struktura ve skutečnosti je, nebo to, co se snažíte ji inicializovat na. Váš vzorek dat Nezdá se, že mají nějaký druh vzoru k ní.

Odpovězeno 12/10/2008 v 19:15
zdroj uživatelem

hlasů
2

Četla jsem vaše nová pracovní místa a znovu si přečíst původní příspěvek, a myslím, že jen zcela objasněn cíl zde. Líto, že to trvalo tak dlouho, jsem trochu pomalý.

Abychom parafrázovali otázku, na řádku 4 původního příkladu:

{ "(AN", "ANCIENT", {1, 2, 2}, {1, 2, 3}, "U+4E94)", "FIVE"},

Budete chtít přeložit do trojic odkazy na řetězců použitých dříve, ve snaze kompresi dat. Ta linka se stává:

{ "(AN", "ANCIENT", "FORM", "OF", "U+4E94)", "FIVE"},

Je-li cílem je komprese Nemyslím si, že uvidíte velký zisk zde. Self-odkazování ztrojnásobuje jsou vždy 3 byty, ale řetězce, které jsou substituované ven pouze 8 bytů celkem, počítat null terminátory, a ušetříte až 2 bajty na této lince. A to je pro používání znaků. Vzhledem k tomu, vaše struktura je tak velká, že budete muset použít celých čísel o reference, vaše triple je ve skutečnosti 12 bytů, což je ještě horší. V tomto případě budete jen někdy šetří místo nahrazením slova, která jsou 12 ASCII znaků nebo více.

Pokud jsem úplně mimo základnu zde pak neváhejte mě ignorovat, ale myslím, že přístup tokenizaci na prostor a odstranění duplicitních slov je jen trochu chudáka Huffman komprese . Huffman kde abeceda je seznam nejdelších společných dílčích , nebo nějaká jiná standardní metoda komprese textu bude pravděpodobně fungovat i pro tento problém.

Pokud z nějakého důvodu není možné, i když si myslím, že bych se získat seznam všech unikátních slov ve vašich dat a použít jej jako vyhledávací tabulky. Pak ukládat všechny řetězce jako seznam indexů do této tabulky. Budete muset použít dvě tabulky, ale nakonec to by mohlo být jednodušší, a to by vám ušetří prostor používán od teď začínající 1. používáte jako „zkráceně strážce“. Zjednodušeně řečeno, vaše zkratka markery by se stal jediný index namísto trojice.

Tak,

const char * words[] = {
    "hello", "world", "goodbye", "cruel"
    };

const int strings[] = {
    { 0, 1 },
    { 2, 3, 1 }
    };

Bys stále ztrácejí hodně prostoru, pokud vaše řetězce nejsou hrubě jednotná délka ačkoli.

Odpovězeno 13/10/2008 v 18:49
zdroj uživatelem

hlasů
1

Původní údaje o 1.7MB který byl odvozen od 2 jiných souborů, jeden z mého zaměstnavatele a ostatních (Unihan.txt, při teplotě asi 30 MB) z Unicode Consortium. Použití slovníku look-up techniky, pomocí slovníku horního 128 nejdéle a nejčastěji se vyskytující slova, přináší pouze objem dat až 1,5 MB. Mohl bych snad zlepší, že tím, že vyšší inteligence s mým detekcí slova, která v současné době je jen VBScript Split () v prostoru.

Nemám žádné údaje pro to, jak malá jsem si s přístupem kvazi-Huffman, ale já si myslím, že je to o něco méně než 1 MB. Byl jsem chtěl mít vše v binárním, nikoli jako samostatný soubor (navzdory tomu, co jiní mohou říci o praxi atd špatný) Jak to stojí, ale je to všechno stále jen trochu příliš tvrdé, alespoň v C. Je-li Nemůžu přijít na to, jak vytvořit variantní matice BSTR v Euphoria ...

EDIT : Použil jsem slovníku vyhledávání s ohledem na standardní UCNs a že funguje dobře, vzhledem k opakující se povaze popisů glyfů. Problém s Unihan je to, že jste skončili s popisem toho, co piktogramy prostředky ; je tu kvalitativní (a kvantitativní!) rozdíl mezi "VULGAR FRACTION ONE QUARTER"a"A KIND OF PUNISHMENT IN HAN DYNASTY, NAME OF CHESSMEN IN CHINESE CHESS GAME(SIMPLIFIED FORM, A VARIANT U+7F75) TO CURSE; TO REVILE; TO ABUSE, TO SCOLD"

Tedy odklon od slovníku look-up a směrem k nějaké více-mocný „komprese“ technikou.

(A před říká každý, „tak co je to velký problém s 1.7MB?“ Pocházím z doby, kdy 16K RAM bylo hodně. A mám prostorová omezení v každém případě).

Odpovězeno 14/10/2008 v 02:20
zdroj uživatelem

hlasů
1

Myslím, že tady je otázkou, zda je možné staticky deklarovat multi-dimenzionální pole řetězců tvar C, kde existuje jiný počet stringů na každém řádku. Takže asi takhle:

const char * arr[][3] =
    {
    {"bla", "bla", "bla"},
    {"bla", "bla" }
    };

V některých jazycích je to označováno jako „zubaté pole.“ V C a C ++ můžete to udělat, i když kompilátor bude chtít přidělit prostor pro uložení všech řádků, jako kdyby se jedná o stejnou délku, takže skončíte není inicializace 3. položku druhého pole. Když jsem testoval to ven na gcc třetí položka v tomto poli byla nastavena na hodnotu NULL, ale já nevím, jestli se můžete spolehnout na to.

Nemyslím si, že budete mít možnost získat kompilátor přijmout pole deklarované jako {1,2,3} jako řetězce C stylu. I kdyby to udělal, a vy léčit je jako řetězce, měli byste mít problém, protože oni nejsou null ukončen.

Já bych souhlasit s ostatními plakátů, lepší přístup je pravděpodobně ukládat tato data XML, YAML, případně v databázi, že je máte užívat od, a přistupovat k nim tam. Pokud potřebujete vytvořit tyto staticky ve zdrojovém souboru, budete pravděpodobně lépe deklarovat takovou strukturu, která má smysl pro vaše data a inicializace řadu z nich. Něco jako:

typedef struct
{
  const char * somestring;
  const char * someotherstring;
  const unsigned int triple[3];
} Abbreviation;

const Abbreviation abb[] =
  {
    {"First Thing", "Second String", {1,2,3} },
    {"Other Thing", "Some String", {4,5,6} }
  };
Odpovězeno 12/10/2008 v 20:03
zdroj uživatelem

hlasů
0

Sága není u konce přesto se zdá. Nakonec jsem skončil soustružení všechno do otrhané pole int. Ale s tím se ztrácí představu položek v řadě, která sebevztažný mechanismus za trojice byla v závislosti na.

Jsem nyní hledá do bloku Euphoria spíše než C, protože jeho vynikající podporu potrhaných polí. Jeden může vytvořit standardní DLL s euforie a poté, co jsem se přijít na to, jak předat zpět variantní řadu BSTR a napsat typelib ...

Nezapomínejme, myslím, že bych mohl zůstat u C a ukládání trojčata jsou jen tři ints v řadě, a ukládat řetězce jako ukazatele obsazení jako celá čísla. A to by zachraň mě poměrně velký přepsání VBScript, který postavil sebereferenční slovníku na prvním místě.

Odpovězeno 13/10/2008 v 16:09
zdroj uživatelem

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more