허프만 트리를 기반으로 한 간단한 파일 압축 버전

리소스 다운로드 주소 : https://download.csdn.net/download/sheziqiong/88358849
리소스 다운로드 주소 : https://download.csdn.net/download/sheziqiong/88358849

허프만 트리를 기반으로 한 간단한 파일 압축 버전

1. 데이터 압축의 개념

데이터 압축이란 데이터의 양을 줄여 유용한 정보를 잃지 않으면서 저장 공간을 줄이거나, 데이터의 전송, 저장 및 처리 효율을 높이거나, 데이터를 특정 알고리즘에 따라 재구성하여 데이터 중복성과 저장 공간을 줄이는 기술적 방법을 말한다.

2. 압축이 필요한 이유

1. 데이터 저장 용량을 압축하고 저장 공간을 줄입니다.

2. 데이터 전송 속도를 높이고 대역폭 사용량을 줄이며 통신 효율성을 향상시킬 수 있습니다.

3. 전송 중 데이터 보안을 강화하기 위한 데이터 암호화 보호.

3. 압축의 분류

손실 압축

손실 압축은 이미지나 음파의 특정 주파수 구성 요소에 대한 인간의 둔감함을 이용하여 압축 과정에서 특정 양의 정보가 손실될 수 있습니다. 원본 이미지는 축소되지만 압축률을 훨씬 높이는 대신 압축된 데이터를 사용하여 재구성합니다. 재구성된 데이터는 원본 데이터와 다르지만 원본 데이터에 표현된 정보에 대한 사람들의 오해에는 영향을 미치지 않습니다. .

무손실 압축

파일의 데이터는 특정 인코딩 형식에 따라 재구성됩니다. 압축된 파일은 파일 내용에 영향을 주지 않고 원본 파일과 정확히 동일한 형식으로 복원할 수 있습니다. 디지털 이미지의 경우 이미지 세부 정보가 손실되지 않습니다. .

외부 링크 이미지 전송에 실패했습니다. 소스 사이트에 필터링 방지 메커니즘이 있을 수 있습니다. 이미지를 저장하고 직접 업로드하는 것이 좋습니다.

4. ZIP 압축의 역사

1977년 두 명의 이스라엘인 Jacob Ziv와 Abraham Lempel이 범용 데이터 압축 알고리즘인 "A Universal Algorithm for Sequential Data Compression"이라는 논문을 발표했습니다. 소위 범용 압축 알고리즘이란 이 압축 알고리즘이 데이터를 압축하지 않는다는 의미입니다. 이 알고리즘은 오늘날 가장 무손실 데이터 압축의 핵심이 되었으며, 두 과학자를 기념하기 위해 알고리즘을 LZ77이라고 명명했고, 1년 후 그들은 LZ78이라는 유사한 알고리즘을 제안했습니다. ZIP 알고리즘은 LZ77의 아이디어를 기반으로 발전했지만 ZIP은 압축이 어려울 때까지 LZ77 인코딩 이후 결과를 계속해서 압축합니다. LZW, LZO, LZMA, LZSS, LZR, LZB, LZH, LZC, LZT, LZMW, LZJ, LZFG 등과 같이 기본적으로 LZ로 시작하는 LZ77 및 LZ78 기반 알고리즘의 다양한 변형이 있습니다.

