Buscar

aula08

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes
Você viu 3, do total de 5 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Prévia do material em texto

8ºAula
COMPACTAÇÃO DE ARQUIVOS
Objetivos de aprendizagem
Ao término desta aula, vocês serão capazes de: 
• saber o que é uma compactação de arquivos;
• conhecer o processo de compactação run-length;
• entender o algoritmo de Huffman.
Olá,
Para fecharmos a nossa disciplina com “Chave de Ouro”, 
vamos estudar um assunto muito discutido na Ciência da 
Computação, atualmente: a Compactação de Arquivos. Nesta 
aula, vamos aprender o que ela é, e veremos alguns algoritmos 
simples que fazem dessa compactação uma forma simples.
Leiam atentamente esta aula e façam os exercícios. Se 
enfrentarem alguma dúvida, estaremos a sua disposição na área 
do aluno.
Bons estudos!
53
Estrutura de Dados II 52
1. 
Seções de estudo
Compressão de dados
2. Codificação run-length
3. Algoritmo de Huffman
1 - Compressão de dados
A compressão de dados é o processo de reduzir o 
tamanho de um arquivo ou de um dado. Ele é muito 
importante, pois graças a esses algoritmos de compactação, 
muitos gigabytes de espaço nos discos rígidos e banda de 
internet foram poupados. Ela é usada nos seguintes fins:
• Para economizar espaço de armazenamento.
• Para economizar banda durante a transmissão de 
dados, deixando a transmissão mais rápida - vide o 
exemplo do streaming.
• Para juntar vários arquivos em um só. Por exemplo, 
o Microsoft Office, desde a versão 2007, a qual usa a 
tecnologia ZIP para seus novos formatos de arquivo, 
que reúne imagens, vídeos, textos, informações 
sobre o arquivo etc.
• Entre outros.
• Para desempenhar essa tarefa, foram desenvolvidos 
vários algoritmos e técnicas de compressão de 
arquivos. Esses algoritmos e técnicas podem ser 
divididos em dois grandes grupos:
• Compressão sem perda: São os algoritmos que 
compactam arquivos sem perda alguma no conteúdo 
e na integridade dos dados. Nesse grupo, um dado 
que é submetido a um processo de compressão e 
descompressão é idêntico ao original. Os dados 
redundantes são removidos na compressão e 
acrescentados na descompressão. Algoritmos 
desse grupo são usados quando nenhuma perda é 
admitida nos dados, como arquivos de texto. São 
exemplos: A codificação run-length, codificação de 
Huffman (tema desta aula), codificação Lempel-Ziv, 
compactação ZIP etc.
• Compressão com perda: São algoritmos que geram 
perdas no conteúdo e na integridade nos dados. 
Mas são perdas imperceptíveis. Esses algoritmos 
são usados quando a perda (de forma moderada) 
é algo aceitável e benéfico, como imagens, áudios e 
vídeos. São exemplos disso: a tecnologia JPEG, MP3 
e MPEG.
Nesta aula, vamos estudar os algoritmos de compactação 
de dados sem perda mais simples, que são o run-length e o 
algoritmo de Huffman.
2 - Codi cação run-length
A codificação run-length é uma das mais simples que 
existe. Ela consiste em ler todos os caracteres de um texto, e 
condensar as sequências repetidas de uma letra pela sua letra e 
o respectivo número de aparições seguidas. Assim, 
suponhamos a seguinte sequência:
Para compactar usando a codificação run-length 
precisamos ler a cadeia de caracteres do texto, para verificar 
quantas vezes repete uma letra no texto. Primeiramente, 
lemos a sequência de letras “a”. Contamos quantas vezes 
seguidas aparece a letra “a” no texto. No caso, verificamos 
que ela repete 8 vezes. Assim, colocamos a letra “a” e depois 
o número 8, para indicar que ela repete 8 vezes no texto.
O próximo caractere a ser lido é “b”. Constatamos que 
ela aparece 6 vezes seguidas. Assim, inserimos a letra “b” e 
o número 6. O mesmo acontece com a letra “c”, que repete 
duas vezes.
Feito isso, basta apenas inserir no novo texto a letra e o 
seu respectivo número de caracteres seguidos:
Para descompactar basta ler a letra e a sua quantidade de 
vezes. Feito isso, basta inserir no texto a quantidade de vezes 
desse caractere.
A seguir, veremos o pseudocódigo desta operação:
procedimento compactar(texto: caractere)
declare
 qtd: inteiro
 anterior, atual: caractere
