[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

RE: Exemplo freq (hashing)



Marcos Lemos writes:
 > Alguém já testou o programa freq que se encontra na página ?
 >      Eu o testei com a seguinte entrada:
 >       lemos
 >       yoshi
 >       lemos
 >       knuth
 >       yoshi
 >       knuth
 > 
 >      E obtive a seguinte saída :
 >          
 >      lemos 2 
 >    
 >      ..., ou seja, simplesmente o programa não contou as palavras "yoshi"
 > e "knuth".

Eu experimentei rodar com a sua entrada e obtive o seguinte:

======================================================================
<4>[random:/home/yoshi/examples/mac122] > freq < tmp.txt 
yoshi 2
lemos 2
knuth 2
Numero de palavras lidas = 6
Numero de comparacoes feitas = 3
Numero medio de comparacoes feitas por palavra lida = 0.500000
Numero de palavras distintas = 3
Numero esperado de palavras por lista ligada = 0.002973
<5>[random:/home/yoshi/examples/mac122] > cat tmp.txt
lemos
yoshi
lemos
knuth
yoshi
knuth
<6>[random:/home/yoshi/examples/mac122] > 
======================================================================

Experimente fazer o seguinte.  Troque a definicao da funcao pelo seguinte: 

/********************************************************************/
long hash_div(char *s)                                     
{@+                       
  long h;
  for (h=0; *s!='\0'; s++)
    h=(258*h+(unsigned char)*s)%HASH_PRIME;
  return h;
}
/********************************************************************/

Para ser totalmente coerente, talvez voce queira tambem trocar a declaracao de
h_valor para 

long h_valor;

mas isto nao é estritamente necessario.  

O que deve estar acontecendo é o seguinte.  No calculo de h, deve estar dando
overflow em um dos passos em que se calcula 

  258*h+(unsigned char)*s

Aí, quando se calcula este valor %HASH_PRIME, obtemos um numero negativo.
Infelizmente, em C, quando fazemos uma operacao do tipo a%b e tem numeros
negativos envolvidos, nao podemos ter certeza sobre o sinal de a%b (bem, isto
falando a grosso modo). 

Concluindo, provavelmente o seu compilador e o gcc (que estou usando) tem
limites diferentes para os maiores inteiros que eles podem aceitar em
variaveis tipo int.

No gcc, 

INT_MAX=2147483647
INT_MIN=-2147483648

LONG_MAX=2147483647
LONG_MIN=-2147483648

Isto é, tanto para int como para long, os valores admissiveis sao tais que 

-2^31 <= x <= 2^31-1.

Provavelmente isto é diferente em seu compilador.  Para saber quais sao os
limites nele, escreva um programinha que imprime as constantes

INT_MAX e INT_MIN,

definidas em <limits.h>.  Veja Seçao B.11 de Kernighan & Ritchie.

Boa sorte!

Yoshi 

 >      Bem, no cálculo do h_valor, substituí 258 por 128:
 > 
 >         h = (128 * h + (unsigned char) *s) % HASH_PRIME;
 > 
 >      Aí o programa retornou a resposta correta:
 >      lemos 2
 >      yoshi 2
 >      knuth 2
 >      Fiz alguns testes e descobri que com o valor 258, o programa estava
 > tentando armazenar a palavra "yoshi" na posição -302 do vetor!!!
 >      Será que este problema está acontecendo somente comigo ? Gostaria que
 > alguém verificasse...
 > 
 > Lemos