ZIP의 저자는 오픈 소스 세계에서 비극적인 전설로 여겨지는 Phil Katz입니다. PhilKatz는 DOS 시대에 유명해진 멋진 프로그래머입니다. 그 시대에는 인터넷 속도가 매우 느렸습니다. PhilKatz가 인터넷 서핑을 시작한 것은 1990년도 아니었습니다. WWW는 실제로 존재하지 않았습니다. 물론 브라우저도 없었습니다. .당시 인터넷 서핑을 하는 목적은 무엇이었나요? 기본적으로는 네트워크 관리자가 다양한 명령을 입력해서 실제로 채팅도 하고 포럼에 들어갈 수 있는 것과 같았고, 압축하지 않고 파일을 전송하면 엄청나게 느리기 때문에 그 시대에는 압축이 매우 중요했습니다. 당시 상용 회사에서 ARC라는 압축 소프트웨어를 제공했는데 그 시대에 채팅 속도가 빨라졌으나 비용을 지불해야 했습니다. PhilKatz는 불편함을 느껴 무료일 뿐만 아니라 무료인 PKARC 압축 도구를 만들었습니다. ARC와 호환돼 네티즌들은 모두 PKARC를 사용하기 시작했고, 당연히 ARC사는 불만을 품고 필카츠를 지적재산권이 관련됐다는 등의 주장을 하며 법정에 세웠고, 그 결과 필카츠는 투옥됐다. 좋은 사람은 좋은 사람이다 감옥에서 고민하다 ARC를 능가하는 멋진 알고리즘을 생각해내기로 결심했다 감옥은 생각하기에 적합하다 완성하는데 2주가 걸렸다 PKZIP이라고 한다. 무료지만 이번에는 오픈소스이기도 합니다. 알고리즘이 다르고 지적재산권이 관련되지 않기 때문에 소스코드를 직접 공개하여 ZIP이 인기를 얻었지만 Phil Katz는 한 푼도 벌지 못하고 여전히 과음 등 여러 가지 이유로 빈곤에 시달리다 2000년 모텔에서 사망했다. 영웅은 죽지만 정신은 영원히 살아있습니다. 이제 UE를 사용하여 ZIP 파일을 열면 처음 두 바이트가 두 문자 PK의 ASCII 코드임을 알 수 있습니다.

5. GZIP 압축 알고리즘의 원리

GZIP 압축 알고리즘은 두 단계를 거쳤는데, 첫 번째 단계에서는 개선된 LZ77 압축 알고리즘을 사용하여 문맥상 반복되는 문장을 압축하고, 두 번째 단계에서는 휴먼 코딩 아이디어를 활용하여 첫 번째 단계에서 완성된 데이터를 바이트 단위로 압축함으로써, 효율적인 데이터 압축 및 저장을 달성합니다.

5.1LZ77 압축 알고리즘

LZ77은 긴 문자열(구라고도 함)을 짧은 토큰으로 인코딩하고 사전의 구문을 작은 토큰으로 대체하여 압축하는 사전 기반 알고리즘입니다.

LZ77은 사전을 유지하기 위해 순방향 버퍼와 슬라이딩 창을 사용합니다. 먼저 데이터의 일부를 포워드 버퍼에 로드하고, 데이터의 문구가 포워드 버퍼를 통과하면 슬라이딩 윈도우로 이동하여 사전의 일부가 됩니다.슬라이딩 윈도우가 이동함에 따라 사전의 내용이 또한 지속적으로 업데이트됩니다. 이는 사전을 업데이트하는 동시에 압축을 수행한다는 의미입니다.

사전이 구축되어 있다고 가정하고, 문자를 읽을 때마다 앞으로 스캔하여 사전에 반복되는 문구가 있는지 확인하고, 반복되는 문구가 발견되면 문구 태그로 인코딩합니다. 구문 태그는 슬라이딩 창의 오프셋(헤더에서 일치가 시작되는 이전 문자까지), 일치의 기호 수, 일치가 끝난 후 정방향 버퍼의 첫 번째 기호 등 세 부분으로 구성됩니다. oset, 길이, nextChar). 일치하는 항목이 없으면 일치하지 않는 기호가 기호 토큰으로 인코딩됩니다. 이 기호 태그에는 압축 없이 기호 자체만 포함됩니다. n개의 기호가 인코딩되고 해당 토큰이 생성되면, n개의 기호는 슬라이딩 윈도우의 한쪽 끝에서 제거되고 순방향 버퍼에 있는 동일한 수의 기호로 대체됩니다. 그런 다음 정방향 버퍼가 다시 채워집니다.

다음 그림은 슬라이딩 윈도우 크기가 8바이트이고 순방향 버퍼 크기가 4바이트라고 가정할 때 LZ77의 압축 과정을 보여줍니다.

