You are on page 1of 157

Processamento de Cadeias de

Caracteres

ltima alterao: 8 de Novembro de 2010

Transparncias elaboradas por Fabiano Cupertino Botelho, Charles Ornelas Almeida, Israel Guerra e Nivio Ziviani
Projeto de Algoritmos Cap.8 Processamento de Cadeias de Caracteres 1
Contedo do Captulo
8.1 Casamento de Cadeias
8.1.1 Casamento Exato
8.1.2 Casamento Aproximado
8.2 Compresso
8.2.1 Por Que Usar Compresso
8.2.2 Compresso de Textos em Linguagem Natural
8.2.3 Codicao de Huffman Usando Palavras
8.2.4 Codicao de Huffman Usando Bytes
8.2.5 Pesquisa em Texto Comprimido
Projeto de Algoritmos Cap.8 Processamento de Cadeias de Caracteres Seo 8.1 2
Denio e Motivao
Cadeia de caracteres: sequncia de elementos denominados
caracteres.
Os caracteres so escolhidos de um conjunto denominado alfabeto.
Ex.: em uma cadeia de bits o alfabeto {0, 1}.
Casamento de cadeias de caracteres ou casamento de padro:
encontrar todas as ocorrncias de um padro em um texto.
Exemplos de aplicao:
edio de texto;
recuperao de informao;
estudo de sequncias de DNA em biologia computacional.
Projeto de Algoritmos Cap.8 Processamento de Cadeias de Caracteres Seo 8.1 3
Notao
Texto: arranjo T[1..n] de tamanho n;
Padro: arranjo P[1..m] de tamanho m n.
Os elementos de P e T so escolhidos de um alfabeto nito de
tamanho c.
Ex.: = {0, 1} ou = {a, b, . . . , z}.
Casamento de cadeias ou casamento de padro: dados duas
cadeias P (padro) de comprimento |P| = m e T (texto) de
comprimento |T| = n, onde n m, deseja-se saber as ocorrncias de
P em T.
Projeto de Algoritmos Cap.8 Processamento de Cadeias de Caracteres Seo 8.1 4
Estruturas de Dados para Texto e Padro
#define MAXTAMTEXTO 1000
#define MAXTAMPADRAO 10
#define MAXCHAR 256
#define NUMMAXERROS 10
typedef char TipoTexto[ MAXTAMTEXTO] ;
typedef char TipoPadrao[ MAXTAMPADRAO] ;
Projeto de Algoritmos Cap.8 Processamento de Cadeias de Caracteres Seo 8.1 5
Categorias de Algoritmos
P e T no so pr-processados:
algoritmo sequencial, on-line e de tempo-real;
padro e texto no so conhecidos a priori.
complexidade de tempo O(mn) e de espao O(1), para pior caso.
P pr-processado:
algoritmo sequencial;
padro conhecido anteriormente permitindo seu
pr-processamento.
complexidade de tempo O(n) e de espao O(m + c), no pior caso.
ex.: programas para edio de textos.
Projeto de Algoritmos Cap.8 Processamento de Cadeias de Caracteres Seo 8.1 6
Categorias de Algoritmos
P e T so pr-processados:
algoritmo constri ndice.
complexidade de tempo O(log n) e de espao O(n).
tempo para obter o ndice grande, O(n) ou O(nlog n).
compensado por muitas operaes de pesquisa no texto.
Tipos de ndices mais conhecidos:
Arquivos invertidos
rvores trie e rvores Patricia
Arranjos de suxos
Projeto de Algoritmos Cap.8 Processamento de Cadeias de Caracteres Seo 8.1 7
Exemplos: P e T so pr-processados
Diversos tipos de ndices: arquivos invertidos, rvores trie e Patricia, e
arranjos de suxos.
Um arquivo invertido possui duas partes: vocabulrio e
ocorrncias.
O vocabulrio o conjunto de todas as palavras distintas no texto.
Para cada palavra distinta, uma lista de posies onde ela ocorre no
texto armazenada.
O conjunto das listas chamado de ocorrncias.
As posies podem referir-se a palavras ou caracteres.
Projeto de Algoritmos Cap.8 Processamento de Cadeias de Caracteres Seo 8.1 8
Exemplo de Arquivo Invertido
1 7 16 22 26 36 45 53
Texto exemplo. Texto tem palavras. Palavras exercem fascnio.
exemplo 7
exercem 45
fascnio 53
palavras 26 36
tem 22
texto 1 16
Projeto de Algoritmos Cap.8 Processamento de Cadeias de Caracteres Seo 8.1 9
Arquivo Invertido - Tamanho
O vocabulrio ocupa pouco espao.
A previso sobre o crescimento do tamanho do vocabulrio: lei de Heaps.
Lei de Heaps: o vocabulrio de um texto em linguagem natural contendo n
palavras tem tamanho V = Kn

= O(n

), onde K e dependem das


caractersticas de cada texto.
K geralmente assume valores entre 10 e 100, e uma constante entre 0 e
1, na prtica cando entre 0,4 e 0,6.
O vocabulrio cresce sublinearmente com o tamanho do texto, em uma
proporo perto de sua raiz quadrada.
As ocorrncias ocupam muito mais espao.
Como cada palavra referenciada uma vez na lista de ocorrncias, o espao
necessrio O(n).
Na prtica, o espao para a lista de ocorrncias ca entre 30% e 40% do
tamanho do texto.
Projeto de Algoritmos Cap.8 Processamento de Cadeias de Caracteres Seo 8.1 10
Arquivo Invertido - Pesquisa
A pesquisa tem geralmente trs passos:
Pesquisa no vocabulrio: palavras e padres da consulta so
isoladas e pesquisadas no vocabulrio.
Recuperao das ocorrncias: as listas de ocorrncias das
palavras encontradas no vocabulrio so recuperadas.
Manipulao das ocorrncias: as listas de ocorrncias so
processadas para tratar frases, proximidade, ou operaes
booleanas.
Como a pesquisa em um arquivo invertido sempre comea pelo
vocabulrio, interessante mant-lo em um arquivo separado.
Na maioria das vezes, esse arquivo cabe na memria principal.
Projeto de Algoritmos Cap.8 Processamento de Cadeias de Caracteres Seo 8.1 11
Arquivo Invertido - Pesquisa
A pesquisa de palavras simples pode ser realizada usando qualquer
estrutura de dados que torne a busca eciente, como hashing, rvore
trie ou rvore B.
As duas primeiras tm custo O(m), onde m o tamanho da consulta
(independentemente do tamanho do texto).
Guardar as palavras na ordem lexicogrca barato em termos de
espao e competitivo em desempenho, j que a pesquisa binria pode
ser empregada com custo O(log n).
A pesquisa por frases usando ndices mais difcil de resolver.
Cada elemento da frase tem de ser pesquisado separadamente e suas
listas de ocorrncias recuperadas.
A seguir, as listas tm de ser percorridas de forma sicronizada para
encontrar as posies nas quais todas as palavras aparecem em
sequncia.
Projeto de Algoritmos Cap.8 Processamento de Cadeias de Caracteres Seo 8.1 12
Arquivo Invertido Usando Trie
Arquivo invertido usando uma rvore trie para o texto:
Texto exemplo. Texto tem palavras. Palavras exercem fascnio.
fascnio: 53
palavras: 26,36
exercem: 45
exemplo: 7
tem: 22
texto: 1, 16
p
f
e
t
x e
m
r
e
m
x
O vocabulrio lido at o momento colocado em uma rvore trie,
armazenando uma lista de ocorrncias para cada palavra.
Projeto de Algoritmos Cap.8 Processamento de Cadeias de Caracteres Seo 8.1 13
Arquivo Invertido Usando Trie
Cada nova palavra lida pesquisada na trie:
Se a pesquisa sem sucesso, ento a palavra inserida na rvore
e uma lista de ocorrncias inicializada com a posio da nova
palavra no texto.
Seno, uma vez que a palavra j se encontra na rvore, a nova
posio inserida ao nal da lista de ocorrncias.
Projeto de Algoritmos Cap.8 Processamento de Cadeias de Caracteres Seo 8.1.1 14
Casamento Exato
Consiste em obter todas as ocorrncias exatas do padro no texto.
Ex.: ocorrncia exata do padro teste.
teste
os testes testam estes alunos . . .
Dois enfoques:
1. leitura dos caracteres do texto um a um: algoritmos fora bruta,
Knuth-Morris-Pratt e Shift-And.
2. pesquisa de P em uma janela que desliza ao longo de T, pesquisando
por um suxo da janela que casa com um suxo de P, por
comparaes da direita para a esquerda: algoritmos
Boyer-Moore-Horspool e Boyer-Moore.
Projeto de Algoritmos Cap.8 Processamento de Cadeias de Caracteres Seo 8.1.1 15
Fora Bruta - Implementao
o algoritmo mais simples para casamento de cadeias.
A idia tentar casar qualquer subcadeia no texto de comprimento m
com o padro.
void ForcaBruta(TipoTexto T, long n, TipoPadrao P, long m)
{ long i , j , k;
for ( i = 1; i <= (n m + 1) ; i ++)
{ k = i ; j = 1;
while (T[ k1] == P[ j 1] && j <= m) { j ++; k++; }
i f ( j > m) pr i nt f ( " Casamento na posicao%3l d \n" , i ) ;
}
}
Projeto de Algoritmos Cap.8 Processamento de Cadeias de Caracteres Seo 8.1.1 16
Fora Bruta - Anlise
Pior caso: C
n
= mn.
O pior caso ocorre, por exemplo, quando P = aab e T =aaaaaaaaaa.
Caso esperado: C
n
=
c
c1

1
1
c
m

