문제

시각적 C/C ++ 6을 가정하면 22399 요소의 복잡한 데이터 구조가 다음과 같이 보입니다.

{
{ "(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"}, 
...
}

이것을 선언하는 가장 좋은 방법은 무엇입니까? 나는 같은 것을 시도했다

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

그리고

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

그러나 컴파일은 만성적 인 것을 wit습니다.

편집하다: 데이터는 특정 Unihan 문자에 대한 설명 데이터베이스입니다. 데이터를 압축하는 다양한 방법을 탐색 해 왔습니다. 22399 개의 항목이 있으며, 각 항목은 다양한 수의 문자열 또는 {Abbrev 마커, 마지막으로 본 선, 마지막으로 본 선의 요소}를 포함 할 수 있습니다.

그건 그렉의 말을 통해, 나는 각 줄에 동일한 수의 요소가 포함되어 있어야 할 수도 있습니다. 그게 사실인가요?

#2 편집: 그리고 트리플렛의 숫자 값 중 일부는 숯의 한계를 벗어납니다.

도움이 되었습니까?

해결책

방금 새 게시물을 읽고 원래 게시물을 다시 읽었으며 여기서 목표를 완전히 이해했다고 생각합니다. 너무 오래 걸려서 죄송합니다. 속도가 느립니다.

원래 예제의 4 행에 질문을 역설적으로 말하십시오.

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

데이터를 압축하기 위해 트리플을 이전에 사용 된 문자열에 대한 참조로 변환하려고합니다. 그 선은 다음과 같이됩니다.

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

목표가 압축이라면 여기에서 많은 이익을 얻을 것이라고 생각하지 않습니다. 자체 참조 트리플은 각각 3 바이트이지만, 치환되는 문자열은 총 8 바이트에 불과하며, 널 터미네이터를 계산 하고이 줄에 2 바이트 만 절약합니다. 그리고 그것은 숯을 사용하기위한 것입니다. 구조가 너무 커서 참조에 Ints를 사용해야하므로 트리플은 실제로 12 바이트이며 더 나쁩니다. 이 경우 12 개의 ASCII 문자 이상인 단어를 대체하여 공간을 절약 할 수 있습니다.

내가 여기에 완전히 기지에서 벗어나면 자유롭게 나를 무시할 수 있지만, 나는 공간에서 토큰 화를 내고 중복 단어를 제거하는 것이 불쌍한 사람의 일종이라고 생각합니다. 허프만 압축. 알파벳이 목록 인 Huffman 가장 긴 공통 기판, 또는 다른 표준 텍스트 압축 방법은 아마도이 문제에 대해 잘 작동 할 것입니다.

어떤 이유로 든 이것이 옵션이 아니라면, 데이터에서 모든 고유 한 단어 목록을 얻고이를 조회 테이블로 사용할 것이라고 생각합니다. 그런 다음 모든 문자열을 인덱스 목록으로 해당 테이블에 저장하십시오. 두 개의 테이블을 사용해야하지만 결국에는 더 간단 할 수 있으며, 현재 "Abbrev 마커"로 사용하는 주요 1에서 사용하는 공간을 절약 할 수 있습니다. 기본적으로 약어 마커는 삼중 항 대신 단일 색인이됩니다.

그래서,

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

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

끈이 대략 균일 한 길이가 없다면 여전히 많은 공간을 잃을 것입니다.

다른 팁

데이터를 XML 또는 다른 구조화 된 양식으로 저장 한 다음 코드에서 초기화하는 대신 읽고 구문 분석 할 것입니다. 초기화에서 지불하는 형벌은 코드의 이해가 용이하고 유지 보수 가능성을 높이는 것 이상의 것입니다. 또한 각 항목을 유지하기 위해 특정 데이터 구조를 설계하는 것을 고려합니다.

편집] 아래의 예는 다음 설명을 복제하려고 시도합니다.

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");

C에서는 만 나갈 수 있습니다 첫 번째 배열을 선언 할 때 치수 :

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

컴파일러가 각 "행"이 얼마나 큰지 알고 싶어서 "열"을 올바르게 배치 할 수 있기 때문입니다. 나는 당신이 원하는 방식으로 치수를 자유롭게 해석 할 수 있기 때문에 차원을 따옴표에 넣었지만, 그것은 2 차원 배열의 일반적인 관습입니다.