각 토큰이 디코딩되면 토큰이 문자로 인코딩되어 슬라이딩 창에 복사됩니다. 구문 토큰이 발견될 때마다 슬라이딩 창에서 해당 오프셋을 조회하고 거기에서 발견된 지정된 길이의 구문을 찾습니다. 기호 태그가 발견될 때마다 태그에 저장된 기호 중 하나를 생성합니다.

5.2 GZIP의 LZ77 아이디어

GZIP 알고리즘에서는 LZ77의 알고리즘 아이디어도 사용되지만 주로 구문 태그 개선을 위해 개선되었습니다. "길이 + 거리"의 튜플만 표현에 사용되며 일치 검색은 검색 버퍼는 사전, 즉 사전에서 수행됩니다.

참고: 검색 버퍼의 데이터는 스캔되어 설정된 사전의 데이터이고, 고급 버퍼는 압축된 데이터입니다.

현재 예측 버퍼의 첫 번째 바이트는 문자 "r"입니다. 해야 할 일은 예측 버퍼에서 "r"로 시작하는 연속 문자로 구성된 문자열의 검색 버퍼에서 가장 긴 일치 항목을 찾는 것입니다. . 예를 들어 녹색 부분에 "re"가 있고 "re(여기에 공백이 있습니다)"도 녹색 부분에 있는데 전자보다 후자가 하나 더 많아 후자가 선택됩니다.

이제 처리해야 할 네 가지 문제가 있습니다.

1. "r"부터 시작하여 미리보기 버퍼의 문자열은 몇 개의 문자로 구성됩니까? 어떤 규칙이 있나요? 아니면 일치하는 항목을 찾을 수만 있다면 얼마나 많은 문자가 있는지가 중요합니까?

2. 검색 버퍼에서 일치하는 문자열을 효율적으로 찾는 방법은 무엇입니까?

3. 가장 긴 일치 항목을 찾는 방법은 무엇입니까?

4. 일치하는 항목을 찾을 수 없으면 어떻게 해야 합니까?

5.2.1 일치하는 문자열은 몇 개의 문자로 구성됩니까?

1. 길이 거리 쌍을 사용하여 단일 문자를 대체하는 경우 대체하지 않는 것이 좋습니다.

2. 연속된 두 문자를 길이 거리 쌍으로 대체하는 경우 대체 여부는 상관없지만 대체 전후에 두 개의 숫자를 사용해야 합니다(문자는 실제로 숫자입니다).

3. 교체를 위한 전제 조건은 문자열이 미리보기 버퍼에서 최소 3개의 연속 문자로 구성되어야 하고 미리보기 버퍼의 첫 번째 바이트부터 시작해야 한다는 것입니다.

따라서 미리보기 버퍼의 문자열은 최소 3개의 연속 문자로 구성되어야 합니다. 즉, 미리보기 버퍼의 문자열이 연속된 3개 이상의 문자로 구성되어 있고 검색 버퍼에서 일치하는 문자가 발견되면 미리보기 버퍼의 문자열을 "길이 + 거리" 쌍으로 대체할 수 있습니다.

5.2.2 일치하는 문자열을 효율적으로 찾는 방법

문자열이 검색 버퍼에서 일치하는 문자열을 검색할 수 있으려면 문자열이 최소 3개의 연속 문자로 구성되어야 합니다. 압축은 조회 속도를 향상시키기 위해 사전(해시 테이블)을 사용합니다. 압축에서 "사전"은 크기가 64KB이고 두 부분으로 나누어진 연속 메모리의 전체 블록으로 구성되며, 아래 그림과 같이 각 부분의 크기는 하나의 WSIZE입니다.

포인터 head=prev+WSIZE, prev는 사전 전체 메모리의 시작 위치를 가리킵니다. 메모리는 연속적이기 때문에 prev와 head는 두 개의 배열, 즉 prev[]와 head[]로 간주될 수 있습니다.