(n m + 1) + O(1)
O caso esperado muito melhor do que o pior caso.
Em experimento com texto randmico e alfabeto de tamanho c = 4, o
nmero esperado de comparaes aproximadamente igual a 1,3.
Projeto de Algoritmos Cap.8 Processamento de Cadeias de Caracteres Seo 8.1.1 17
Autmatos
Um autmato um modelo de computao muito simples.
Um autmato nito denido por uma tupla (Q, I, F, , T ), onde Q
um conjunto nito de estados, entre os quais existe um estado inicial
I Q, e alguns so estados nais ou estados de trmino F Q.
Transies entre estados so rotuladas por elementos de {},
onde o alfabeto nito de entrada e a transio vazia.
As transies so formalmente denidas por uma funo de transio
T .
T associa a cada estado q Q um conjunto {q
1
, q
2
, . . . , q
k
} de estados
de Q para cada {}.
Projeto de Algoritmos Cap.8 Processamento de Cadeias de Caracteres Seo 8.1.1 18
Tipos de Autmatos
Autmato nito no-determinista:
Quando T tal que existe um estado q associado a um dado
caractere para mais de um estado, digamos
T (q, ) = {q
1
, q
2
, . . . , q
k
}, k > 1, ou existe alguma transio rotulada
por .
Neste caso, a funo de transio T denida pelo conjunto de
triplas = {(q, , q

), onde q Q, {}, e q

T (q, ).
Autmato nito determinista:
Quando a funo de transio T denida pela funo
= Q Q.
Neste caso, se T (q, ) = {q

}, ento (q, ) = q

.
Projeto de Algoritmos Cap.8 Processamento de Cadeias de Caracteres Seo 8.1.1 19
Exemplo de Autmatos
Autmato nito no-determinista.
A partir do estado 0, atravs do caractere de transio a possvel
atingir os estados 2 e 3.
a
b
a c
0
1 2
3
Autmato nito determinista.
Para cada caractere de transio todos os estados levam a um nico
estado.
d
b
a c
0
1 2
3
Projeto de Algoritmos Cap.8 Processamento de Cadeias de Caracteres Seo 8.1.1 20
Reconhecimento por Autmato
Uma cadeia reconhecida por (Q, I, F, , ) ou (Q, I, F, , ) se
qualquer um dos autmatos rotula um caminho que vai de um estado
inicial at um estado nal.
A linguagem reconhecida por um autmato o conjunto de cadeias
que o autmato capaz de reconher.
Ex.: a linguagem reconhecida pelo autmato abaixo o conjunto de
cadeias {a} e {abc} no estado 3.
a
b
a c
0
1 2
3
Projeto de Algoritmos Cap.8 Processamento de Cadeias de Caracteres Seo 8.1.1 21
Transies Vazias
So transies rotulada com uma cadeia vazia , tambm chamadas
de transies-, em autmatos no-deterministas
No h necessidade de se ler um caractere para caminhar atravs de
uma transio vazia.
Simplicam a construo do autmato.
Sempre existe um autmato equivalente que reconhece a mesma
linguagem sem transies-.
Projeto de Algoritmos Cap.8 Processamento de Cadeias de Caracteres Seo 8.1.1 22
Estados Ativos
Se uma cadeia x rotula um caminho de I at um estado q ento o
estado q considerado ativo depois de ler x.
Um autmato nito determinista tem no mximo um estado ativo em
um determinado instante.
Um autmato nito no-determinista pode ter vrios estados ativos.
Casamento aproximado de cadeias pode ser resolvido por meio de
autmatos nitos no-deterministas.
Projeto de Algoritmos Cap.8 Processamento de Cadeias de Caracteres Seo 8.1.1 23
Ciclos em Autmatos
Os autmatos abaixo so acclicos pois as transies no formam ciclos.
a
b
a c
0
1 2
3
d
b
a c
0
1 2
3
Autmatos nitos cclicos, deterministas ou no-deterministas, so teis
para casamento de expresses regulares
A linguagem reconhecida por um autmato cclico pode ser innita.
Ex: o autmato abaixo reconhece ba, bba, bbba, bbbba, e assim por diante.
a
a
b
b
0 1
Projeto de Algoritmos Cap.8 Processamento de Cadeias de Caracteres Seo 8.1.1 24
Exemplo de Uso de Autmato
4
3 2 1 0
b
c
a
b,c
c
b
a
a
a
b c
O autmato reconhece P ={aabc}.
A pesquisa de P sobre um texto T com alfabeto ={a, b, c} pode ser
vista como a simulao do autmato na pesquisa de P sobre T.
No incio, o estado inicial ativa o estado 1.
Para cada caractere lido do texto, a aresta correspondente seguida,
ativando o estado destino.
Se o estado 4 estiver ativo e um caractere c lido o estado nal se torna
ativo, resultando em um casamento de aabc com o texto.
Como cada caractere do texto lido uma vez, a complexidade de tempo
O(n), e de espao m+ 2 para vrtices e || m para arestas.
Projeto de Algoritmos Cap.8 Processamento de Cadeias de Caracteres Seo 8.1.1 25
Knuth-Morris-Pratt (KMP)
O KMP o primeiro algoritmo (1977) cujo pior caso tem complexidade
de tempo linear no tamanho do texto, O(n).
um dos algoritmos mais famosos para resolver o problema de
casamento de cadeias.
Tem implementao complicada e na prtica perde em ecincia para
o Shift-And e o Boyer-Moore-Horspool.
At 1971, o limite inferior conhecido para busca exata de padres era
O(mn).
Projeto de Algoritmos Cap.8 Processamento de Cadeias de Caracteres Seo 8.1.1 26
KMP - 2DPDA
Em 1971, Cook provou que qualquer problema que puder ser resolvido por
um autmato determinista de dois caminhos com memria de pilha (Two-way
Deterministic Pushdown Store Automaton, 2DPDA) pode ser resolvido em
tempo linear por uma mquina RAM.
O 2DPDA constitudo de:
uma ta apenas para leitura;
uma pilha de dados (memria temporria);
um controle de estado que permite mover a ta para esquerda ou direita,
empilhar ou desempilhar smbolos, e mudar de estado.
Controle
#
...
$
p
1
p
2
... c
1
c
2
c
n
c
n
c
n1
#
c
1

p
m
Pilha
Cabea de leitura
...
Projeto de Algoritmos Cap.8 Processamento de Cadeias de Caracteres Seo 8.1.1 27
KMP - Casamento de Cadeias no 2DPDA
Controle
#
...
$
p
1
p
2
... c
1
c
2
c
n
c
n
c
n1
#
c
1

p
m
Pilha
Cabea de leitura
...
A entrada do autmato a cadeia: #c
1
c
2
c
n
$p
1
p
2
p
m
.
A partir de # todos os caracteres so empilhados at encontrar o caractere $.
A leitura cotinua at encontrar o caractere .
A seguir a leitura realizada no sentido contrrio, iniciando por p
n
,
comparado-o com o ltimo caractere empilhado, no caso c
n
.
Esta operao repetida para os caracteres seguintes, e se o caractere $ for
atingido ento as duas cadeias so iguais.
Projeto de Algoritmos Cap.8 Processamento de Cadeias de Caracteres Seo 8.1.1 28
KMP - Algoritmo
Primeira verso do KMP uma simulao linear do 2DPDA
O algoritmo computa o suxo mais longo no texto que tambm o
prexo de P.
Quando o comprimento do suxo no texto igual a |P| ocorre um
casamento.
O pr-processamento de P permite que nenhum caractere seja
reexaminado.
O apontador para o texto nunca decrementado.
O pr-processamento de P pode ser visto como a construo
econmica de um autmato determinista que depois usado para
pesquisar pelo padro no texto.
Projeto de Algoritmos Cap.8 Processamento de Cadeias de Caracteres Seo 8.1.1 29
Shift-And
O Shift-And vezes mais rpido e muito mais simples do que o KMP.
Pode ser estendido para permitir casamento aproximado de cadeias
de caracteres.
Usa o conceito de paralelismo de bit:
tcnica que tira proveito do paralelismo intrnseco das operaes
sobre bits dentro de uma palavra de computador.
possvel empacotar muitos valores em uma nica palavra e
atualizar todos eles em uma nica operao.
Tirando proveito do paralelismo de bit, o nmero de operaes que um
algoritmo realiza pode ser reduzido por um fator de at w, onde w o
nmero de bits da palavra do computador.
Projeto de Algoritmos Cap.8 Processamento de Cadeias de Caracteres Seo 8.1.1 30
Shift-And: Operaes com Paralelismo de Bit
Para denotar repetio de bit usado exponenciao: 01
3
= 0111.
Uma sequncia de bits b
1
. . . b
c
chamada de mscara de bits de
comprimento c, e armazenada em alguma posio de uma palavra w
do computador.
Operaes sobre os bits da palavra do computador:
|: operao or;
&: operao and;
: complementa todos os bits;
>>: move os bits para a direita e entra com zeros esquerda (por
exemplo, b
1
, b
2
, . . . , b
c1
, b
c
>> 2 = 00b
3
, . . . , b
c2
).
Projeto de Algoritmos Cap.8 Processamento de Cadeias de Caracteres Seo 8.1.1 31
Shift-And - Princpio de Funcionamento
Mantm um conjunto de todos os prexos de P que casam com o
texto j lido.
Utiliza o paralelismo de bit para atualizar o conjunto a cada caractere
lido do texto.
Este conjunto representado por uma mscara de bits
R = (b
1
, b
2
, . . . , b
m
).
O algoritmo Shift-And pode ser visto como a simulao de um
autmato que pesquisa pelo padro no texto (no-determinista para
simular o paralelismo de bit).
Ex.: Autmato no-determinista que reconhece todos os prexos de
P ={teste}
0 2 3 4 5 1
e t s e t

Projeto de Algoritmos Cap.8 Processamento de Cadeias de Caracteres Seo 8.1.1 32


Shift-And - Algoritmo
O valor 1 colocado na j-sima posio de R = (b
1
, b
2
, . . . , b
m
) se e
somente se p
1
. . . p
j
um suxo de t
1
. . . t
i
, onde i corresponde
posio corrente no texto.
A j-sima posio de R dita estar ativa.
b
m
ativo signica um casamento.
R

, o novo valor do conjunto R, calculado na leitura do prximo


caractere t
i+1
.
A posio j + 1 em R

car ativa se e somente se a posio j estava


ativa em R (p
1
. . . p
j
era suxo de t
1
. . . t
i
e t
i+1
casa com p
j+1
).
Com o uso de paralelismo de bit possvel computar o novo conjunto
com custo O(1).
Projeto de Algoritmos Cap.8 Processamento de Cadeias de Caracteres Seo 8.1.1 33
sHift-And - Pr-processamento
O primeiro passo a construo de uma tabela M para armazenar
uma mscara de bits b
1
. . . , b
m
para cada caractere.
Ex.: mscaras de bits para os caracteres presentes em P ={teste}.
1 2 3 4 5
M[t] 1 0 0 1 0
M[e] 0 1 0 0 1
M[s] 0 0 1 0 0
A mscara em M[t] 10010, pois o caractere t aparece nas posies
1 e 4 de P.
Projeto de Algoritmos Cap.8 Processamento de Cadeias de Caracteres Seo 8.1.1 34
Shift-And - Pesquisa
O valor do conjunto inicializado como R = 0
m
(0
m
signica 0 repetido
m vezes).
Para cada novo caractere t
i+1
lido do texto o valor do conjunto R

atualizado: R

= ((R >> 1) | 10
m1
) & M[T[i]].
A operao >> desloca todas as posies para a direita no passo
i + 1 para marcar quais posies de P eram suxos no passo i.
A cadeia vazia tambm marcada como um suxo, permitindo um
casamento na posio corrente do texto (self-loop no incio do
autmato).
0 2 3 4 5 1
e t s e t

Do conjunto obtido at o momento, so mantidas apenas as posies


que t
i+1
casa com p
j+1
, obtido com a operao and desse conjunto de
posies com o conjunto M[t
i+1
] de posies de t
i+1
em P.
Projeto de Algoritmos Cap.8 Processamento de Cadeias de Caracteres Seo 8.1.1 35
Exemplo de Funcionamento do Shif-And
Pesquisa do padro P ={teste} no texto T ={os testes ...}.
Texto (R >> 1)|10
m1
R

o 1 0 0 0 0 0 0 0 0 0
s 1 0 0 0 0 0 0 0 0 0
1 0 0 0 0 0 0 0 0 0
t 1 0 0 0 0 1 0 0 0 0
e 1 1 0 0 0 0 1 0 0 0
s 1 0 1 0 0 0 0 1 0 0
t 1 0 0 1 0 1 0 0 1 0
e 1 1 0 0 1 0 1 0 0 1
s 1 0 1 0 0 0 0 1 0 0
1 0 0 1 0 0 0 0 0 0
Projeto de Algoritmos Cap.8 Processamento de Cadeias de Caracteres Seo 8.1.1 36
Shift-And - Implementao
ShiftAnd ( P = p
1
p
2
p
m
, T = t
1
t
2
t
n
)
{ /Prprocessamento/
for ( c ) M[ c] = 0
m
;
for ( j = 1; j <= m; j ++) M[ p
j
] = M[ p
j
] | 0
j1
10
mj
;
/Pesquisa/
R = 0
m
;
for ( i = 1; i <= n; i ++)
{ R = ( ( R >> 1| 10
m1
) & M[ T [ i ] ] ) ;
i f ( R & 0
m1
1 = 0
m
) Casamento na posicao i m + 1 ;
}
}
As operaes and, or, deslocamento direita e complemento no
podem ser realizadas com ecincia na linguagem Pascal padro, o
que compromete o conceito de paralelismo de bit.
Anlise: O custo do algoritmo Shift-And O(n), desde que as
operaes possam ser realizadas em O(1) e o padro caiba em umas
poucas palavras do computador.
Projeto de Algoritmos Cap.8 Processamento de Cadeias de Caracteres Seo 8.1.1 37
Boyer-Moore-Horspool (BMH)
Em 1977, foi publicado o algoritmo Boyer-Moore (BM).
A idia pesquisar no padro no sentido da direita para a esquerda, o
que torna o algoritmo muito rpido.
Em 1980, Horspool apresentou uma simplicao no algoritmo
original, to eciente quanto o algoritmo original, cando conhecida
como Boyer-Moore-Horspool (BMH).
Pela extrema simplicidade de implementao e comprovada ecincia,
o BMH deve ser escolhido em aplicaes de uso geral que necessitam
realizar casamento exato de cadeias.
Projeto de Algoritmos Cap.8 Processamento de Cadeias de Caracteres Seo 8.1.1 38
Funcionamento do BM e BMH
O BM e BMH pesquisa o padro P em uma janela que desliza ao
longo do texto T.
Para cada posio desta janela, o algoritmo pesquisa por um suxo da
janela que casa com um suxo de P, com comparaes realizadas no
sentido da direita para a esquerda.
Se no ocorrer uma desigualdade, ento uma ocorrncia de P em T
ocorreu.
Seno, o algoritmo calcula um deslocamento que o padro deve ser
deslizado para a direita antes que uma nova tentativa de casamento
se inicie.
O BM original prope duas heursticas para calcular o deslocamento:
ocorrncia e casamento.
Projeto de Algoritmos Cap.8 Processamento de Cadeias de Caracteres Seo 8.1.1 39
BM - Heurstica Ocorrncia
Alinha a posio no texto que causou a coliso com o primeiro caractere no
padro que casa com ele;
Ex.: P ={cacbac}, T ={aabcaccacbac}.
1 2 3 4 5 6 7 8 9 0 1 2
c a c b a c
a a b c a c c a c b a c
c a c b a c
c a c b a c
c a c b a c
c a c b a c
A partir da posio 6, da direita para a esquerda, existe uma coliso na
posio 4 de T, entre b do padro e c do texto.
Logo, o padro deve ser deslocado para a direita at o primeiro caractere no
padro que casa com c.
O processo repetido at encontrar casamento a partir da posio 7 de T.
Projeto de Algoritmos Cap.8 Processamento de Cadeias de Caracteres Seo 8.1.1 40
BM - Heurstica Casamento
Ao mover o padro para a direita, faa-o casar com o pedao do texto
anteriormente casado.
Ex.: P ={cacbac} no texto T ={aabcaccacbac}.
1 2 3 4 5 6 7 8 9 0 1 2
c a c b a c
a a b c a c c a c b a c
c a c b a c
c a c b a c
Novamente, a partir da posio 6, da direita para a esquerda, existe uma
coliso na posio 4 de T, entre o b do padro e o c do texto.
Neste caso, o padro deve ser deslocado para a direita at casar com o
pedao do texto anteriormente casado, no caso ac, deslocando o padro 3
posies direita.
O processo repetido mais uma vez e o casamento entre P e T ocorre.
Projeto de Algoritmos Cap.8 Processamento de Cadeias de Caracteres Seo 8.1.1 41
Escolha da Heurstica
O algoritmo BM escolhe a heurstica que provoca o maior
deslocamento do padro.
Esta escolha implica em realizar uma comparao entre dois inteiros
para cada caractere lido do texto, penalizando o desempenho do
algoritmo com relao a tempo de processamento.
Vrias propostas de simplicao ocorreram ao longo dos anos.
As que produzem os melhores resultados so as que consideram
apenas a heurstica ocorrncia.
Projeto de Algoritmos Cap.8 Processamento de Cadeias de Caracteres Seo 8.1.1 42
Algoritmo Boyer-Moore-Horspool (BMH)
A simplicao mais importante devida a Horspool em 1980.
Executa mais rpido do que o algoritmo BM original.
Parte da observao de que qualquer caractere j lido do texto a partir
do ltimo deslocamento pode ser usado para enderear a tabela de
deslocamentos.
Enderea a tabela com o caractere no texto correspondente ao ltimo
caractere do padro.
Projeto de Algoritmos Cap.8 Processamento de Cadeias de Caracteres Seo 8.1.1 43
BMH - Tabela de Deslocamentos
Para pr-computar o padro o valor inicial de todas as entradas na
tabela de deslocamentos feito igual a m.
A seguir, apenas para os m1 primeiros caracteres do padro so
usados para obter os outros valores da tabela.
Formalmente, d[x] = min{jtalquej = m|(1 j < m&P[mj] = x)}.
Ex.: Para o padro P ={teste}, os valores de d so d[t] = 1, d[e] = 3,
d[s] = 2, e todos os outros valores so iguais ao valor de |P|, nesse caso
m = 5.
Projeto de Algoritmos Cap.8 Processamento de Cadeias de Caracteres Seo 8.1.1 44
BMH - Implementao
void BMH(TipoTexto T, long n, TipoPadrao P, long m)
{ long i , j , k, d[ MAXCHAR + 1] ;
for ( j = 0; j <= MAXCHAR; j ++) d[ j ] = m;
for ( j = 1; j < m; j ++) d[P[ j 1]] = m j ;
i = m;
while ( i <= n) /Pesquisa/
{ k = i ;
j = m;
while (T[ k1] == P[ j 1] && j > 0) { k; j ; }
i f ( j == 0)
pr i nt f ( " Casamento na posicao: %3l d \n" , k + 1);
i += d[T[ i 1]];
}
}
d[ord(T[i])] equivale ao en-
dereo na tabela d do
caractere que est na i-
sima posio no texto, a
qual corresponde posi-
o do ltimo caractere de
P.
Projeto de Algoritmos Cap.8 Processamento de Cadeias de Caracteres Seo 8.1.1 45
Algoritmo BMHS - Boyer-Moore-Horspool-Sunday
Sunday (1990) apresentou outra simplicao importante para o
algoritmo BM, cando conhecida como BMHS.
Variante do BMH: enderear a tabela com o caractere no texto
correspondente ao prximo caractere aps o ltimo caractere do
padro, em vez de deslocar o padro usando o ltimo caractere como
no algoritmo BMH.
Para pr-computar o padro, o valor inicial de todas as entradas na
tabela de deslocamentos feito igual a m + 1.
A seguir, os m primeiros caracteres do padro so usados para obter
os outros valores da tabela.
Formalmente
d[x] = min{j tal que j = m | (1 j m & P[m + 1 j] = x)}.
Para o padro P = teste, os valores de d so d[t] = 2, d[e] = 1,
d[s] = 3, e todos os outros valores so iguais ao valor de |P| + 1.
Projeto de Algoritmos Cap.8 Processamento de Cadeias de Caracteres Seo 8.1.1 46
BMHS - Implementao
void BMHS(TipoTexto T, long n, TipoPadrao P, long m)
{ long i , j , k, d[ MAXCHAR + 1] ;
for ( j = 0; j <= MAXCHAR; j ++) d[ j ] = m + 1;
for ( j = 1; j <= m; j ++) d[P[ j 1]] = m j + 1;
i = m;
while ( i <= n) /Pesquisa/
{ k = i ;
j = m;
while (T[ k1] == P[ j 1] && j > 0) { k; j ; }
i f ( j == 0)
pr i nt f ( " Casamento na posicao: %3l d \n" , k + 1);
i += d[T[ i ] ] ;
}
}
A fase de pesquisa
constituda por um anel
em que i varia de m
at n, com incrementos
d[ord(T[i+1])], o que equi-
vale ao endereo na ta-
bela d do caractere que
est na i + 1-sima posi-
o no texto, a qual cor-
responde posio do l-
timo caractere de P.
Projeto de Algoritmos Cap.8 Processamento de Cadeias de Caracteres Seo 8.1.1 47
BH - Anlise
Os dois tipos de deslocamento (ocorrncia e casamento) podem ser
pr-computados com base apenas no padro e no alfabeto.
Assim, a complexidade de tempo e de espao para esta fase
O(m + c).
O pior caso do algoritmo O(n + rm), onde r igual ao nmero total
de casamentos, o que torna o algoritmo inecente quando o nmero
de casamentos grande.
O melhor caso e o caso mdio para o algoritmo O(n/m), um
resultado excelente pois executa em tempo sublinear.
Projeto de Algoritmos Cap.8 Processamento de Cadeias de Caracteres Seo 8.1.1 48
BMH - Anlise
O deslocamento ocorrncia tambm pode ser pr-computado com
base apenas no padro e no alfabeto.
A complexidade de tempo e de espao para essa fase O(c).
Para a fase de pesquisa, o pior caso do algoritmo O(nm), o melhor
caso O(n/m) e o caso esperado O(n/m), se c no pequeno e m
no muito grande.
Projeto de Algoritmos Cap.8 Processamento de Cadeias de Caracteres Seo 8.1.1 49
BMHS - Anlise
Na variante BMHS, seu comportamento assinttico igual ao do
algoritmo BMH.
Entretanto, os deslocamentos so mais longos (podendo ser iguais a
m + 1), levando a saltos relativamente maiores para padres curtos.
Por exemplo, para um padro de tamanho m = 1, o deslocamento
igual a 2m quando no h casamento.
Projeto de Algoritmos Cap.8 Processamento de Cadeias de Caracteres Seo 8.1.2 50
Casamento Aproximado
O casamento aproximado de cadeias permite operaes de insero,
substituio e retirada de caracteres do padro. Ex.: Trs ocorrncias
do padro teste em que os casos de insero, substituio, retirada
de caracteres no padro acontecem:
1. um espao inserido entre o terceiro e quarto caracteres do
padro;
2. o ltimo caractere do padro substitudo pelo caractere a;
3. o primeiro caractere do padro retirado.
tes te
testa
este
os testes testam estes alunos . . .
Projeto de Algoritmos Cap.8 Processamento de Cadeias de Caracteres Seo 8.1.2 51
Distncia de Edio
Nmero k de operaes de insero, substituio e retirada de
caracteres necessrio para transformar uma cadeia x em outra cadeia
y.
ed(P, P

): distncia de edio entre duas cadeias P e P

; o menor
nmero de operaes necessrias para converter P em P

, ou vice
versa.
Ex.: ed(teste, estende) = 4, valor obtido por meio de uma retirada do
primeiro t de P e a insero dos 3 caracteres nde ao nal de P.
O problema do casamento aproximado de cadeias o de encontrar
todas as ocorrncias em T de cada P

que satisfaz ed(P, P

) k.
Projeto de Algoritmos Cap.8 Processamento de Cadeias de Caracteres Seo 8.1.2 52
Casamento Aproximado
A busca aproximada s faz sentido para 0 < k < m, pois para k = m toda
subcadeia de comprimento m pode ser convertida em P por meio da
substituio de m caracteres.
O caso em que k = 0 corresponde ao casamento exato de cadeias.
O nvel de erro = k/m, fornece uma medida da frao do padro que pode
ser alterado.
Em geral < 1/2 para a maioria dos casos de interesse.
Casamento aproximado de cadeias, ou casamento de cadeias
permitindo erros: um nmero limitado k de operaes (erros) de insero,
de substituio e de retirada permitido entre P e suas ocorrncias em T.
A pesquisa com casamento aproximado modelado por autmato
no-determinista.
O algoritmo de casamento aproximado de cadeias usa o paralelismo de bit.
Projeto de Algoritmos Cap.8 Processamento de Cadeias de Caracteres Seo 8.1.2 53
Exemplo de Autmato para Casamento Aproximado
e e e e e
t e e s
t e s t e
(a)
(b)
(c)
t e e s
t e s t e
t e e s
t e s t e

t
0 1 2 3 4 5
5 4 3 2 1
0 1 2 3 4 5
4 3 2 1
0 1 2 3 4
5 4 3 2 1
5
5
0
P ={teste} e k = 1.
(a) insero; (b) substitui-
o e (c) retirada.
Casamento de caractere
representado por uma
aresta horizontal. Avana-
mos em P e T.
O self-loop permite que
uma ocorrncia se inicie em
qualquer posio em T.
Projeto de Algoritmos Cap.8 Processamento de Cadeias de Caracteres Seo 8.1.2 54
Exemplo de Autmato para Casamento Aproximado
Uma aresta vertical insere um caractere no padro. Avanamos em T
mas no em P.
t e e s
t e s t e

0 1 2 3 4 5
5 4 3 2 1
Uma aresta diagonal slida substitui um caractere. Avanamos em T e
P.
t e e s
t e s t e

0 1 2 3 4 5
4 3 2 1 5
Projeto de Algoritmos Cap.8 Processamento de Cadeias de Caracteres Seo 8.1.2 55
Exemplo de Autmato para Casamento Aproximado
Uma aresta diagonal tracejada retira um caractere. Avanamos em P
mas no em T (transio-)
t e e s
t e s t e

0 1 2 3 4
5 4 3 2 1
5
Projeto de Algoritmos Cap.8 Processamento de Cadeias de Caracteres Seo 8.1.2 56
Exemplo de Autmato para Casamento Aproximado
t e s t e
t e s t e
e t s e t

5
5
5


0
0
0
1
1
1
2
2
2 3
3
3
4
4
4
P ={teste} e K = 2.
As trs operaes de distncia de edio esto juntas em um nico autmato:
Linha 1: casamento exato (k = 0);
Linha 2: casamento aproximado permitindo um erro (k = 1);
Linha 3: casamento aproximado permitindo dois erros (k = 2).
Uma vez que um estado no autmato est ativo, todos os estados nas linhas
seguintes na mesma coluna tambm esto ativos.
Projeto de Algoritmos Cap.8 Processamento de Cadeias de Caracteres Seo 8.1.2 57
Shift-And para Casamento Aproximado
Utiliza paralelismo de bit.
Simula um autmato no-determinista.
Empacota cada linha j (0 < j k) do autmato no-determinista em
uma palavra R
j
diferente do computador.
Para cada novo caractere lido do texto todas as transies do
autmato so simuladas usando operaes entre as k + 1 mscaras
de bits.
Todas as k + 1 mscaras de bits tm a mesma estrutura e assim o
mesmo bit alinhado com a mesma posio no texto.
Projeto de Algoritmos Cap.8 Processamento de Cadeias de Caracteres Seo 8.1.2 58
Shift-And para Casamento Aproximado
Na posio i do texto, os novos valores R

j
, 0 < j k, so obtidos a partir dos
valores correntes R
j
:
R

0
= ((R
0
>> 1) | 10
m1
) & M[T[i]]
R

j
= ((R
j
>> 1) & M[T[i]]) | R
j1
| (R
j1
>> 1) | (R

j1
>> 1) | 10
m1
,
onde M a tabela do algoritmo Shift-And para casamento exato.
A pesquisa inicia com R
j
= 1
j
0
mj
.
R
0
equivale ao algoritmo Shift-And para casamento exato.
As outras linhas R
j
recebem 1s (estados ativos) tambm de linhas anteriores.
Considerando um automato para casamento aproximado, a frmula para R

expressa:
arestas horizontais indicando casamento;
verticais indicando insero;
diagonais cheias indicando substituio;
diagonais tracejadas indicando retirada.
Projeto de Algoritmos Cap.8 Processamento de Cadeias de Caracteres Seo 8.1.2 59
Shif-And para Casamento Aproximado: Primeiro
Renamento
void Shift-And-Aproximado ( P = p
1
p
2
. . . p
m
, T = t
1
t
2
. . . t
n
, k)
{ /Prprocessamento/
for ( c ) M[c] = 0
m
;
for ( j = 1; j <= m; j ++) M[p
j
] = M[p
j
] | 0
j1
10
mj
;
/Pesquisa/
for ( j = 0; j <= k; j ++) R
j
= 1
j
0
mj
;
for ( i = 1; i <= n; i ++)
{ Rant = R
0
;
Rnovo = ((Rant >> 1) | 10
m1
) & M[T[i]] ;
R
0
= Rnovo;
for ( j = 1; j <= k; j ++)
{ Rnovo = ((R
j
>> 1 & M[T[i]]) | Rant | ((Rant | Rnovo) >> 1));
Rant = R
j
;
R
j
= Rnovo | 10
m1
;
}
i f ( Rnovo & 0
m1
1 = 0
m
) Casamento na posicao i ;
}
}
Projeto de Algoritmos Cap.8 Processamento de Cadeias de Caracteres Seo 8.1.2 60
Shif-And para Casamento Aproximado - Implementao
void ShiftAndAproximado(TipoTexto T, long n, TipoPadrao P, long m, long k)
{ long Masc[ MAXCHAR] , i , j , Ri , Rant , Rnovo;
long R[ NUMMAXERROS + 1] ;
for ( i = 0; i < MAXCHAR; i ++) Masc[ i ] = 0;
for ( i = 1; i <= m; i ++) { Masc[P[ i 1] + 127] |= 1 << (m i ) ; }
R[ 0] = 0; Ri = 1 << (m 1);
for ( j = 1; j <= k; j ++) R[ j ] = (1 << (m j ) ) | R[ j 1];
for ( i = 0; i < n; i ++)
{ Rant = R[ 0] ;
Rnovo = ( ( ( (unsigned long)Rant) >> 1) | Ri ) & Masc[T[ i ] + 127];
R[ 0] = Rnovo;
for ( j = 1; j <= k; j ++)
{ Rnovo = ( ( ( (unsigned long)R[ j ]) >> 1) & Masc[T[ i ] + 127])
| Rant | ( ( ( unsigned long) (Rant | Rnovo)) >> 1);
Rant = R[ j ] ; R[ j ] = Rnovo | Ri ;
}
i f ( (Rnovo & 1) ! = 0) pr i nt f ( " Casamento na posicao%12l d \n" , i + 1);
}
}
Projeto de Algoritmos Cap.8 Processamento de Cadeias de Caracteres Seo 8.1.2 61
Shif-And para Casamento Aproximado - 1 Erro de
Insero
Padro: teste.
Texto: os testes testam.
Permitindo um erro (k = 1) de insero.
R

0
= (R
0
>> 1)|10
m1
&M[T[i]]
R

1
= (R
1
>> 1)&M[T[i]]|R
0
|(10
m1
)
Uma ocorrncia exata na posio 8 (e) e duas, permitindo uma insero,
nas posies 9 e 12 (s e e, respectivamente).
Projeto de Algoritmos Cap.8 Processamento de Cadeias de Caracteres Seo 8.1.2 62
Shif-And para Casamento Aproximado - 1 Erro de
Insero
Texto (R
0
>> 1)|10
m1
R

0
R
1
>> 1 R

1
o 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0
s 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0
1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0
t 1 0 0 0 0 1 0 0 0 0 0 1 0 0 0 1 0 0 0 0
e 1 1 0 0 0 0 1 0 0 0 0 1 0 0 0 1 1 0 0 0
s 1 0 1 0 0 0 0 1 0 0 0 1 1 0 0 1 1 1 0 0
t 1 0 0 1 0 1 0 0 1 0 0 1 1 1 0 1 0 1 1 0
e 1 1 0 0 1 0 1 0 0 1 0 1 0 1 1 1 1 0 1 1
s 1 0 1 0 0 0 0 1 0 0 0 1 1 0 1 1 1 1 0 1
1 0 0 0 0 0 0 0 0 0 0 1 1 1 0 1 0 1 0 0
t 1 0 0 0 0 1 0 0 0 0 0 1 0 1 0 1 0 0 1 0
e 1 1 0 0 0 0 1 0 0 0 0 1 0 0 1 1 1 0 0 1
s 1 0 1 0 0 0 0 1 0 0 0 1 1 0 0 1 1 1 0 0
t 1 0 0 1 0 1 0 0 1 0 0 1 1 1 0 1 0 1 1 0
a 1 1 0 0 1 0 0 0 0 0 0 1 0 1 1 1 0 0 1 0
m 1 0 0 0 0 0 0 0 0 0 0 1 0 0 1 1 0 0 0 0
Projeto de Algoritmos Cap.8 Processamento de Cadeias de Caracteres Seo 8.1.2 63
Shif-And para Casamento Aproximado - 1 Erro de
Insero, 1 Erro de Retirada e 1 Erro de Substituio
Padro: teste.
Texto: os testes testam.
Permitindo um erro de insero, um de retirada e um de substituio.
R

0
= (R
0
>> 1)|10
m1
&M[T[i]].
R

1
= (R
1
>> 1)&M[T[i]]|R
0
|(R

0
>> 1)|(R
0
>> 1)|(10
m1
)
Uma ocorrncia exata na posio 8 (e) e cinco, permitindo um erro,
nas posies 7, 9, 12, 14 e 15 (t, s, e, t e a, respec.).
Projeto de Algoritmos Cap.8 Processamento de Cadeias de Caracteres Seo 8.1.2 64
Shif-And para Casamento Aproximado - 1 Erro de
Insero, 1 Erro de Retirada e 1 Erro de Substituio
Texto (R
0
>> 1)|10
m1
R

0
R
1
>> 1 R

1
o 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0
s 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0
1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0
t 1 0 0 0 0 1 0 0 0 0 0 1 0 0 0 1 1 0 0 0
e 1 1 0 0 0 0 1 0 0 0 0 1 1 0 0 1 1 1 0 0
s 1 0 1 0 0 0 0 1 0 0 0 1 1 1 0 1 1 1 1 0
t 1 0 0 1 0 1 0 0 1 0 0 1 1 1 1 1 1 1 1 1
e 1 1 0 0 1 0 1 0 0 1 0 1 1 1 1 1 1 1 1 1
s 1 0 1 0 0 0 0 1 0 0 0 1 1 1 1 1 1 1 1 1
1 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 0 1 1 0
t 1 0 0 0 0 1 0 0 0 0 0 1 0 1 1 1 1 0 1 0
e 1 1 0 0 0 0 1 0 0 0 0 1 1 0 1 1 1 1 0 1
s 1 0 1 0 0 0 0 1 0 0 0 1 1 1 0 1 1 1 1 0
t 1 0 0 1 0 1 0 0 1 0 0 1 1 1 1 1 1 1 1 1
a 1 1 0 0 1 0 0 0 0 0 0 1 1 1 1 1 1 0 1 1
m 1 0 0 0 0 0 0 0 0 0 0 1 1 0 1 1 0 0 0 0
Projeto de Algoritmos Cap.8 Processamento de Cadeias de Caracteres Seo 8.2 65
Compresso - Motivao
Exploso de informao textual disponvel on-line:
Bibliotecas digitais.
Sistemas de automao de escritrios.
Bancos de dados de documentos.
World-Wide Web.
Somente a Web tem hoje bilhes de pginas estticas disponveis.
Cada bilho de pginas ocupando aproximadamente 10 terabytes de
texto corrido.
Em setembro de 2003, a mquina de busca Google
(www.google.com.br) dizia ter mais de 3,5 bilhes de pginas estticas
em seu banco de dados.
Projeto de Algoritmos Cap.8 Processamento de Cadeias de Caracteres Seo 8.2 66
Caractersticas necessrias para sistemas de
recuperao de informao
Mtodos recentes de compresso tm permitido:
1. Pesquisar diretamente o texto comprimido mais rapidamente do
que o texto original.
2. Obter maior compresso em relao a mtodos tradicionais,
gerando maior economia de espao.
3. Acessar diretamente qualquer parte do texto comprimido sem
necessidade de descomprimir todo o texto desde o incio (Moura,
Navarro, Ziviani e Baeza-Yates, 2000; Ziviani, Moura, Navarro e
Baeza-Yates, 2000).
Compromisso espao X tempo:
vencer-vencer.
Projeto de Algoritmos Cap.8 Processamento de Cadeias de Caracteres Seo 8.2.1 67
Porque Usar Compresso
Compresso de texto - maneiras de representar o texto original em
menos espao:
Substituir os smbolos do texto por outros que possam ser
representados usando um nmero menor de bits ou bytes.
Ganho obtido: o texto comprimido ocupa menos espao de
armazenamento menos tempo para ser lido do disco ou ser
transmitido por um canal de comunicao e para ser pesquisado.
Preo a pagar: custo computacional para codicar e decodicar o
texto.
Avano da tecnologia: De acordo com Patterson e Hennessy (1995),
em 20 anos, o tempo de acesso a discos magnticos tem se mantido
praticamente constante, enquanto a velocidade de processamento
aumentou aproximadamente 2 mil vezes melhor investir mais poder
de computao em compresso em troca de menos espao em disco
ou menor tempo de transmisso.
Projeto de Algoritmos Cap.8 Processamento de Cadeias de Caracteres Seo 8.2.1 68
Razo de Compresso
Denida pela porcentagem que o arquivo comprimido representa em
relao ao tamanho do arquivo no comprimido.
Exemplo: se o arquivo no comprimido possui 100 bytes e o arquivo
comprimido resultante possui 30 bytes, ento a razo de compresso
de 30%.
Utilizada para medir O ganho em espao obtido por um mtodo de
compresso.
Projeto de Algoritmos Cap.8 Processamento de Cadeias de Caracteres Seo 8.2.1 69
Outros Importantes Aspectos a Considerar
Alm da economia de espao, deve-se considerar:
Velocidade de compresso e de descompresso.
Possibilidade de realizar casamento de cadeias diretamente no texto
comprimido.
Permitir acesso direto a qualquer parte do texto comprimido e iniciar a
descompresso a partir da parte acessada:
Um sistema de recuperao de informao para grandes colees
de documentos que estejam comprimidos necessitam acesso
direto a qualquer ponto do texto comprimido.
Projeto de Algoritmos Cap.8 Processamento de Cadeias de Caracteres Seo 8.2.2 70
Compresso de Textos em Linguagem Natural
Um dos mtodos de codicao mais conhecidos o de Huffman (1952):
Atribui cdigos mais curtos a smbolos com frequncias altas.
Um cdigo nico, de tamanho varivel, atribudo a cada smbolo
diferente do texto.
As implementaes tradicionais do mtodo de Huffman consideram
caracteres como smbolos.
Para aliar as necessidades dos algoritmos de compresso s necessidades
dos sistemas de recuperao de informao apontadas acima, deve-se
considerar palavras como smbolos a serem codicados.
Mtodos de Huffman baseados em caracteres comprimem o texto para
aproximadamente 60%.
Mtodos de Huffman baseados em palavras comprimem o texto para valores
pouco acima de 25%.
Projeto de Algoritmos Cap.8 Processamento de Cadeias de Caracteres Seo 8.2.2 71
Mtodos de Huffman Baseados em Palavras: Vantagens
Permitem acesso randmico a palavras dentro do texto comprimido.
Considerar palavras como smbolos signica que a tabela de smbolos
do codicador exatamente o vocabulrio do texto.
Isso permite uma integrao natural entre o mtodo de compresso e
o arquivo invertido.
Permitem acessar diretamente qualquer parte do texto comprimido
sem necessidade de descomprimir todo o texto desde o incio.
Projeto de Algoritmos Cap.8 Processamento de Cadeias de Caracteres Seo 8.2.2 72
Famlia de Mtodos de Compresso Ziv-Lempel
Substitui uma sequncia de smbolos por um apontador para uma
ocorrncia anterior daquela sequncia.
A compresso obtida porque os apontadores ocupam menos espao
do que a sequncia de smbolos que eles substituem.
Os mtodos Ziv-Lempel so populares pela sua velocidade, economia
de memria e generalidade.
J o mtodo de Huffman baseado em palavras muito bom quando a
cadeia de caracteres constitui texto em linguagem natural.
Projeto de Algoritmos Cap.8 Processamento de Cadeias de Caracteres Seo 8.2.2 73
Desvantagens dos Mtodos de Ziv-Lempel para Ambiente
de Recuperao de Informao
necessrio iniciar a decodicao desde o incio do arquivo
comprimido Acesso randmico muito caro.
muito difcil pesquisar no arquivo comprimido sem descomprimir.
Uma possvel vantagem do mtodo Ziv-Lempel o fato de no ser
necesrio armazenar a tabela de smbolos da maneira com que o
mtodo de Huffman precisa.
No entanto, isso tem pouca importncia em um ambiente de
recuperao de informao, j que se necessita o vocabulrio do texto
para criar o ndice e permitir a pesquisa eciente.
Projeto de Algoritmos Cap.8 Processamento de Cadeias de Caracteres Seo 8.2.3 74
Compresso de Huffman Usando Palavras
Tcnica de compresso mais ecaz para textos em linguagem natural.
O mtodo considera cada palavra diferente do texto como um smbolo.
Conta suas frequncias e gera um cdigo de Huffman para as
palavras.
A seguir, comprime o texto substituindo cada palavra pelo seu cdigo.
Assim, a compresso realizada em duas passadas sobre o texto:
1. Obteno da frequncia de cada palavra diferente.
2. Realizao da compresso.
Projeto de Algoritmos Cap.8 Processamento de Cadeias de Caracteres Seo 8.2.3 75
Forma Eciente de Lidar com Palavras e Separadores
Um texto em linguagem natural constitudo de palavras e de
separadores.
Separadores so caracteres que aparecem entre palavras: espao,
vrgula, ponto, ponto e vrgula, interrogao, e assim por diante.
Uma forma eciente de lidar com palavras e separadores
representar o espao simples de forma implcita no texto comprimido.
Nesse modelo, se uma palavra seguida de um espao, ento,
somente a palavra codicada.
Seno, a palavra e o separador so codicados separadamente.
No momento da decodicao, supe-se que um espao simples
segue cada palavra, a no ser que o prximo smbolo corresponda a
um separador.
Projeto de Algoritmos Cap.8 Processamento de Cadeias de Caracteres Seo 8.2.3 76
Compresso usando codicao de Huffman
Exemplo: para cada rosa rosa, uma rosa uma rosa
rosa
4
,
1
uma
2

1
cada
1
para
1
rosa
4
uma
2
para cada ,
uma
rosa
4
para cada ,
uma
rosa
rosa
4
para cada
,
1
uma
2

1
para cada ,
rosa
4
uma
2
para cada ,
a)
c)
0
0
0 0
1
1
1 1
e) f)
1 0
0
0
0 0
1
1
1 1
b)
0 1
0
0 0
1
1 1
d)
0 1 0 1
2
4
2 2
10
6
2
4
2
2 2
4
6
2 2
OBS: O algoritmo de Huffman uma abordagem gulosa.
Projeto de Algoritmos Cap.8 Processamento de Cadeias de Caracteres Seo 8.2.3 77
rvore de Huffman
O mtodo de Huffman produz a rvore de codicao que minimiza o
comprimento do arquivo comprimido.
Existem diversas rvores que produzem a mesma compresso.
Por exemplo, trocar o lho esquerda de um n por um lho direita
leva a uma rvore de codicao alternativa com a mesma razo de
compresso.
Entretanto, a escolha preferencial para a maioria das aplicaes a
rvore cannica.
Uma rvore de Huffman cannica quando a altura da subrvore
direita de qualquer n nunca menor que a altura da subrvore
esquerda.
Projeto de Algoritmos Cap.8 Processamento de Cadeias de Caracteres Seo 8.2.3 78
rvore de Huffman
A representao do cdigo na forma de rvore facilita a visualizao.
Sugere mtodos de codicao e decodicao triviais:
Codicao: a rvore percorrida emitindo bits ao longo de suas
arestas.
Decodicao: os bits de entrada so usados para selecionar as
arestas.
Essa abordagem ineciente tanto em termos de espao quanto em
termos de tempo.
Projeto de Algoritmos Cap.8 Processamento de Cadeias de Caracteres Seo 8.2.3 79
Algoritmo Baseado na Codicao Cannica com
Comportamento Linear em Tempo e Espao
O algoritmo atribudo a Moffat e Katajainen (1995).
Calcula os comprimentos dos cdigos em lugar dos cdigos
propriamente ditos.
A compresso atingida a mesma, independentemente dos cdigos
utilizados.
Aps o clculo dos comprimentos, h uma forma elegante e eciente
para a codicao e a decodicao.
Projeto de Algoritmos Cap.8 Processamento de Cadeias de Caracteres Seo 8.2.3 80
O Algoritmo
A entrada do algoritmo um vetor A contendo as frequncias das
palavras em ordem no-crescente.
Frequncias relativas frase exemplo: para cada rosa rosa,
uma rosa uma rosa
4 2 1 1 1 1
Durante execuo so utilizados vetores logicamente distintos, mas
capazes de coexistirem no mesmo vetor das frequncias.
O algoritmo divide-se em trs fases:
1. Combinao dos ns.
2. Converso do vetor no conjunto das profundidades dos ns
internos.
3. Calculo das profundidades dos ns folhas.
Projeto de Algoritmos Cap.8 Processamento de Cadeias de Caracteres Seo 8.2.3 81
Primeira Fase - Combinao dos ns
Peso da
rvore
disponveis
Posies
ns internos
Pesos dos
ns internos
ndices pais
ns internos
ndices pais
1 2 n
1 2 3 n
...
a)
c)
...
1
...
n
... ... ...
b)
Raiz Prox Folha
Frequncias
dos ns folhas
Frequncias
Projeto de Algoritmos Cap.8 Processamento de Cadeias de Caracteres Seo 8.2.3 82
Primeira Fase - Combinao dos ns
A primeira fase baseada em duas observaes:
1. A frequncia de um n s precisa ser mantida at que ele seja
processado.
2. No preciso manter apontadores para os pais dos ns folhas,
pois eles podem ser inferidos.
Exemplo: ns internos nas profundidades [0, 1, 2, 3, 3] teriam ns
folhas nas profundidades [1, 2, 4, 4, 4, 4].
Projeto de Algoritmos Cap.8 Processamento de Cadeias de Caracteres Seo 8.2.3 83
Pseudocdigo para a Primeira Fase
PrimeiraFase (A, n)
{ Raiz = n; Folha = n;
for ( Prox = n; n >= 2; Prox)
{ / Procura Posicao /
i f ( (nao existe Folha) | | ( ( Raiz > Prox) && (A[ Raiz] <= A[ Folha] ) ) )
{ A[ Prox] = A[ Raiz ] ; A[ Raiz] = Prox; Raiz = Raiz 1; / No interno / }
else { A[ Prox] = A[ Folha] ; Folha = Folha 1; / No folha / }
/ Atualiza Frequencias /
i f ( (nao existe Folha) | | ( ( Raiz > Prox) && (A[ Raiz] <= A[ Folha] ) ) )
{ / No interno /
A[ Prox] = A[ Prox] + A[ Raiz ] ; A[ Raiz] = Prox; Raiz = Raiz 1;
}
else { A[ Prox] = A[ Prox] + A[ Folha] ; Folha = Folha 1; / No folha / }
}
}
Projeto de Algoritmos Cap.8 Processamento de Cadeias de Caracteres Seo 8.2.3 84
Exemplo de Processamento da Primeira Fase
4 2 2 1 1 1
4 2 1 1 2 2
4 2 1 2 2 4
4 4 1 2 4 4
4 2 2 4 4 4
4 2 4 4 6 3
4 4 6 3 4 4
10 2 3 4 4
4 2 1 1 1 1
4 2 2 1 1 1
4 2 1 1 1 1 a)
b)
c)
d)
e)
f)
g)
h)
i)
j)
k)
1 2 3 4 5 6 Prox Raiz
6
6
5
5
4
4
3
3
2
2
1 2
5
4
6
6
6
6
6
4
3
3
Folha
0
1
6
5
4
3
2
2
2
1
0
Projeto de Algoritmos Cap.8 Processamento de Cadeias de Caracteres Seo 8.2.3 85
Segunda Fase - Converso do Vetor no Conjunto das
Profundidades dos ns internos
ns internos
ndices pais Peso da
rvore
Profundidade
dos ns internos ns internos
ndices pais
Prox
1 2 3
a)
...
n
1
c)
2
...
n
Profundidade dos ns internos
b)
2
... ...
n 1
Projeto de Algoritmos Cap.8 Processamento de Cadeias de Caracteres Seo 8.2.3 86
Pseudocdigo para a Segunda Fase
SegundaFase (A, n)
{ A[ 2] = 0;
for ( Prox = 3; Prox <= n; Prox++) A[ Prox] = A[A[ Prox] ] + 1;
}
Profundidades dos ns internos obtida com a segunda fase tendo como
entrada o vetor exibido na letra k do slide 84.
0 1 2 3 3
Projeto de Algoritmos Cap.8 Processamento de Cadeias de Caracteres Seo 8.2.3 87
Terceira Fase - Calculo das profundidades dos ns folhas
Profundidade
dos ns internos dos cdigos
Comprimento
disponveis
Posies
Prox Raiz
1
c)
n
...
Comprimento dos cdigos
1
... ... ...
b)
n
1
a)
2 n
Profundidade dos ns internos
...
Projeto de Algoritmos Cap.8 Processamento de Cadeias de Caracteres Seo 8.2.3 88
Pseudocdigo para a Terceira Fase
TerceiraFase (A, n)
{ Disp = 1; u = 0; h = 0; Raiz = 2; Prox = 1;
while ( Disp > 0)
{ while ( Raiz <= n && A[ Raiz] == h) { u = u + 1; Raiz = Raiz + 1; }
while ( Disp > u) { A[ Prox] = h; Prox = Prox + 1; Disp = Disp 1; }
Disp = 2 u; h = h + 1; u = 0;
}
}
Aplicando a Terceira Fase sobre:
0 1 2 3 3
Os comprimentos dos cdigos em nmero de bits so obtidos:
1 2 4 4 4 4
Projeto de Algoritmos Cap.8 Processamento de Cadeias de Caracteres Seo 8.2.3 89
Clculo do comprimento dos cdigos a partir de um
vertor de frequncias
CalculaCompCodigo (A, n)
{ A = PrimeiraFase (A, n) ;
A = SegundaFase (A, n) ;
A = TerceiraFase (A, n) ;
}
Projeto de Algoritmos Cap.8 Processamento de Cadeias de Caracteres Seo 8.2.3 90
Cdigo Cannico
Os comprimentos dos cdigos obedecem ao algoritmo de Huffman.
Cdigos de mesmo comprimento so inteiros consecutivos.
A partir dos comprimentos obtidos, o clculo dos cdigos trivial: o primeiro
cdigo composto apenas por zeros e, para os demais, adiciona-se 1 ao
cdigo anterior e faz-se um deslocamento esquerda para obter-se o
comprimento adequado quando necessrio.
Codicao Cannica Obtida:
i Smbolo Cdigo Cannico
1 rosa 0
2 uma 10
3 para 1100
4 cada 1101
5 , 1110
6 1111
Projeto de Algoritmos Cap.8 Processamento de Cadeias de Caracteres Seo 8.2.3 91
Elaborao de Algoritmos Ecientes para a Codicao e
para a Decodicao
Os algoritmos so baseados na seguinte observao:
Cdigos de mesmo comprimento so inteiros consecutivos.
Os algoritmos so baseados no uso de dois vetores com
MaxCompCod elementos,sendo MaxCompCod o comprimento do
maior cdigo.
Projeto de Algoritmos Cap.8 Processamento de Cadeias de Caracteres Seo 8.2.3 92
Vetores Base e Offset
Vetor Base: indica, para um dado comprimento c, o valor inteiro do primeiro
cdigo com esse comprimento.
O vetor Base calculado pela relao:
Base[c] =