즉, 데이터 구조가 실제로 무엇인지 또는 초기화하려는 것이 무엇인지 확실하지 않습니다. 샘플 데이터에는 어떤 종류의 패턴이없는 것 같습니다.

여기서 질문은 각 행에 다른 수의 문자열이있는 C 스타일 문자열의 다차원 배열을 정적으로 선언 할 수 있는지 여부입니다. 그래서 다음과 같은 것 :

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

일부 언어에서는 이것을 "들쭉날쭉 한 배열"이라고합니다. C 및 C ++에서는이 작업을 수행 할 수 있지만 컴파일러는 모든 행을 같은 길이처럼 보관할 수있는 공간을 할당하려고하므로 두 번째 배열의 세 번째 항목을 초기화하지 않습니다. GCC에서 이것을 테스트했을 때 해당 배열의 세 번째 항목은 NULL로 설정되었지만 그에 의존 할 수 있는지 모르겠습니다.

C 스타일 문자열로 {1,2,3}과 같이 선언 된 배열을 컴파일러로 받아 들일 수 있다고 생각하지 않습니다. 그랬더라도, 당신은 이것을 문자열로 취급하더라도, 당신은 그들이 종결되지 않았기 때문에 문제가 생길 것입니다.

다른 포스터에 동의합니다. 더 나은 접근 방식은 아마도이 데이터를 XML, Yaml 또는 아마도 데이터베이스에 저장하고 그곳에서 액세스하는 것입니다. 소스 파일에서 이러한 이러한 데이터에 적합한 구조를 선언하고 해당 배열을 초기화하는 것이 좋습니다. 같은 것 :

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} }
  };

원래 데이터는 약 1.7MB이며, 하나는 내 고용주와 다른 하나는 유니 코드 컨소시엄의 다른 파일 (UNIHAN.TXT, 약 30MB)에서 파생되었습니다. 사전 룩업 기술을 사용하여 가장 길고 가장 빈번하게 발생하는 단어의 사전을 사용하면 데이터 크기가 1.5MB로 줄어 듭니다. 나는 현재 공간의 vbscript split () 일뿐입니다.

나는 준 허프만 접근 방식으로 얼마나 작은 지에 대한 인물이 없지만, 내 생각에 1MB보다 약간 작다는 것입니다. 나는 별도의 파일이 아닌 바이너리 에이 모든 것을 갖고 싶었지만 (다른 사람들이 나쁜 연습에 대해 말할 수 있음에도 불구하고), 그것은 적어도 C에서 너무 힘들어지고 있습니다. 행복감에서 BSTR의 변형 어레이를 만드는 방법을 알아낼 수 있습니다 ...

편집하다: 표준 UCN과 관련하여 사전 조회를 사용했으며 글리프 설명의 반복적 인 특성으로 인해 잘 작동합니다. Unihan의 문제는 Glyph에 대한 설명으로 끝나는 것입니다. 수단; 정 성적 (및 정량적) 차이가 있습니다. "VULGAR FRACTION ONE QUARTER" 그리고 "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"

따라서 사전 조회에서 멀어지고 더 강력한 "압축"기술로 이동합니다.

(그리고 누군가가 말하기 전에, "1.7MB의 큰 문제는 무엇입니까?"라고 말하기 전에, 나는 16k 램이 많은 시대에서 왔습니다. 그리고 어쨌든 공간 제약이 있습니다.)

사가는 아직 끝나지 않았습니다. 나는 결국 모든 것을 울퉁불퉁 한 배열로 바꿨습니다. int. 그러나 그로 인해 삼중 항의 자체 참조 메커니즘이 의존하는 선에서 아이디어를 잃어 버렸습니다.

이제 사용을 찾고 있습니다 행복감 울퉁불퉁 한 배열에 대한 우수한 지원으로 인해 C 대신. Euphoria를 사용하여 표준 DLL을 구축 할 수 있으며 BSTR의 변형 배열을 백업하고 타입을 작성하는 방법을 알아낼 수 있습니다.

당신을 염두에 두십시오. 나는 C를 고수하고 삼중 항을 연속으로 3 개의 int로 보관할 수 있다고 생각합니다. 그리고 그것은 처음에 자기 참조 사전을 구축 한 VBScript의 다소 큰 재 작성을 저를 절약 할 것입니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top