압축이란 이 세 개의 연속된 문자를 사용하여 해시 값을 계산하는 것이며, 이 해시 값은 head[] 배열의 인덱스입니다. 세 글자가 다르고, 배열 순서가 다르며, 계산된 해시 값도 다릅니다. 총 결과가 있고, 해시 값의 범위는 0,32767 이므로 각 해시 값은 에 대응할 수 없습니다. string., 분명히 충돌이 있을 것이고 prev는 충돌을 해결하기 위해 여기에 있으며 이 배열은 가장 긴 일치 문자열을 찾는 데도 도움이 될 수 있습니다.

1. 사전 구축

소위 사전의 구성은 문자열을 사전에 삽입하는 것입니다. 압축은 바이트 단위로 수행됩니다. 바이트가 처리될 때마다 검색 버퍼가 1바이트씩 확장됩니다(32KB에 도달하면 슬라이드 인됨). 예견 버퍼의 방향은 1바이트), 예견 버퍼는 1바이트씩 줄어들고 예견 버퍼의 첫 번째 문자는 지속적으로 변경됩니다. 미리보기 버퍼의 첫 번째 바이트가 변경될 때마다 "현재 미리보기 버퍼의 첫 번째 바이트부터 시작하여 미리보기 버퍼의 연속된 3바이트"로 구성된 문자열을 사용하여 계산됩니다. 해시 값 ins_h는 배열 헤드의 인덱스입니다. []이므로 head[ins_h]는 문자열의 발생 위치를 기록하는 데 사용되며, 문자열의 발생 위치는 문자열의 첫 번째 문자(즉, 현재 예측 버퍼의 첫 번째 바이트)가 현재 창에서 문자열을 사전에 삽입하는 과정입니다.

2. 일치하는 문자열 찾기

참고: 사전에 문자열을 삽입하면 실제로는 문자열의 시작 위치가 사전에 삽입됩니다. 해시는 예비 일치일 뿐이며 예비 일치와 일치하는 위치를 찾는 데 사용됩니다. 더 긴 일치를 찾으려면 이 위치를 사용하세요. 목적입니다.

5.2.3 가장 긴 일치 항목을 찾는 방법

1. 삽입 중 사전 충돌이 발생하면 어떻게 해야 하나요?

삽입 과정은 head[ins_h]를 이용하여 현재 문자열의 발생 위치를 기록하는 것이며, ins_h는 현재 문자열의 해시 값이자 head[] 배열의 인덱스이다. 특정 head[ins_h]에 현재 문자열의 발생 위치를 삽입할 때 head[ins_h]가 비어 있지 않으면 어떻게 되나요? 예를 들어:

가정: strstart는 창에서 미리보기 버퍼의 첫 번째 문자 위치이고, 배열 요소 prev[strstart]는 이전 문자열의 위치입니다. 삽입은 다음과 같이 진행됩니다.

참고: strstart는 점진적으로 증가하므로 prev[strstart]에 값이 할당될 때마다 이전 내용을 덮어쓰지 않도록 할 수 있습니다. 각 할당 전에 prev[strstart]는 완전히 새로운 것이어야 합니다.

이는 해시 값은 동일하지만 위치가 다른 문자열을 prev[] 배열의 인덱스와 배열 요소 값을 통해 함께 연결하는 "체인" 관계를 형성합니다.

참고: 압축하기 전에 head[] 배열은 0으로 초기화되지만 prev[] 배열은 초기화되지 않습니다. prev[] 배열의 초기화는 동적으로 수행됩니다. 따라서 head[x]와 prev[x]는 0을 "empty" 즉, 일치하는 문자열 플래그가 없다는 의미로 사용하며, 그 값 자체의 의미는 문자열의 위치이지만 0번째 문자는 window는 문자열로 구성되어 있으며 위치도 0이므로 모호성이 발생합니다. 이 모호성에 대한 해결책은 매우 간단하고 조잡하며 창의 첫 번째 문자열이 일치 프로세스에 참여하지 않도록 하는 것입니다.

2. 미리보기 버퍼의 첫 번째 문자 위치가 32K보다 큰 경우 어떻게 해야 합니까?