0 se c = 1,
2 (Base[c 1] +w
c1
) caso contrrio,
sendo w
c
o nmero de cdigos com comprimento c.
Offset: indica o ndice no vocabulrio da primeira palavra de cada
comprimento de cdigo c.
Vetores Base e Offset para a
tabela do slide 90:
c Base[c] Offset[c]
1 0 1
2 2 2
3 6 2
4 12 3
Projeto de Algoritmos Cap.8 Processamento de Cadeias de Caracteres Seo 8.2.3 93
Pseudocdigo para codicao
Codifica (Base, Offset , i , MaxCompCod)
{ c = 1;
while ( i >= Offset [ c + 1] ) && (c + 1 <= MaxCompCod )
c = c + 1;
Codigo = i Offset [ c] + Base[ c] ;
}
Obteno do cdigo:
Parmetros: vetores Base e Offset, ndice i do smbolo (Tabela da
transparncia 71) a ser codicado e o comprimento MaxCompCod dos
vetores Base e Offset.
No anel while feito o clculo do comprimento c de cdigo a ser
utilizado.
A seguir, basta saber qual a ordem do cdigo para o comprimento c
(i Offset[c]) e somar esse valor Base[c].
Projeto de Algoritmos Cap.8 Processamento de Cadeias de Caracteres Seo 8.2.3 94
Exemplo de Codicao
Para a palavra i = 4 (cada):
1. Verica-se que um cdigo de comprimento 4.
2. Verica-se tambm que o segundo cdigo com esse
comprimento.
3. Assim, seu cdigo 13 (4 Offset[4] +Base[4]), o que corresponde
a 1101 em binrio.
Projeto de Algoritmos Cap.8 Processamento de Cadeias de Caracteres Seo 8.2.3 95
Pseudocdigo para decodicao
Decodifica (Base, Offset , ArqComprimido, MaxCompCod)
{ c = 1;
Codigo = LeBit (ArqComprimido) ;
while ( ( ( Codigo << 1 ) >= Base[ c + 1]) && ( c + 1 <= MaxCompCod ) )
{ Codigo = (Codigo < < 1) | | LeBit (ArqComprimido) ;
c = c + 1;
}
i = Codigo Base[ c] + Offset [ c] ;
}
Parmetros: vetores Base e Offset, o arquivo comprimido e o
comprimento MaxCompCod dos vetores Base e Offset.
Na decodicao, o arquivo de entrada lido bit-a-bit, adicionando-se
os bits lidos ao cdigo e comparando-o com o vetor Base.
O anel while mostra como identicar o cdigo a partir de uma posio
do arquivo comprimido.
Projeto de Algoritmos Cap.8 Processamento de Cadeias de Caracteres Seo 8.2.3 96
Exemplo de Decodicao
Decodicao da sequncia de bits 1101:
c LeBit Codigo Codigo << 1 Base[c + 1]
1 1 1 - -
2 1 10 or 1 = 11 10 10
3 0 110 or 0 = 110 110 110
4 1 1100 or 1 = 1101 1100 1100
A primeira linha da tabela
o estado inicial do while
quando j foi lido o primeiro
bit da sequncia, atribudo
varivel Codigo.
A linha dois e seguintes representam a situao do anel while aps cada
respectiva iterao.
Na linha dois, o segundo bit foi lido (bit 1) e a varivel Codigo recebe o
cdigo anterior deslocado esquerda de um bit seguido da operao or com
o bit lido.
De posse do cdigo, Base e Offset so usados para identicar qual o ndice i
da palavra no vocabulrio, sendo i = Codigo Base[c] + Oset[c].
Projeto de Algoritmos Cap.8 Processamento de Cadeias de Caracteres Seo 8.2.3 97
Pseudocdigo para Realizar a Compresso
Compressao ( ArqTexto, ArqComprimido)
{ / Primeira etapa /
while ( ! feof ( ArqTexto) )
{ Palavra = ExtraiProximaPalavra ( ArqTexto) ;
Pos = Pesquisa ( Palavra, Vocabulario) ;
i f Pos uma posicao valida
Vocabulario[Pos] . Freq = Vocabulario[Pos] . Freq + 1
else Insere ( Palavra, Vocabulario) ;
}
/ Segunda etapa /
Vocabulario = OrdenaPorFrequencia ( Vocabulario) ;
Vocabulario = CalculaCompCodigo ( Vocabulario, n) ;
ConstroiVetores (Base, Offset , ArqComprimido) ;
Grava ( Vocabulario, ArqComprimido) ;
LeVocabulario ( Vocabulario, ArqComprimido) ;
Projeto de Algoritmos Cap.8 Processamento de Cadeias de Caracteres Seo 8.2.3 98
Pseudocdigo para Realizar a Compresso
/ Terceira etapa /
PosicionaPrimeiraPosicao ( ArqTexto) ;
while ( ! feof (ArqTexto) )
{ Palavra = ExtraiProximaPalavra ( ArqTexto) ;
Pos = Pesquisa ( Palavra, Vocabulario) ;
Codigo = Codifica (Base, Offset ,
Vocabulario[Pos] .Ordem, MaxCompCod) ;
Escreve (ArqComprimido, Codigo) ;
}
}
Projeto de Algoritmos Cap.8 Processamento de Cadeias de Caracteres Seo 8.2.3 99
Pseudocdigo para Realizar a Descompresso
Descompressao ( ArqTexto, ArqComprimido)
{ LerVetores (Base, Offset , ArqComprimido) ;
LeVocabulario ( Vocabulario, ArqComprimido) ;
while ( ! feof (ArqComprimido) )
{ i = Decodifica (Base, Offset , ArqComprimido, MaxCompCod) ;
Grava ( Vocabulario[ i ] , ArqTexto) ;
}
}
Projeto de Algoritmos Cap.8 Processamento de Cadeias de Caracteres Seo 8.2.4 100
Codicao de Huffman Usando Bytes
O mtodo original proposto por Huffman (1952) tem sido usado como
um cdigo binrio.
Moura, Navarro, Ziviani e Baeza-Yates (2000) modicaram a atribuio
de cdigos de tal forma que uma sequncia de bytes associada a
cada palavra do texto.
Consequentemente, o grau de cada n passa de 2 para 256. Essa
verso chamada de cdigo de Huffman pleno.
Outra possibilidade utilizar apenas 7 dos 8 bits de cada byte para a
codicao, e a rvore passa ento a ter grau 128.
Nesse caso, o oitavo bit usado para marcar o primeiro byte do cdigo
da palavra, sendo chamado de cdigo de Huffman com marcao.
Projeto de Algoritmos Cap.8 Processamento de Cadeias de Caracteres Seo 8.2.4 101
Exemplo de Cdigos Plenos e com Marcao
O cdigo de Huffman com marcao ajuda na pesquisa sobre o texto
comprimido.
Exemplo:
Cdigo pleno para uma com 3 bytes: 47 81 8.
Cdigo com marcao para uma com 3 bytes: 175 81 8
Note que o primeiro byte 175 = 47 + 128.
Assim, no cdigo com marcao o oitavo bit 1 quando o byte o
primeiro do cdigo, seno ele 0.
Projeto de Algoritmos Cap.8 Processamento de Cadeias de Caracteres Seo 8.2.4 102
rvore de Huffman Orientada a Bytes
A construo da rvore de Huffman orientada a bytes pode ocasionar o
aparecimento de ns internos no totalmente preenchidos:
...
...
...
256 elementos 256 elementos
254 ns vazios
...
...
...
256 elementos 2 elementos 254 ns vazios
254 elementos
a) rvore ineficiente
rvore tima b)
Na Figura, o alfabeto possui 512 smbolos (ns folhas), todos com a mesma
frequncia de ocorrncia.
O segundo nvel tem 254 espaos vazios que poderiam ser ocupados com
smbolos, mudando o comprimento de seus cdigos de 2 para 1 byte.
Projeto de Algoritmos Cap.8 Processamento de Cadeias de Caracteres Seo 8.2.4 103
Movendo Ns Vazios para Nveis mais Profundos
Um meio de assegurar que ns vazios sempre ocupem o nvel mais
baixo da rvore combin-los com os ns de menores frequncias.
O objetivo mov-los para o nvel mais profundo da rvore.
Para isso, devemos selecionar o nmero de smbolos que sero
combinados com os ns vazios, dada pela equao:
1 + ((n BaseNum) mod (BaseNum1))
No caso da Figura da transparncia anterior igual a 1 + ((512 256)
mod 255) = 2.
Projeto de Algoritmos Cap.8 Processamento de Cadeias de Caracteres Seo 8.2.4 104
Clculo dos Comprimentos dos Cdigos
void CalculaCompCodigo( TipoDicionario A, int n)
{ int u = 0; / Nodos internos usados /
int h = 0; / Altura da arvore /
int NoInt ; / Numero de nodos internos /
int Prox, Raiz, Folha;
int Disp = 1; int x, Resto;
i f (n > BASENUM 1)
{ Resto = 1 + ((n BASENUM) % (BASENUM 1));
i f (Resto < 2) Resto = BASENUM;
}
else Resto = n 1;
NoInt = 1 + ((n Resto) / ( BASENUM 1));
for ( x = n 1; x >= (n Resto) + 1; x) A[n] . Freq += A[ x] . Freq;
/ Primeira Fase /
Raiz = n; Folha = n Resto;
Projeto de Algoritmos Cap.8 Processamento de Cadeias de Caracteres Seo 8.2.4 105
Clculo dos Comprimentos dos Cdigos
for ( Prox = n 1; Prox >= (n NoInt ) + 1; Prox)
{ / Procura Posicao /
i f ( ( Folha<1) | | ( ( Raiz > Prox) && (A[ Raiz] . Freq<=A[ Folha] . Freq) ) )
{ / No interno /
A[ Prox] . Freq = A[ Raiz] . Freq; A[ Raiz] . Freq = Prox;
Raiz;
}
else { / Nofolha /
A[ Prox] . Freq = A[ Folha] . Freq; Folha;
}
/ Atualiza Frequencias /
for ( x = 1; x <= BASENUM 1; x++)
{ i f ( ( Folha<1) | | ( ( Raiz>Prox) && (A[ Raiz] . Freq<=A[ Folha] . Freq) ) )
{ / No interno /
A[ Prox] . Freq += A[ Raiz] . Freq; A[ Raiz] . Freq = Prox;
Raiz;
}
Projeto de Algoritmos Cap.8 Processamento de Cadeias de Caracteres Seo 8.2.4 106
Clculo dos Comprimentos dos Cdigos
else { / Nofolha /
A[ Prox] . Freq += A[ Folha] . Freq; Folha;
}
}
}
/ Segunda Fase /
A[ Raiz] . Freq = 0;
for ( Prox = Raiz + 1; Prox <= n; Prox++) A[ Prox] . Freq = A[A[ Prox] . Freq] . Freq + 1;
/ Terceira Fase /
Prox = 1;
while ( Disp > 0)
{ while ( Raiz <= n && A[ Raiz] . Freq == h) { u++; Raiz++; }
while ( Disp > u)
{ A[ Prox] . Freq = h; Prox++; Disp;
i f ( Prox > n) { u = 0; break; }
}
Disp = BASENUM u; h++; u = 0;
}
}
Projeto de Algoritmos Cap.8 Processamento de Cadeias de Caracteres Seo 8.2.4 107
Clculo dos Comprimentos dos Cdigos: Generalizao
OBS: A constante BaseNum pode ser usada para trabalharmos com
quaisquer bases numricas menores ou iguais a um byte. Por exemplo,
para a codicao plena o valor 256 e para a codicao com marcao
o valor 128.
Projeto de Algoritmos Cap.8 Processamento de Cadeias de Caracteres Seo 8.2.4 108
Mudanas em Relao ao Pseudocdigo Apresentado
A mais sensvel est no cdigo inserido antes da primeira fase, o qual
tem como funo eliminar o problema causado por ns internos da
rvore no totalmente preenchidos.
Na primeira fase, as BaseNum rvores de menor custo so
combinadas a cada passo, em vez de duas como no caso da
codicao binria:
Isso feito pelo anel for introduzido na parte que atualiza
frequncias na primeira fase.
A segunda fase no sofre alteraes.
A terceira fase alterada para indicar quantos ns esto disponveis
em cada nvel, o que representado pela varivel Disp.
Projeto de Algoritmos Cap.8 Processamento de Cadeias de Caracteres Seo 8.2.4 109
Codicao Orientada a Bytes
int Codifica(TipoVetoresBO VetoresBaseOffset ,
int Ordem, int c,
int MaxCompCod)
{ c = 1;
while (Ordem >= VetoresBaseOffset[c + 1] . Offset &&
c + 1 <= MaxCompCod) ( c)++;
return (Ordem VetoresBaseOffset[c] . Offset +
VetoresBaseOffset[c] .Base) ;
}
OBS: a codicao orientada a bytes no requer nenhuma alterao em
relao codicao usando bits
Projeto de Algoritmos Cap.8 Processamento de Cadeias de Caracteres Seo 8.2.4 110
Decodicao Orientada a Bytes
int Decodifica(TipoVetoresBO VetoresBaseOffset , FILE ArqComprimido, int MaxCompCod)
{ int c = 1;
int Codigo = 0 , CodigoTmp = 0;
int LogBase2 = ( int )round( log(BASENUM) / log(2. 0));
fread(&Codigo, sizeof(unsigned char) , 1 , ArqComprimido) ;
i f (LogBase2 == 7) Codigo = 128; / remove o bi t de marcacao /
while ( ( c + 1 <= MaxCompCod) && ((Codigo << LogBase2) >= VetoresBaseOffset [ c+1].Base) )
{ fread(&CodigoTmp, sizeof(unsigned char) , 1 , ArqComprimido) ;
Codigo = (Codigo << LogBase2) | CodigoTmp;
c++;
}
return (Codigo VetoresBaseOffset [ c] .Base + VetoresBaseOffset [ c] . Offset ) ;
}
Projeto de Algoritmos Cap.8 Processamento de Cadeias de Caracteres Seo 8.2.4 111
Decodicao Orientada a Bytes
Alteraes:
1. Permitir leitura byte a byte do arquivo comprimido, em vez de bit a bit.
2. O nmero de bits deslocados esquerda para encontrar o
comprimento c do cdigo (o qual indexa Base e Offset) dado por:
log
2
BaseNum
Projeto de Algoritmos Cap.8 Processamento de Cadeias de Caracteres Seo 8.2.4 112
Clculo dos Vetores Base e Offset
O clculo do vetor Offset no requer alterao alguma.
Para generalizar o clculo do vetor Base, basta substituir o fator 2 por
BaseNum, como na relao abaixo:
Base[c] =

