2014-10-29 2 views
0

나는 수백만의 이진 문자열을 생성하는 프로그램을 사용하고 있습니다. 메모리에서 이진 트리를 유지해야하지만 문자열은 2048 자입니다 (1001011 ... .101). 지금까지 내가 16 진수 형식으로 변환하고 원래 문자열 크기의 1/4 만 저장할 수있는 512 chars 문자열을 얻을 수 있지만 여전히 너무 커서 모든 문자열을 메모리에 보관할 수 없습니다. 그래서 모든 변환 된 문자열의 고유성을 더 보장하는 이진 문자열을 줄이는 방법이 있는지 궁금합니다. 감사!C에서 이진수를 줄이십시오

+7

문자열을 저장하는 이유는 무엇입니까? 2048 비트를 2048 비트 (예 : 256'uint8_t's 또는 64'uint32_t's)로 저장하십시오. 문자열은 사람을위한 것입니다. 컴퓨터는 숫자를 사용합니다. –

+0

하지만 문자열로 바이너리를 가지고, 그래서 2048 문자 문자열을 uint8_t 또는 uint32_t로 변환하는 방법은 무엇입니까? –

+3

이것이 명확하지 않다면, C로 프로그래밍하지 말아야합니다. 문자열이 단지 32 자라고 가정 해 봅시다. 그럼 당신은 그냥 :'uint32_t val = 0; for (i = 0; i <32; i + = 1) {val << = 1; val = = (str [i] & 1);}'2048 문자의 경우 64 회 수행 –

답변

0

길이 8 : "01010110"의 자릿수 1과 0의 문자열은 단일 문자 (unsigned char)로 저장할 수 있습니다. 숯불 거기에에서 = 256

에서 1 또는 0/비트

2048 자, 당신은 압축을 사용합니다.

unsigned char n = 0 ; 
char* s = "11010110" ; 

for(size_t i = 0 ; i < 8 ; i++) 
{ 
    if(s[i] == '1') 
    { 
     n |= 1u << (7 - i) ; 
    } 
} 

등등 당신이 어떤 입력이 남아있는 때까지

당신은 비트 연산자 나 사용의 sprintf() 예를 들어

사용하여 수동으로 변환 할 수 있습니다.

+1

저장하는 경우 raw 이진수를'unsigned char'의 배열에 넣어두면 문자열이 아닙니다. (정의상 0 바이트로 끝납니다.) 그냥 문자열 함수를 사용하지 마십시오. 물론 다른 메소드를 사용해야합니다. (컴파일 타임 상수라는 것을 의문의 여지가있다.) –

2

문자열을 문자열로 저장하지 말고 원시 번호로 저장하십시오. 어떤면에서 이것은 "Base-256"인코딩과 동일합니다. 물론 이것은 단순히 바이트로 구성된 큰 부호없는 정수입니다. 평소와 같이이 숫자를 비교할 수 있습니다.

이진 문자열을 인쇄해야하는 경우 필요에 따라 숫자의 서식을 지정하십시오. 즉, 특정 기수가있는 문자열로 값을 처리해야하는 경우에만 특정 기수가 그림에 들어가야합니다.

+1

이 일반화 된/막연한 대답은 문제가있는 OP에 도움이되지 않는다. – user3629249

+0

@ user3629249 막연하거나 일반화되지 않는다. 숫자가 아니라 문자열로 "특정대로입니다. – dasblinkenlight

1

char 데이터 형식을 사용하여 char에 8 비트, 즉 단일 문자열에 대해 256 char 배열을 저장할 수 있습니다.

더 압축하려면 데이터 패턴을 모니터링해야합니다. 패턴에 따라 압축 알고리즘을 선택하여 데이터를 압축 할 수 있습니다.

+0

그래서 내가 가질 수 있습니다 char string [256] = "1010101 ...."<- 최대 2048 1과 0입니까? –

+0

char를 사용하여 숫자를 저장하는 것은 구식입니다. 그 밖의 것이 없다면, char의 signed/unsigned 속성은 정의되지 않는다. 대신 #include 을 사용하고 uint8_t –

+0

예를 사용하고 압축 알고리즘을 사용하십시오. @Luis –

-1

데이터를 2 진수 바이트 배열이 아닌 문자열로 처리해야하는 경우 Base64 encoding을 사용하여 24 비트를 4 문자로 변환 할 수 있습니다. 이것은 24 비트를 6 문자로 변환하는 16 진수보다 향상된 것입니다. 24 비트가 3 개의 8 비트 문자로 바뀌는 순수한 바이너리 표현과 같이 여전히 좋지 않습니다.

바이너리 배열의 위험성은 문자열 함수를 사용할 수 없다는 것입니다. 8 비트의 임의의 시퀀스가 ​​문자열의 끝으로 해석되기 때문입니다. 명시적인 바이트 수를 취하는 memcmp과 같은 함수를 사용해야합니다.

+0

"바이너리 배열의 위험은 문자열 함수를 사용할 수 없다는 것입니다 ..."- 어떻게 위험합니까? 그것은 당신이 어떤 종류의 데이터를 작업하고 있는지를 아는 것입니다. –

+0

@KeithThompson 나는 명백해야하지만 함정에 빠져있는 함정을 지적하고있었습니다. 나는이 질문을하는 누군가가 미묘함을 알고 있다고 가정 할 수 없다. –

0

무료 bignum 라이브러리 중 하나 (예 : GNU MP)를 사용해야합니다. 법적으로 방해가되는 다른 도서관들도 있습니다. 당신이 이미 하나를 사용하고 있지 않다는 것에 놀랍습니다. 처음에 2048 비트 문자열을 어떻게 생성하고 있습니까?

둘째, 왜 메모리에 저장합니까? 왜 디스크에 없습니까? 아니면 심지어 데이터베이스 엔진을 사용합니까?

숙제가 맞습니까?

+0

그것의 연구에 관해서 나는 그것을 가능한 한 빨리 얻을 필요가있다. 그것은 기억의 이유이다. PC에 20GB RAM이 있지만 메모리에 트리로드를 최적화해야합니다. 라이브러리를 확인해 보겠습니다. –

+0

기본적으로 2048 비트의 숫자가 있으며 메모리에 있는지 여부를 알고 싶습니까? 숫자에 더 많은 데이터가 첨부되어 있습니까? 아니면 숫자 자체입니까? 그렇다면 힙 (heap)은 거의 확실하게 이동하는 방법입니다 (제 생각에). –

+0

확장하려면 힙은 작성 방법에 대한 특정 규칙을 따르는 이진 트리입니다. 이진 트리는 이진수 집합을 표현하는 이상적인 방법입니다. 트리가 힙이면 간단한 배열로 저장하는 것이 매우 효율적입니다. 불행하게도, 내가 힙을 가지고 작업 한 이후로 세부 사항을 잊어 버린 것은 오랜 시간이 걸렸지 만,이 부분을 살펴 봐야합니다. –

0

글쎄, 마침내 괜찮은 제안을 얻었습니다.

double bin2double(unsigned char *binstr, size_t len) 
{ 
    double ret = 0; 
    size_t cur; 
    for(cur = 0; cur < len; cur++) 
     { 
     ret *= 1.001; 
     ret += binstr[cur] - 48; 
     } 
    return ret; 
} 

이렇게하면 크기가 len 인 모든 다른 이진 문자열 binstr에 대해 다른 이중 값을 얻을 수 있습니다.이 값은 내 트리에 쉽게로드 할 수 있습니다. 모두에게 감사 드려요.