압축이 바이트 단위로 진행되면서 미리보기 버퍼의 첫 번째 문자인 strstart가 지속적으로 증가(증가)하여 필연적으로 32K보다 커지게 됩니다(슬라이딩 창의 크기가 64K이므로).strstart가 32K를 초과하면, 해당 함수를 직접 사용하면 prev 배열의 첨자가 잘못됩니다. 소스 코드에 대한 해결책은 strstart를 prev[]의 인덱스로 직접 사용하는 대신 strstart와 WMASK의 비트별 AND 연산 결과를 prev[]의 인덱스로 사용하도록 하는 것입니다.이 중 WMASK의 값은 다음과 같습니다. 10진수로 32768, 즉 prev[strstart&WMASK ]입니다. 이렇게 하면 strstart의 값 범위 내에서 prev[]의 인덱스가 strstart와 완전히 일치합니다.

3. 일치하는 체인이 무한 루프를 생성하는 경우 어떻게 해야 합니까? strstart가 32K보다 크면 일치하는 체인에서 무한 루프가 발생할 수 있습니다.

소스 코드는 이 문제를 해결하기 위해 max_chain_length(최대 체인 길이 256을 나타냄)를 사용하는데, 이는 일치하는 체인을 따라 검색할 때 검색할 최대 항목 수를 나타냅니다. max_chain_length 값이 작을수록 일치하는 노드가 검색되는 횟수가 적어지고 압축 속도가 빨라지지만 상대적으로 압축률이 낮을 수 있습니다.

4. 지연 매칭 소스 코드는 가장 긴 일치를 찾기 위해 지연 매칭과 long_match라는 두 가지 방법을 사용합니다. 게으른 일치는 다른 문자열에 대해 가장 긴 일치를 찾는 반면,

maximum_match는 현재 문자열과 가장 긴 일치 항목을 찾습니다.

소위 지연 매칭이란 현재 문자열이 자신에게 가장 적합한 매칭 문자열을 찾았음에도 불구하고 이를 길이 거리 쌍으로 대체하려고 하지 않고 대신 prev_length와 prev_match 두 변수를 사용하여 일치하는 길이를 기록하고 각각 위치가 일치합니다. . 그런 다음 strstart가 한 문자를 고급 버퍼 쪽으로 이동하도록 하면 이제 strstart가 새 위치에 도달하고 현재 문자열이 업데이트됩니다. 이때 현재 문자열과 가장 잘 어울리는 일치 문자열을 찾아보세요. 현재 문자열에 가장 잘 맞는 매칭 문자열을 찾아 매칭 위치와 매칭 길이를 구했다고 가정하면, 레이지 매칭의 재능이 발휘되는 순간이다. 현재 일치하는 문자열의 일치하는 길이를 prev_length와 비교하여 전자가 후자보다 크면 전자를 사용하여 후자를 업데이트하고 동시에 prev_match를 현재 일치 위치로 업데이트하고 (현재 strstart에 있는 문자를 업데이트합니다. –1) position은 Unmatched 문자를 처리하는데 사용 prev_length와 prev_match 업데이트가 완료되면 strstart는 한 문자를 advance buffer 방향으로 이동시켜 동일한 처리를 계속한다.이 처리 방법은 지연 일치(lazy match)이다. 후자보다 마지막입니다. 일치하는 길이(prev_length)가 이 시간보다 크면 지연 일치가 중지되고 마지막 일치 길이와 일치 위치를 사용하여 길이-거리 쌍 튜플을 형성하여 교체를 완료합니다. 지연 일치가 중지된 후 prev_length 및 prev_match를 초기화하고 strstart를 새 위치(교체된 문자열 외부)로 이동하고 지연 일치 프로세스의 새로운 라운드를 시작할 준비를 합니다. 대체된 문자열의 각 문자로 구성된 문자열은 여전히 ​​사전에 삽입되어야 합니다.

5.가장 긴 경기