0 se c = 1,
BaseNum(Base[c 1] + w
c1
) caso contrrio.
Projeto de Algoritmos Cap.8 Processamento de Cadeias de Caracteres Seo 8.2.4 113
Construo dos Vetores Base e Offset (1)
int ConstroiVetores(TipoVetoresBO VetoresBaseOffset ,
TipoDicionario Vocabulario,
int n, FILE ArqComprimido)
{ int Wcs[ MAXTAMVETORESDO + 1] ;
int i , MaxCompCod;
MaxCompCod = Vocabulario[n] . Freq;
for ( i = 1; i <= MaxCompCod; i ++)
{ Wcs[ i ] = 0; VetoresBaseOffset [ i ] . Offset = 0; }
for ( i = 1; i <= n; i ++)
{ Wcs[ Vocabulario[ i ] . Freq]++;
VetoresBaseOffset [ Vocabulario[ i ] . Freq] . Offset =
i Wcs[ Vocabulario[ i ] . Freq] + 1;
}
Projeto de Algoritmos Cap.8 Processamento de Cadeias de Caracteres Seo 8.2.4 114
Construo dos Vetores Base e Offset (2)
VetoresBaseOffset [ 1] .Base = 0;
for ( i = 2; i <= MaxCompCod; i ++)
{ VetoresBaseOffset [ i ] .Base =
BASENUM ( VetoresBaseOffset [ i 1].Base + Wcs[ i 1]);
i f ( VetoresBaseOffset [ i ] . Offset == 0)
VetoresBaseOffset [ i ] . Offset = VetoresBaseOffset [ i 1].Offset ;
}
/ Salvando as tabelas em disco /
GravaNumInt(ArqComprimido, MaxCompCod) ;
for ( i = 1; i <= MaxCompCod; i ++)
{ GravaNumInt(ArqComprimido, VetoresBaseOffset [ i ] .Base) ;
GravaNumInt(ArqComprimido, VetoresBaseOffset [ i ] . Offset ) ;
}
return MaxCompCod;
}
Projeto de Algoritmos Cap.8 Processamento de Cadeias de Caracteres Seo 8.2.4 115
Procedimentos para Ler e Escrever Nmeros Inteiros em
um Arquivo de Bytes
int LeNumInt(FILE ArqComprimido)
{ int Num;
fread(&Num, sizeof( int ) , 1 , ArqComprimido) ;
return Num;
}
O procedimento LeNumInt l do disco cada byte de um nmero inteiro
e o recompe.
Projeto de Algoritmos Cap.8 Processamento de Cadeias de Caracteres Seo 8.2.4 116
Procedimentos para Ler e Escrever Nmeros Inteiros em
um Arquivo de Bytes
void GravaNumInt(FILE ArqComprimido, int Num)
{ fwri te(&Num, sizeof( int ) , 1 , ArqComprimido) ; }
O procedimento GravaNumInt grava no disco cada byte (da esquerda
para a direita) do nmero inteiro passado como parmetro.
Projeto de Algoritmos Cap.8 Processamento de Cadeias de Caracteres Seo 8.2.4 117
O Por Qu da Existncia de LeNumInt e GravaNumInt
So necessrios em razo de a varivel ArqComprimido, passada
como parmetro, ter sido declarada no programa principal como um
arquivo de bytes.
Isso faz com que o procedimento write (read) do Pascal escreva (leia)
do disco o byte mais direita do nmero.
Por exemplo, considere o nmero 300 representado em 4 bytes, como
mostrado na Figura abaixo.
Caso fosse utilizado o procedimento write, seria gravado o nmero 44
em disco, que o nmero representado no byte mais direita.
Um problema anlogo ocorre ao se utlizar o procedimento read para
ler do disco um nmero inteiro representado em mais de um byte.
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 1 0 0
Byte 3 Byte 2 Byte 1 Byte 0
Projeto de Algoritmos Cap.8 Processamento de Cadeias de Caracteres Seo 8.2.4 118
Dene Alfabeto Utilizado na Composio de Palavras
void DefineAlfabeto(TipoAlfabeto Alfabeto , FILE ArqAlf )
{ / Os Simbolos devem estar juntos em uma linha no arquivo /
char Simbolos[ MAXALFABETO + 1] ;
int i ;
char Temp;
for ( i = 0; i <= MAXALFABETO; i ++) Alfabeto[ i ] = FALSE;
fgets(Simbolos, MAXALFABETO + 1 , ArqAlf ) ;
Temp = strchr (Simbolos, \n ) ;
i f (Temp ! = NULL) Temp = 0;
for ( i = 0; i <= strl en(Simbolos) 1; i ++)
Alfabeto[ Simbolos[ i ] + 127] = TRUE;
Alfabeto[ 0] = FALSE; / caractere de codigo zero: separador /
OBS: O procedimento DeneAlfabeto l de um arquivo alfabeto.txt todos o
caracteres que sero utilizados para compor palavras.
Projeto de Algoritmos Cap.8 Processamento de Cadeias de Caracteres Seo 8.2.4 119
Extrao do Prximo Smbolo a ser Codicado (1)
void ExtraiProximaPalavra ( TipoPalavra Result , int TipoIndice,
char Linha, FILE ArqTxt , TipoAlfabeto Alfabeto)
{ short FimPalavra = FALSE , Aux = FALSE;
Result [ 0] = \0 ;
i f (TipoIndice > strl en(Linha) )
{ i f ( fgets(Linha, MAXALFABETO + 1,ArqTxt ) )
{ / Coloca um delimitador em Linha /
spri nt f (Linha + strl en(Linha) , "%c" , (char) 0) ; TipoIndice = 1;
}
else { spri nt f (Linha, "%c" , (char) 0) ; FimPalavra = TRUE; }
}
Projeto de Algoritmos Cap.8 Processamento de Cadeias de Caracteres Seo 8.2.4 120
Extrao do Prximo Smbolo a ser Codicado (2)
while (TipoIndice <= strl en(Linha) && !FimPalavra)
{ i f ( Alfabeto[ Linha[TipoIndice 1] + 127])
{ spri nt f (Result + strl en(Result ) , "%c" , Linha[TipoIndice 1]);
Aux = TRUE;
}
else { i f (Aux)
{ i f ( Linha[TipoIndice 1] != (char)0) (TipoIndice); }
else { spri nt f (Result + strl en(Result ) , "%c" ,
Linha[TipoIndice 1]);
}
FimPalavra = TRUE;
}
(TipoIndice)++;
}
}
Projeto de Algoritmos Cap.8 Processamento de Cadeias de Caracteres Seo 8.2.4 121
Cdigo para Fazer a Compresso
O Cdigo para fazer a compresso dividido em trs etapas:
1. Na primeira, as palavras so extradas do texto a ser comprimido e
suas respectivas frequncias so contabilizadas.
2. Na segunda, so gerados os vetores Base e Offset, os quais so
gravados no arquivo comprimido seguidamente do vocabulrio.
Para delimitar os smbolos do vocabulrio no disco, cada um deles
separado pelo caractere zero.
3. Na terceira, o arquivo texto percorrido pela segunda vez, sendo
seus smbolos novamente extrados, codicados e gravados no
arquivo comprimido.
Projeto de Algoritmos Cap.8 Processamento de Cadeias de Caracteres Seo 8.2.4 122
Cdigo para Fazer a Compresso
void Compressao(FILE ArqTxt , FILE ArqAlf , FILE ArqComprimido)
{ TipoAlfabeto Alfabeto;
TipoPalavra Palavra, Linha; int Ind = 1 , MaxCompCod; TipoPesos p;
TipoDicionario Vocabulario = ( TipoDicionario)
calloc(M+1, sizeof(TipoItem) ) ;
TipoVetoresBO VetoresBaseOffset = (TipoVetoresBO)
calloc(MAXTAMVETORESDO+1, sizeof(TipoBaseOffset ) ) ;
f pr i nt f ( stderr , "Definindo alfabeto\n" ) ;
DefineAlfabeto( Alfabeto , ArqAlf ) ; /Le alfabeto def . em arquivo/
Linha = \0 ;
f pr i nt f ( stderr , " Incializando Voc. \ n" ) ; I ni ci al i za (Vocabulario) ;
f pr i nt f ( stderr , "Gerando Pesos\n" ) ; GeraPesos(p) ;
f pr i nt f ( stderr , "Primeira etapa\n" ) ;
Projeto de Algoritmos Cap.8 Processamento de Cadeias de Caracteres Seo 8.2.4 123
Cdigo para Fazer a Compresso
PrimeiraEtapa(ArqTxt , Alfabeto, &Ind,
Palavra, Linha, Vocabulario, p) ;
f pr i nt f ( stderr , "Segunda etapa\n" ) ;
MaxCompCod = SegundaEtapa(Vocabulario, VetoresBaseOffset , p,
ArqComprimido) ;
fseek(ArqTxt , 0 , SEEK_SET) ; / Move cursor para i ni ci o do arquivo/
Ind = 1; Linha = \0 ;
f pr i nt f ( stderr , "Terceira etapa\n" ) ;
TerceiraEtapa(ArqTxt , Alfabeto, &Ind , Palavra, Linha, Vocabulario, p,
VetoresBaseOffset , ArqComprimido, MaxCompCod) ;
free ( Vocabulario) ; free ( VetoresBaseOffset ) ;
}
Projeto de Algoritmos Cap.8 Processamento de Cadeias de Caracteres Seo 8.2.4 124
Primeira Etapa da Compresso (1)
void PrimeiraEtapa(FILE ArqTxt , TipoAlfabeto Alfabeto , int TipoIndice,
TipoPalavra Palavra, char Linha,
TipoDicionario Vocabulario, TipoPesos p)
{ TipoItem Elemento; int i ; char PalavraTrim = NULL;
do
{ ExtraiProximaPalavra(Palavra, TipoIndice , Linha, ArqTxt , Alfabeto) ;
memcpy(Elemento.Chave, Palavra, sizeof(TipoChave) ) ;
Elemento. Freq = 1;
i f (Palavra ! = \0 )
{ i = Pesquisa(Elemento.Chave, p, Vocabulario) ;
i f ( i < M)
Vocabulario[ i ] . Freq++;
else Insere(&Elemento, p, Vocabulario) ;
Projeto de Algoritmos Cap.8 Processamento de Cadeias de Caracteres Seo 8.2.4 125
Primeira Etapa da Compresso (2)
do
{ ExtraiProximaPalavra(Palavra, TipoIndice , Linha,
ArqTxt , Alfabeto) ;
memcpy(Elemento.Chave, Palavra, sizeof(TipoChave) ) ;
/ O primeiro espaco depois da palavra nao e codificado /
i f ( PalavraTrim ! = NULL) free(PalavraTrim) ;
PalavraTrim = Trim(Palavra) ;
i f ( strcmp(PalavraTrim, " " ) && (PalavraTrim) ! = (char)0)
{ i = Pesquisa(Elemento.Chave, p, Vocabulario) ;
i f ( i < M) Vocabulario[ i ] . Freq++;
else Insere(&Elemento, p, Vocabulario) ;
}
} while ( strcmp(Palavra, " " ) ) ;
i f ( PalavraTrim ! = NULL) free(PalavraTrim) ;
}
} while ( Palavra[ 0] ! = \0 ) ;
}
Projeto de Algoritmos Cap.8 Processamento de Cadeias de Caracteres Seo 8.2.4 126
Segunda Etapa da Compresso (1)
int SegundaEtapa( TipoDicionario Vocabulario, TipoVetoresBO VetoresBaseOffset ,
TipoPesos p, FILE ArqComprimido)
{
int Result , i , j , NumNodosFolhas, PosArq;
TipoItem Elemento;
char Ch;
TipoPalavra Palavra;
NumNodosFolhas = OrdenaPorFrequencia(Vocabulario) ;
CalculaCompCodigo(Vocabulario, NumNodosFolhas) ;
Result = ConstroiVetores(VetoresBaseOffset , Vocabulario,
NumNodosFolhas, ArqComprimido) ;
/ Grava Vocabulario /
GravaNumInt(ArqComprimido, NumNodosFolhas) ;
PosArq = f t el l (ArqComprimido) ;
for ( i = 1; i <= NumNodosFolhas; i ++)
{
j = strl en(Vocabulario[ i ] .Chave) ;
fwri te(Vocabulario[ i ] .Chave, sizeof(char) , j + 1 , ArqComprimido) ;
}
Projeto de Algoritmos Cap.8 Processamento de Cadeias de Caracteres Seo 8.2.4 127
Segunda Etapa da Compresso (2)
/ Le e reconstroi a condicao de hash no vetor que contem o vocabulario /
fseek(ArqComprimido, PosArq, SEEK_SET) ;
I ni ci al i za (Vocabulario) ;
for ( i = 1; i <= NumNodosFolhas; i ++)
{
Palavra = \0 ;
do
{ fread(&Ch, sizeof(char) , 1 , ArqComprimido) ;
i f (Ch ! = (char)0)
spri nt f (Palavra + strl en(Palavra) , "%c" , Ch) ;
} while (Ch ! = (char)0);
memcpy(Elemento.Chave, Palavra, sizeof(TipoChave) ) ;
Elemento.Ordem = i ;
j = Pesquisa(Elemento.Chave, p, Vocabulario) ;
i f ( j >= M)
Insere(&Elemento, p, Vocabulario) ;
}
return Result ;
}
Projeto de Algoritmos Cap.8 Processamento de Cadeias de Caracteres Seo 8.2.4 128
Funo para Ordenar o Vocabulrio por Frequncia
O objetivo dessa funo ordenar in situ o vetor Vocabulario,
utilizando a prpria tabela hash.
Para isso, os smbolos do vetor Vocabulario so copiados para as
posies de 1 a n no prprio vetor e ordenados de forma no
crescente por suas respectivas frequncias de ocorrncia.
O algoritmo de ordenao usado foi o Quicksort alterado para:
1. Receber como parmetro uma varivel denida como
TipoDicionario.
2. Mudar a condio de ordenao para no crescente.
3. Fazer com que a chave de ordenao seja o campo que representa
as frequncias dos smbolos no arquivo texto.
A funo OrdenaPorFrequencia retorna o nmero de smbolos
presentes no vocabulrio.
Projeto de Algoritmos Cap.8 Processamento de Cadeias de Caracteres Seo 8.2.4 129
Funo para Ordenar o Vocabulrio por Frequncia
TipoIndice OrdenaPorFrequencia( TipoDicionario Vocabulario)
{ TipoIndice i ; TipoIndice n = 1;
TipoItem Item;
Item = Vocabulario[ 1] ;
for ( i = 0; i <= M 1; i ++)
{ i f ( strcmp(Vocabulario[ i ] .Chave, VAZIO) )
{ i f ( i ! = 1) { Vocabulario[n] = Vocabulario[ i ] ; n++; } }
}
i f ( strcmp(Item.Chave, VAZIO) ) Vocabulario[n] = Item; else n;
QuickSort(Vocabulario, &n) ;
return n;
}
Projeto de Algoritmos Cap.8 Processamento de Cadeias de Caracteres Seo 8.2.4 130
Terceira Etapa da Compresso (1)
void TerceiraEtapa(FILE ArqTxt , TipoAlfabeto Alfabeto , int TipoIndice,
TipoPalavra Palavra, char Linha,
TipoDicionario Vocabulario, TipoPesos p,
TipoVetoresBO VetoresBaseOffset ,
FILE ArqComprimido, int MaxCompCod)
{ TipoApontador Pos; TipoChave Chave;
char PalavraTrim = NULL;
int Codigo, c;
do
{ ExtraiProximaPalavra(Palavra, TipoIndice , Linha, ArqTxt , Alfabeto) ;
memcpy(Chave, Palavra, sizeof(TipoChave) ) ;
i f (Palavra ! = \0 )
{ Pos = Pesquisa(Chave, p, Vocabulario) ;
Codigo = Codifica(VetoresBaseOffset , Vocabulario[Pos] .Ordem, &c,
MaxCompCod) ;
Escreve(ArqComprimido, &Codigo, &c) ;
Projeto de Algoritmos Cap.8 Processamento de Cadeias de Caracteres Seo 8.2.4 131
Terceira Etapa da Compresso (2)
do
{ ExtraiProximaPalavra(Palavra, TipoIndice, Linha, ArqTxt , Alfabeto) ;
/ O primeiro espaco depois da palavra nao e codificado /
PalavraTrim = Trim(Palavra) ;
i f ( strcmp(PalavraTrim, " " ) && (PalavraTrim) ! = (char)0)
{ memcpy(Chave, Palavra, sizeof(TipoChave) ) ;
Pos = Pesquisa(Chave, p, Vocabulario) ;
Codigo = Codifica(VetoresBaseOffset ,
Vocabulario[Pos] .Ordem, &c, MaxCompCod) ;
Escreve(ArqComprimido, &Codigo, &c) ;
}
i f ( strcmp(PalavraTrim, " " ) ) free(PalavraTrim) ;
} while ( strcmp(Palavra, " " ) ) ;
}
} while (Palavra ! = \0 ) ;
}
Projeto de Algoritmos Cap.8 Processamento de Cadeias de Caracteres Seo 8.2.4 132
Procedimento Escreve
O procedimento Escreve recebe o cdigo e seu comprimento c.
O cdigo representado por um inteiro, o que limita seu comprimento
a, no mximo, 4 bytes em um compilador que usa 4 bytes para
representar inteiros.
Primeiramente, o procedimento Escreve extrai o primeiro byte e coloca
a marcao no oitavo bit fazendo uma operao or do byte com a
constante 128 (que em hexadecimal 80.)
Esse byte ento colocado na primeira posio do vetor Saida.
No anel while, caso o comprimento c do cdigo seja maior do que um,
os demais bytes so extrados e armazenados em Saida[i], em que
2 i c.
Por m, o vetor de bytes Saida gravado em disco no anel for.
Projeto de Algoritmos Cap.8 Processamento de Cadeias de Caracteres Seo 8.2.4 133
Implementao do Procedimento Escreve
void Escreve(FILE ArqComprimido, int Codigo, int c)
{ unsigned char Saida[ MAXTAMVETORESDO + 1] ; int i = 1 , cTmp;
int LogBase2 = ( int )round( log(BASENUM) / log(2. 0));
int Mask = ( int ) pow(2 , LogBase2) 1; cTmp = c;
Saida[ i ] = ( (unsigned)(Codigo)) >> ((c 1) LogBase2) ;
i f (LogBase2 == 7) Saida[ i ] = Saida[ i ] | 0x80;
i ++; (c);
while (c > 0)
{ Saida[ i ] = ( ( (unsigned)(Codigo))>>((c1)LogBase2)) & Mask;
i ++; (c); }
for ( i = 1; i <= cTmp; i ++)
fwri te(&Saida[ i ] , sizeof(unsigned char) , 1 , ArqComprimido) ;
}
Projeto de Algoritmos Cap.8 Processamento de Cadeias de Caracteres Seo 8.2.4 134
Descrio do Cdigo para Fazer a Descompresso
O primeiro passo recuperar o modelo usado na compresso. Para
isso, l o alfabeto, o vetor Base, o vetor Offset e o vetor Vocabulario.
Em seguida, inicia a decodicao, tomando o cuidado de adicionar
um espao em branco entre dois smbolos que sejam palavras.
O processo de decodicao termina quando o arquivo comprimido
totalmente percorrido.
Projeto de Algoritmos Cap.8 Processamento de Cadeias de Caracteres Seo 8.2.4 135
Cdigo para Fazer a Descompresso
void Descompressao(FILE ArqComprimido, FILE ArqTxt , FILE ArqAlf )
{ TipoAlfabeto Alfabeto ; int Ind , MaxCompCod;
TipoVetorPalavra Vocabulario; TipoVetoresBO VetoresBaseOffset ;
TipoPalavra PalavraAnt ;
DefineAlfabeto( Alfabeto , ArqAlf ) ; / Le alfabeto definido em arq. /
MaxCompCod = LeVetores(ArqComprimido, VetoresBaseOffset ) ;
LeVocabulario(ArqComprimido, Vocabulario) ;
Ind = Decodifica(VetoresBaseOffset , ArqComprimido, MaxCompCod) ;
fputs(Vocabulario[ Ind] , ArqTxt ) ;
Projeto de Algoritmos Cap.8 Processamento de Cadeias de Caracteres Seo 8.2.4 136
Cdigo para Fazer a Descompresso
while ( ! feof (ArqComprimido) )
{Ind = Decodifica(VetoresBaseOffset , ArqComprimido, MaxCompCod) ;
i f ( Ind > 0)
{ i f ( Alfabeto[ Vocabulario[ Ind][0]+127] && PalavraAnt [ 0] ! = \n )
putc( , ArqTxt ) ;
strcpy(PalavraAnt , Vocabulario[ Ind] ) ;
fputs(Vocabulario[ Ind] , ArqTxt ) ;
}
}
}
Obs: Na descompresso, o vocaburio representado por um vetor de
smbolos do tipo TipoVetorPalavra.
Projeto de Algoritmos Cap.8 Processamento de Cadeias de Caracteres Seo 8.2.4 137
Procedimentos Auxiliares da Descompresso
int LeVetores(FILE ArqComprimido, TipoBaseOffset VetoresBaseOffset)
{ int MaxCompCod, i ;
MaxCompCod = LeNumInt(ArqComprimido) ;
for ( i = 1; i <= MaxCompCod; i ++)
{ VetoresBaseOffset [ i ] .Base = LeNumInt(ArqComprimido) ;
VetoresBaseOffset [ i ] . Offset = LeNumInt(ArqComprimido) ;
}
return MaxCompCod;
}
Projeto de Algoritmos Cap.8 Processamento de Cadeias de Caracteres Seo 8.2.4 138
Procedimentos Auxiliares da Descompresso
int LeVocabulario(FILE ArqComprimido, TipoVetorPalavra Vocabulario)
{ int NumNodosFolhas, i ; TipoPalavra Palavra;
char Ch;
NumNodosFolhas = LeNumInt(ArqComprimido) ;
for ( i = 1; i <= NumNodosFolhas; i ++)
{ Palavra = \0 ;
do
{ fread(&Ch, sizeof(unsigned char) , 1 , ArqComprimido) ;
i f (Ch ! = (char)0) /Palavras estao separadas pelo caratere 0/
spri nt f (Palavra + strl en(Palavra) , "%c" , Ch) ;
} while (Ch ! = (char)0);
strcpy(Vocabulario[ i ] , Palavra) ;
}
return NumNodosFolhas;
}
Projeto de Algoritmos Cap.8 Processamento de Cadeias de Caracteres Seo 8.2.4 139
Resultados Experimentais
Mostram que no existe grande degradao na razo de compresso
na utilizao de bytes em vez de bits na codicao das palavras de
um vocabulrio.
Por outro lado, tanto a descompresso quanto a pesquisa so muito
mais rpidas com uma codicao de Huffman usando bytes do que
uma codicao de Huffman usando bits, isso porque deslocamentos
de bits e operaes usando mscaras no so necessrias.
Os experimentos foram realizados em uma mquina PC Pentium de
200 MHz com 128 megabytes de RAM.
Projeto de Algoritmos Cap.8 Processamento de Cadeias de Caracteres Seo 8.2.4 140
Comparao das Tcnicas de Compresso: Arquivo WSJ
Dados sobre a coleo usada nos experimentos:
Texto Vocabulrio Vocab./Texto
Tam (bytes) #Palavras Tam (bytes) #Palavras Tamanho #Palavras
262.757.554 42.710.250 1.549.131 208.005 0,59% 0,48%
Mtodo
Razo de Tempo (min) de Tempo (min) de
Compresso Compresso Descompresso
Huffman binrio 27,13 8,77 3,08
Huffman pleno 30,60 8,67 1,95
Huffman com marcao 33,70 8,90 2,02
Gzip 37,53 25,43 2,68
Compress 42,94 7,60 6,78
Projeto de Algoritmos Cap.8 Processamento de Cadeias de Caracteres Seo 8.2.5 141
Pesquisa em Texto Comprimido
Uma das propriedades mais atraentes do mtodo de Huffman usando
bytes em vez de bits que o texto comprimido pode ser pesquisado
exatamente como qualquer texto no comprimido.
Basta comprimir o padro e realizar uma pesquisa diretamente no
arquivo comprimido.
Isso possvel porque o cdigo de Huffman usa bytes em vez de bits;
de outra maneira, o mtodo seria complicado ou mesmo impossvel de
ser implementado.
Projeto de Algoritmos Cap.8 Processamento de Cadeias de Caracteres Seo 8.2.5 142
Casamento Exato: Algoritmo
Buscar a palavra no vocabulrio, podendo usar busca binria nesta
fase:
Se a palavra for localizada no vocabulrio, ento o cdigo de
Huffman com marcao obtido.
Seno a palavra no existe no texto comprimido.
A seguir, o cdigo pesquisado no texto comprimido usando qualquer
algoritmo para casamento exato de padro.
Para pesquisar um padro contendo mais de uma palavra, o primeiro
passo vericar a existncia de cada palavra do padro no
vocabulrio e obter o seu cdigo:
Se qualquer das palavras do padro no existir no vocabulrio,
ento o padro no existir no texto comprimido.
Seno basta coletar todos os cdigos obtidos e realizar a pesquisa
no texto comprimido.
Projeto de Algoritmos Cap.8 Processamento de Cadeias de Caracteres Seo 8.2.5 143
Pesquisa no Arquivo Comprimido
void Busca(FILE ArqComprimido, FILE ArqAlf )
{ TipoAlfabeto Alfabeto;
int Ind , Codigo, MaxCompCod;
TipoVetorPalavra Vocabulario =
(TipoVetorPalavra) calloc(M+1,sizeof(TipoPalavra) ) ;
TipoVetoresBO VetoresBaseOffset = (TipoVetoresBO)
calloc(MAXTAMVETORESDO+1,sizeof(TipoBaseOffset ) ) ;
TipoPalavra p; int c, Ord, NumNodosFolhas;
TipoTexto T; TipoPadrao Padrao;
memset(T, 0 , sizeof T) ; memset(Padrao, 0 , sizeof Padrao) ;
int n = 1;
DefineAlfabeto( Alfabeto, ArqAlf ) ; /Le alfabeto def . em arquivo/
MaxCompCod = LeVetores(ArqComprimido, VetoresBaseOffset ) ;
NumNodosFolhas = LeVocabulario(ArqComprimido, Vocabulario) ;
while ( fread(&T[n] , sizeof(char) , 1 , ArqComprimido) ) n++;
Projeto de Algoritmos Cap.8 Processamento de Cadeias de Caracteres Seo 8.2.5 144
Pesquisa no Arquivo Comprimido
while (1)
{ pr i nt f ( "Padrao ( di gi te s para terminar ) : " ) ;
fgets(p, MAXALFABETO + 1 , stdin ) ;
p[ strl en(p) 1] = \0 ;
i f ( strcmp(p, "s" ) == 0) break;
for ( Ind = 1; Ind <= NumNodosFolhas; Ind++)
i f ( ! strcmp(Vocabulario[ Ind] , p) ) { Ord = Ind; break; }
i f ( Ind == NumNodosFolhas+1)
{ pr i nt f ( "Padrao:%s nao encontrado\n" , p) ; continue; }
Codigo = Codifica(VetoresBaseOffset , Ord, &c, MaxCompCod) ;
Atri bui (Padrao, Codigo, c) ;
BMH(T, n, Padrao, c) ;
}
free ( Vocabulario) ; free ( VetoresBaseOffset ) ;
}
Projeto de Algoritmos Cap.8 Processamento de Cadeias de Caracteres Seo 8.2.5 145
Procedimento para Atribuir o Cdigo ao Padro
void Atri bui (TipoPadrao P, int Codigo, int c)
{ int i = 1;
P[ i ] = (char) ( (Codigo >> ((c 1) 7)) | 0x80) ;
i ++; c;
while ( c > 0)
{ P[ i ] = (char) ( (Codigo >> ((c 1) 7)) & 127);
i ++; c;
}
}
Projeto de Algoritmos Cap.8 Processamento de Cadeias de Caracteres Seo 8.2.5 146
Teste dos Algoritmos de Compresso, Descompresso e
Busca Exata em Texto Comprimido (1)
/ Entram aqui os tipos do Programa 5.28 /
/ Entram aqui os tipos do Programa do Slide 4 /
typedef short TipoAlfabeto[ MAXALFABETO + 1] ;
typedef struct TipoBaseOffset {
int Base, Offset ;
} TipoBaseOffset ;
typedef TipoBaseOffset TipoVetoresBO;
typedef char TipoPalavra[256];
typedef TipoPalavra TipoVetorPalavra;
Projeto de Algoritmos Cap.8 Processamento de Cadeias de Caracteres Seo 8.2.5 147
Teste dos Algoritmos de Compresso, Descompresso e
Busca Exata em Texto Comprimido (2)
/ Entra aqui o procedimento GeraPeso do Programa 5.22 /
/ Entra aqui a funo de transformao do Programa 5.23 /
/ Entram aqui os operadores apresentados no Programa 5.29 /
/ Entram aqui os procedimentos Particao e Quicksort dos Programas 4. 6 e 4.7 /
int main( int argc, char argv[ ] )
{ FILE ArqTxt = NULL, ArqAlf = NULL; FILE ArqComprimido = NULL;
TipoPalavra NomeArqTxt, NomeArqAlf, NomeArqComp, Opcao;
memset(Opcao, 0 , sizeof(Opcao) ) ;
while(Opcao[ 0] ! = t )
{ pr i nt f ( "\n" ) ;
pr i nt f ( " Opcoes \n" ) ;
pr i nt f ( " (c) Compressao \n" ) ;
pr i nt f ( " (d) Descompressao \n" ) ;
pr i nt f ( " (p) Pesquisa no texto comprimido \n" ) ;
pr i nt f ( " ( t ) Termina \n" ) ;
pr i nt f ( "\n" ) ;
Projeto de Algoritmos Cap.8 Processamento de Cadeias de Caracteres Seo 8.2.5 148
Teste dos Algoritmos de Compresso, Descompresso e
Busca Exata em Texto Comprimido (3)
pr i nt f ( " Opcao: " ) ;
fgets(Opcao, MAXALFABETO + 1 , stdin ) ;
strcpy(NomeArqAlf, " alfabeto. t xt " ) ;
ArqAlf = fopen(NomeArqAlf, " r " ) ;
i f (Opcao[0] == c )
{ pr i nt f ( "Arquivo texto a ser comprimido: " ) ;
fgets(NomeArqTxt, MAXALFABETO + 1 , stdin ) ;
NomeArqTxt[ strl en(NomeArqTxt)1] = \0 ;
pr i nt f ( "Arquivo comprimido a ser gerado: " ) ;
fgets(NomeArqComp, MAXALFABETO + 1 , stdin ) ;
NomeArqComp[ strl en(NomeArqComp)1] = \0 ;
ArqTxt = fopen(NomeArqTxt, " r " ) ;
ArqComprimido = fopen(NomeArqComp, "w+b" ) ;
Compressao(ArqTxt , ArqAlf , ArqComprimido) ;
fclose(ArqTxt ) ;
ArqTxt = NULL;
fclose(ArqComprimido) ;
ArqComprimido = NULL;
}
Projeto de Algoritmos Cap.8 Processamento de Cadeias de Caracteres Seo 8.2.5 149
Teste dos Algoritmos de Compresso, Descompresso e
Busca Exata em Texto Comprimido (4)
else i f (Opcao[0] == d )
{ pr i nt f ( "Arquivo comprimido a ser descomprimido: " ) ;
fgets(NomeArqComp, MAXALFABETO + 1 , stdin ) ;
NomeArqComp[ strl en(NomeArqComp)1] = \0 ;
pr i nt f ( "Arquivo texto a ser gerado: " ) ;
fgets(NomeArqTxt, MAXALFABETO + 1 , stdin ) ;
NomeArqTxt[ strl en(NomeArqTxt)1] = \0 ;
ArqTxt = fopen(NomeArqTxt, "w" ) ;
ArqComprimido = fopen(NomeArqComp, " r+b" ) ;
Descompressao(ArqComprimido, ArqTxt , ArqAlf ) ;
fclose(ArqTxt ) ;
ArqTxt = NULL;
fclose(ArqComprimido) ;
ArqComprimido = NULL;
}
Projeto de Algoritmos Cap.8 Processamento de Cadeias de Caracteres Seo 8.2.5 150
Teste dos Algoritmos de Compresso, Descompresso e
Busca Exata em Texto Comprimido (5)
else i f (Opcao[0] == p )
{ pr i nt f ( "Arquivo comprimido para ser pesquisado: " ) ;
fgets(NomeArqComp, MAXALFABETO + 1 , stdin ) ;
NomeArqComp[ strl en(NomeArqComp)1] = \0 ;
strcpy(NomeArqComp, NomeArqComp) ;
ArqComprimido = fopen(NomeArqComp, " r+b" ) ;
Busca(ArqComprimido, ArqAlf ) ;
fclose(ArqComprimido) ;
ArqComprimido = NULL;
}
}
return 0;
}
Projeto de Algoritmos Cap.8 Processamento de Cadeias de Caracteres Seo 8.2.5 151
Casamento Aproximado: Algoritmo
Pesquisar o padro no vocabulrio. Nesse caso, podemos ter:
Casamento exato, o qual pode ser uma pesquisa binria no
vocabulrio, e uma vez que a palavra tenha sido encontrada a folha
correspondente na rvore de Huffman marcada.
Casamento aproximado, o qual pode ser realizado por meio de
pesquisa sequencial no vocabulrio, usando o algoritmo Shift-And.
Nesse caso, vrias palavras do vocabulrio podem ser encontradas
e a folha correspondente a cada uma na rvore de Huffman
marcada.
A seguir, o arquivo comprimido lido byte a byte, ao mesmo tempo
que a rvore de decodicao de Huffman percorrida.
Ao atingir uma folha da rvore, se ela estiver marcada, ento existe
casamento com a palavra do padro.
Seja uma folha marcada ou no, o caminhamento na rvore volta
raiz ao mesmo tempo que a leitura do texto comprimido continua.
Projeto de Algoritmos Cap.8 Processamento de Cadeias de Caracteres Seo 8.2.5 152
Esquema Geral de Pesquisa para a Palavra uma
Permitindo 1 Erro
ama
puma
uma
umas
Projeto de Algoritmos Cap.8 Processamento de Cadeias de Caracteres Seo 8.2.5 153
Casamento Aproximado Usando uma Frase como Padro
Frase: sequncia de padres (palavras), em que cada padro pode
ser desde uma palavra simples at uma expresso regular complexa
permitindo erros.
Pr-Processamento:
Se uma frase tem j palavras, ento uma mscara de j bits colocada
junto a cada palavra do vocabulrio (folha da rvore de Huffman).
Para uma palavra x da frase, o i-simo bit da mscara feito igual a 1
se x a i-sima palavra da frase.
Assim, cada palavra i da frase pesquisada no vocabulrio e a
i-sima posio da mscara marcada quando a palavra
encontrada no vocabulrio.
Projeto de Algoritmos Cap.8 Processamento de Cadeias de Caracteres Seo 8.2.5 154
Casamento Aproximado Usando uma Frase como Padro
O estado da pesquisa controlado por um autmato nito
no-determinista de j + 1 estados.
O autmato permite mover do estado i para o estado i + 1 sempre que
a i-sima palavra da frase reconhecida.
O estado zero est sempre ativo e uma ocorrncia relatada quando
o estado j ativado.
Os bytes do texto comprimido so lidos e a rvore de Huffman
percorrida como antes.
Cada vez que uma folha da rvore atingida, sua mscara de bits
enviada para o autmato.
Um estado ativo i 1 ir ativar o estado i apenas se o i-simo bit da
mscara estiver ativo.
O autmato realiza uma transio para cada palavra do texto.
Projeto de Algoritmos Cap.8 Processamento de Cadeias de Caracteres Seo 8.2.5 155
Esquema Geral de Pesquisa para Frase uma ro
*
rosa
XXX
XX1 X1X 1XX
rosa
roupa
azul
uma
rosas
011
100
000
010
011
O autmato pode ser implementado ecientemente por meio do
algoritmo Shift-And
Separadores podem ser ignorados na pesquisa de frases.
Artigos, preposies etc., tambm podem ser ignorados se
conveniente, bastando ignorar as folhas correspondentes na rvore de
Huffman quando a pesquisa chega a elas.
Essas possibilidades so raras de encontrar em sistemas de pesquisa
on-line.
Projeto de Algoritmos Cap.8 Processamento de Cadeias de Caracteres Seo 8.2.5 156
Tempos de Pesquisa (em segundos) para o Arquivo WSJ,
com Intervalo de Conana de 99%
Algoritmo k = 0 k = 1 k = 2 k = 3
Agrep 23,8 0,38 117,9 0,14 146,1 0,13 174,6 0,16
Pesquisa direta 14,1 0,18 15,0 0,33 17,0 0,71 22,7 2,23
Pesquisa com autmato 22,1 0,09 23,1 0,14 24,7 0,21 25,0 0,49

You might also like