inicio
 anterior <- leia_proximo_caracter(texto)
 qtd <- 1
 enquanto (ha_caracteres(texto)) faca
 atual <- leia_proximo_caracter(texto)
 se (atual = anterior) faca
 qtd <- qtd + 1
 senao
 escreva(anterior)
 escreva(qtd)
 qtd <- 1
 fimse
 anterior <- atual
 fimenquanto
fimprocedimento 
Esse algoritmo pode ser bom. Mas em um texto real, 
onde é difícil duas letras seguidas estarem em uma mesma 
palavra, a codificação run-length mais atrapalha do que ajuda, 
pois insere mais caracteres do que é pedido em uma situação 
de texto real.
Para isso, foram desenvolvidos outros tipos de 
algoritmos. A seguir mostraremos como funciona o algoritmo 
de Huffman.
3 - Algoritmo de Hu man
Outra forma de compactar dados em um arquivo é o 
algoritmo de Huffman. Esse algoritmo permite uma 
economia de 20 a 90% no tamanho do arquivo a ser salvo. 
54
53
Para cumprir o seu papel, o código de Huffman faz uma 
contagem de quantas vezes uma letra ou uma palavra 
aparece no texto, e classifica em ordem da quantidade de 
aparições.
Depois, as letras ou palavras são agrupadas em forma 
de uma árvore, privilegiando os símbolos mais frequentes, 
colocando eles em posições de profundidade menor na 
árvore. Após isso, temos os códigos para cada símbolo 
nessa árvore, que representam o caminho da raiz até o 
símbolo. O 0 representa a subárvore esquerda, enquanto 
que o 1 representa a subárvore direita.
A seguir, mostramos uma tabela de frequências de 
caracteres oriundos de um texto hipotético. Em seguida, 
mostraremos como ficaria à disposição dos caracteres em 
uma árvore de comprimento fixo (onde cada caractere 
recebe uma sequência de um mesmo número de caracteres), 
e em uma árvore gerada pelo algoritmo de Huffman, que 
privilegia os caracteres mais frequentes. Observe que para 
chegarmos a letra “a”, que é a mais frequente, precisaríamos 
percorrer 3 nós antes de chegarmos ao nó final em um 
código de comprimento fixo, enquanto em que uma árvore 
gerada pelo algoritmo de Huffman precisamos percorrer 
apenas 1 nó para chegar ao valor desejado. 
a b c d e f
Frequência (em 
milhares)
45 13 12 16 9 5
Palavra de código em 
comprimento o
000 001 010 011 100 101
Palavra de código de 
comprimento variável
0 101 100 111 1101 1100
Fonte: (CORMEN et. al., 2012, p. 313).
É claro que em uma árvore gerada pelo algoritmo 
de Huffman alguns símbolos serão mais difíceis de ser 
encontrados e, portanto, terão um código maior, mas isso 
é compensado pela facilidade de encontrar os caracteres 
mais frequentes e também pela economia gerada por esses 
códigos.
Mas, como gerar essa árvore? Primeiramente, lemos 
todo o arquivo texto fazendo uma contagem de quantas 
vezes cada caractere aparece no texto. Armazenamos essa 
tabela de frequências em uma lista de registros, onde cada 
registro possui duas informações: o caractere e a quantidade 
de vezes que ele apareceu. 
Como o algoritmo precisa da leitura prévia de todos os 
dados, chamamos esse algoritmo de algoritmo guloso.
Essa lista é submetida ao algoritmo de Huffman. Nesse 
algoritmo extraímos a quantidade de nós e colocamos na 
variável n. O loop percorre de 1 até n-1. A cada interação, 
extraímos os nós com as menores frequências. Depois, 
criamos um novo nó, que terá a soma das frequências dos 
dois nós extraídos, e terá como filhos os dois nós extraídos.
No final, esse novo nó é inserido na lista de maneira 
ordenada. O processo se repete até quando tivermos apenas 
um nó na lista, formando toda a árvore.
procedimento Huffman(C: *Lista)
declare
 n : inteiro
 Q : *//
 x, y, z : *TArvore
inicio
 n <- c.quantidade
 Q <- C
 para i de 1 ate n-1 faca
 z <- novoNo()
 z.esq <- x <- extrair_minimo(Q)
 z.dir <- y <- extrair_minimo(Q)
 z.freq <- x.freq + y.freq
 inserir_ordenado(Q, z)
 fimpara
 retorne extrair_minimo(Q) // Retorna a 