maximum_match는 일치하는 체인을 순회하여 일치하는 체인에서 가장 긴 부분 문자열을 찾는 것입니다. 물론 가장 긴 부분 문자열이 반드시 최적은 아니며 최적을 찾기 위해서는 지연 매칭과 결합되어야 합니다.

알아채다:

1. 일치하는 노드의 순회는 무한하지 않으며 일치하는 링크 노드의 최대 개수에는 제한이 있습니다.

2. 일치하는 문자열의 일치 길이는 무한하지 않으며 일치하는 문자열의 최대 일치 길이는 MAX_MATCH(258)입니다.

3. 매칭 거리는 무한하지 않으며, 매칭 거리는 MAX_DIST를 초과할 수 없습니다.

4. 가장 긴 일치 문자열은 maximum_match와 지연 일치를 통해 얻어집니다. 전자는 현재 strstart의 가장 긴 일치 항목을 찾는 역할을 하고, 후자는 여러 연속 strstart의 가장 긴 일치 항목 중에서 일치하는 문자열 길이가 가장 긴 항목을 최종적인 실제 가장 긴 일치 항목으로 찾는 역할을 합니다.

5.2.4 가장 긴 일치 항목을 찾을 수 없으면 어떻게 해야 합니까?

압축 결과에서 일치하는 문자열이나 거리 쌍을 소스 문자와 구별하는 방법은 무엇입니까? 예를 들어:

참고: 실제로 압축된 문자열에는 거리 쌍의 확장이 없습니다. 따라서 질문이 생깁니다. 23은 거리 쌍이 아니라 소스 문자이고 12,16은 거리 쌍을 나타냅니다. 그러면 이를 어떻게 구별할 수 있을까요?

해결 방법: 1비트를 사용하여 표시합니다. 예를 들어 1은 거리 쌍을 나타내고 0은 소스 문자를 나타냅니다.

5.2.5 감압

압축을 푸는 동안 바이트 단위로 구문 분석됩니다.

1. 현재 바이트의 최상위 비트가 0이면 소스 바이트를 나타내며 파일에 직접 기록됩니다.

2. 현재 바이트의 최상위 비트가 1이면 거리 쌍을 나타내며, 거리 쌍을 꺼내어 일치하는 시작 위치와 거리 쌍의 길이에 따라 유효한 문자열을 구문 분석합니다.

5.3GZIP의 허프만 생각

이전 LZ77 변형 아이디어를 통해 원본 데이터의 반복문 압축 후, 구문 수준의 반복성은 해결되었으나 압축 효과가 최적이었다는 의미는 아니며, 바이트 단위에서도 반복 횟수가 많을 수 있음 수준. 예: "BCDCDDBDDCADCBDC"

1바이트는 8비트를 차지하므로 모든 바이트에 대해 8비트보다 작은 코드를 찾은 다음, 찾은 코드를 사용하여 소스 파일에서 해당 바이트를 다시 쓰면 소스 파일을 더 작게 만들 수도 있습니다. 그렇다면 코드를 찾는 방법은 무엇입니까?

5.3.1 정적 동일 길이 인코딩

각 문자의 인코딩 길이는 동일합니다. 예를 들면 다음과 같습니다.

위의 소스 데이터를 압축하려면 동일한 길이 인코딩을 사용하십시오: 01101110111101111110001110011110. 압축 후 결과는 4바이트만 차지하며 압축률은 여전히 ​​상대적으로 높습니다.

5.3.2 동적 불평등 길이 인코딩

각 문자의 인코딩은 다음과 같은 특정 문자 상황에 따라 결정됩니다.

비균등 길이 인코딩을 사용하여 원본 데이터를 압축합니다: 10111011001010011100011101011 압축이 완료된 후 마지막 바이트가 다 사용되지 않았고 여전히 3비트가 남아 있습니다.분명히 동적 비균등 길이 인코딩은 동일 길이 인코딩보다 압축률이 더 좋습니다. 동적 불평등 길이 인코딩을 얻는 방법은 무엇입니까?

5.3.3인간 인코딩
1.하만나무

이진 트리의 루트 노드에서 이진 트리의 모든 리프 노드까지의 경로 길이의 합에 해당 가중치를 곱한 것이 이진 트리의 가중 경로 길이입니다.

WPL。

위 4개 트리의 가중치 경로 길이는 다음과 같습니다.

WPLa=1 2+3 2+5 2+7 2=32

WPLb=1 2+3 3+5 3+7 1=33

WPLc=7 3+5 3+3 2+1 1=43

WPLd=1 3+3 3+5 2+7 1=29

가중치가 가장 작은 경로를 갖는 이진 트리를 휴먼 트리라고 합니다.

2.인나무 구축

1. 주어진 n 가중치 {w1,w2,w3,…,wn}, F={T1,T2,T3,…,Tn}에서 루트 노드만 사용하여 n 이진 트리 포리스트를 구성합니다.

각 이진 트리 Ti에는 가중치가 wi인 루트 노드가 하나만 있고 왼쪽 및 오른쪽 자식은 비어 있습니다.

2. F에 트리가 하나만 남을 때까지 다음 단계를 반복합니다.

F에서 루트 노드 가중치가 가장 작은 두 개의 이진 트리를 선택하고 왼쪽과 오른쪽 하위 트리로 새로운 이진 트리를 구성합니다. 새 이진 트리의 루트 노드 가중치는 왼쪽 루트 노드의 가중치의 합입니다. 오른쪽 하위 트리 F 이진 트리에서 이 두 개를 삭제하고 새 이진 트리를 F에 추가합니다.

  1. Haman 인코딩 가져오기

질문: 길이가 다른 인코딩의 한 인코딩이 다른 인코딩의 접두사인 경우 어떻게 되나요? 이런 일이 일어날까요?

5.3.4 휴먼 인코딩을 사용하여 소스 파일 압축
  1. 소스 파일에서 각 문자의 발생 횟수를 계산합니다.

2. 캐릭터가 등장하는 횟수를 가중치로 하여 인간나무를 만듭니다.

3. 휴먼트리를 통해 각 캐릭터에 해당하는 휴먼코드를 획득합니다.

4. 소스 파일을 읽고, 얻은 휴먼 인코딩을 사용하여 소스 파일의 각 문자를 다시 쓰고, 다시 쓴 결과를 파일 끝까지 압축 파일에 씁니다.

5.3.4 압축 파일 형식

압축된 데이터만 압축파일에 저장할 수 있나요?

대답은 '아니요'입니다. 압축을 풀 때 압축을 풀 방법이 없기 때문입니다. 예: 10111011001010011100011101011. 압축된 데이터만 압축을 풀 수 없습니다. 따라서 압축된 데이터를 저장하는 것 외에도 압축 파일에는 압축 해제에 필요한 정보도 저장해야 합니다.

1. 소스 파일의 접미사

2. 문자번호쌍의 총 행수

3. 문자 및 문자 발생 횟수(단순히 한 줄에 각 문자를 배치함)

4. 데이터 압축

5.3.5 감압

1. 압축 파일에서 소스 파일의 접미사를 가져옵니다.

2. 압축 파일에서 문자 수를 포함한 총 라인 수를 가져옵니다.

3. 각 문자의 발생 횟수를 가져옵니다.

4. 휴먼 트리 재구축

5. 압축을 푼다

압축된 파일에서 1바이트의 압축 데이터를 얻고, 1바이트의 압축 데이터를 얻을 때마다 루트 노드부터 시작하여 해당 바이트의 바이너리 비트 정보에 따라 휴먼 트리를 순회하며 비트가 0이면 현재 노드를 가져옴 왼쪽 자식, 그렇지 않으면 오른쪽 자식을 취하고 리프 노드 위치를 통과할 때까지 문자가 성공적으로 구문 분석됩니다. 모든 데이터가 구문 분석될 때까지 이 프로세스를 계속합니다.

리소스 다운로드 주소 : https://download.csdn.net/download/sheziqiong/88358849
리소스 다운로드 주소 : https://download.csdn.net/download/sheziqiong/88358849

추천

출처blog.csdn.net/newlw/article/details/133065122