raiz da árvore
fimprocedimento
Depois, precisamos “traduzir” as letraspelas sequências 
correspondentes. Para isso, lemos cada letra do arquivo e 
trocamos pela sequência de bits correspondente a essa letra.
Assim, uma string contendo as seguintes letras:
fabaca
Deve ser traduzida para código binário da seguinte 
forma:
1100010101000
A princípio, não vemos uma melhora grandiosa no 
resultado, pois gerou mais caracteres. Mas, devemos lembrar 
que 1 caractere é armazenado em 1 byte, que equivale a 8 
bits. A string tem seis caracteres, logo são 6 bytes e 48 bytes. 
Em um código binário, todo 0 ou 1 pode ser armazenado 
em 1 bit. A cadeia gerada pelo compactador gerou uma 
cadeia de 13 bits. Ou seja, são 35 bits a menos.
Para facilitar a descompactação podemos salvar no 
arquivo a tabela de símbolos no seu início. Assim, para 
descompactar basta o programa ler essa tabela e ler bit 
por bit do arquivo até achar alguma correspondência. Se 
achar, escreve no arquivo resultante a letra correspondente 
e repete o processo.
A figura a seguir mostra a execução desse algoritmo no 
nosso texto de exemplo:
55
Estrutura de Dados II 54
E com isso, finalizamos a nossa aula e a nossa disciplina. 
Foi muito bom estar com vocês nesta jornada. Muito 
obrigado e até a próxima!
Retomando a aula
Chegamos ao m da nossa oitava aula. Vamos 
relembrar os pontos principais?
1 - Compressão de dados
Nesta seção, vimos que compressão de dados é o 
processo de reduzir o tamanho de um arquivo ou de um 
dado. Ela é usada nos seguintes fins: para economizar 
espaço de armazenamento; para economizar banda durante 
a transmissão de dados, deixando a transmissão mais rápida 
- vide o exemplo do streaming; para juntar vários arquivos em 
um só; entre outros. Existe dois tipos: a compressão com 
perda e a compressão sem perda.
2 - Codificação run-length
Nesta seção, vimos que a codificação run-length é uma 
das mais simples que existe. Ela consiste em ler todos os 
caracteres de um texto, e condensar as sequências repetidas 
de uma letra pela sua letra e o respectivo número de aparições 
seguidas.
3 - Algoritmo de Huffman
Nesta seção, vimos que outra forma de compactar dados 
em um arquivo é o algoritmo de Huffman. Esse algoritmo 
permite uma economia de 20 a 90% no tamanho do arquivo 
a ser salvo. Para cumprir o seu papel, o código de Huffman 
faz uma contagem de quantas vezes uma letra ou uma palavra 
aparece no texto, e classifica em ordem da quantidade de 
aparições. Depois, as letras ou palavras são agrupadas 
em forma de uma árvore, privilegiando os símbolos mais 
frequentes, colocando eles em posições de profundidade 
menor na árvore. Após isso, temos os códigos para cada 
símbolo nessa árvore, que representam o caminho da raiz até 
o símbolo. O 0 representa a subárvore esquerda, enquanto 
que o 1 representa a subárvore direita.
56
55
CORMEN, Thomas H.; et. al.. Algoritmos: teoria e 
prática. Rio de Janeiro: Campus, 2012.
FOROUZAN, Behrouz; MOSHARRAF, Firouz. 
Fundamentos de Ciência da Computação: Tradução da 2ª edição 
americana. São Paulo: Cengage, 2011.
KNUTH, Donald Ervin. The art of computer programming. 
3. ed. Amsterdam: Addison-Wesley, 1998.
SZWARCFITER, Jayme Luiz; MARKENZON, Lilian. 
Estruturas de dados e seus algoritmos. 2. ed. Rio de Janeiro: LTC, 
1994.
TENENBAUM, Aaron M.; AUGENSTEIN, Moshe 
J.; LANGSAN, Yedidyah. et al. Estruturas de dados usando 
C. São Paulo: Pearson Makron Books; São Paulo: Makron 
Books do Brasil; São Paulo: McGraw-Hill, 2013.
ZIVIANI, Nivio. Projeto de algoritmos: com 
implementação em PASCAL e C. 3. ed. São Paulo: Cengage 
Learning, 2011.
Vale a pena ler
Vale a pena
Referências
BARANAUSKAS. José Augusto. Árvores AVL Árvores 
AVL. USP, s.d. Disponível em: <http://dcm.ffclrp.usp.
br/~augusto/teaching/aedi/AED-I-Arvores-AVL.pdf>. 
Acesso em: 17 set. 2018.
CORMEN, Thomas H.; et. al.. Algoritmos: teoria e 
prática. Rio de Janeiro: Campus, 2012.
FEOFILOFF, Paulo. Hashing. São Paulo: USP, 2017. 
Disponível em: <https://www.ime.usp.br/~pf/estruturas-
de-dados/aulas/st-hash.html>. Acesso em: 07 ago. 2018.
FEOFILOFF, Paulo. Listas encadeadas. São Paulo : 
USP, 2017. Disponível em: <https://www.ime.usp.br/~pf/
algoritmos/aulas/lista.html>. Acesso em: 30 jul. 2018.
FEOFLIOFF, Paulo. Árvores binárias de busca. USP, 
2018. Disponível em: <https://www.ime.usp.br/~pf/
algoritmos/aulas/binst.html>. Acesso em: 15 set. 2018. 
FEOFILOFF, Paulo. Árvores B (B-trees). USP, 2018. 
Disponível em: <https://www.ime.usp.br/~pf/estruturas-
de-dados/aulas/B-trees.html>. Acesso em: 23 set. 2018.
FOROUZAN, Behrouz; MOSHARRAF, Firouz. 
Fundamentos de Ciência da Computação: Tradução da 2ª 
edição americana. São Paulo: Cengage, 2011.
HARGROVE, John. The AVL Tree Rotations Tutorial. 
2007. Disponível em: <https://www.cise.ufl.edu/~nemo/
cop3530/AVL-Tree-Rotations.pdf>. Acesso em: 19 set. 
2018. 
KNUTH, Donald Ervin. The art of computer 
programming. 3. ed. Amsterdam: Addison-Wesley, 1998.
MAFFEO, Bruno. Tipos Abstratos de Dados - Definição 
e Exemplos. PUC, s.d. Disponível em: <http://www.inf.puc-
rio.br/~coordicc/icc/TAD.pdf>. Acesso em: 25 jul. 2018.
MENA-CHALCO, Jesús P. Árvores Adelson-Velskii e 
Landis. UFABC, 2014. Disponível em: <http://professor.
ufabc.edu.br/~jesus.mena/courses/mc3305-2q-2015/
AED2-10.pdf>. Acesso em: 17 set. 2018.
NONATO, Luis Gustavo. Método da Dobra. USP, 2003. 
Disponível em: <http://www.lcad.icmc.usp.br/~nonato/
ED/Hashing/node36-b.html>. Acesso em: 08 ago. 2018.
RICARTE, Ivan L. M. Tabelas Hash. UNICAMP, 2003. 
Disponível em: <http://www.dca.fee.unicamp.br/cursos/
EA876/apostila/HTML/node26.html>. Acesso em: 07 ago. 
2018.
SILVA, Fernando. Listas, Pilhas e Filas. DCC-FCUP, 
s.d. Disponível em: <https://www.dcc.fc.up.pt/~fds/aulas/
EDados/1314/Apontamentos/listas-1x2.pdf>. Acesso em: 
02 ago. 2018.
SONG, Siang Wun. Listas Lineares. USP, 2008. 
Disponível em: <https://www.ime.usp.br/~song/mac5710/
slides/02linear.pdf>. Acesso em: 30 jul. 2018.
SOUZA, Jairo Francisco de. Árvores. UFJF, 2009. 
Disponível em: <http://www.ufjf.br/jairo_souza/
files/2009/12/EDI-06.ED_.Arvores.pdf>. Acesso em: 14 
set. 2018.
SOUZA, Jairo Francisco de. Árvores AVL. UFJF, 
2009. Disponível em: <http://www.ufjf.br/jairo_souza/
files/2009/12/5-Indexa%C3%A7%C3%A3o-Arvore-AVL.
pdf>. Acesso em: 17 set. 2018.
SZWARCFITER, Jayme Luiz; MARKENZON, Lilian. 
Estruturas de dados e seus algoritmos. 2. ed. Rio de Janeiro: 
LTC, 1994.
TENENBAUM, Aaron M.; AUGENSTEIN, Moshe J.; 
LANGSAN, Yedidyah. et al. Estruturas de dados usando C. São 
Paulo: Pearson Makron Books; São Paulo: Makron Books do 
Brasil; São Paulo: McGraw-Hill, 2013.
ZIVIANI, Nivio. Projeto de algoritmos: com implementação 
em PASCAL e C. 3. ed. São Paulo: Cengage Learning, 2011.
Minhas anotações
57

Outros materiais