私はハッシュテーブルを実装していますが、いくつかの問題が発生しています。常に単語が追加されたときに更新されたハッシュテーブルを表示します。問題は、この単語が再び表示されるときに周波数を増やす必要があります。更新された頻度でもう一度印刷する:繰り返し単語を1回だけ印刷するにはどうすればよいですか?その頻度を示します。HashTable繰り返し単語を1回だけ印刷する方法は?
もう一つの問題はprint_freqです。それはint freqを受け取ると私はこの周波数の単語を印刷する必要がありますが、auxTableはhtableから単語を保存していないという問題があります。なぜauxtableは周波数を正常に保存するので、なぜ機能しないのか分かりませんが、単語を保存すると、空の文字 ""が保存されます。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#define HTABLE_SIZE 1001
#define MAX_LINE_SIZ 1024
/* Hash Table */
typedef struct node* HASH_TABLE; /* estrutura de dados utilizadas para formar a hastable*/
struct node {
char *palavra; /*word*/
int freq;
};
/*Declaracao das funcoes*/
void inserirHashTable(char *s);
void print_ht();
void print_test();
HASH_TABLE htable[HTABLE_SIZE] = { NULL }; /* Hash table que armazenará as palavras lidas do arquivos */
unsigned int chaves[HTABLE_SIZE]; /* Vetor que armazenará as chaves das palavras da tabela*/
int tamanhoChaves=-1; /*Variavel responsavel por contar a quantidade de chaves do vetor de chaves*/
int size = 0; /* variavel responsavel por armazenar o numero de elementos da tabela*/
/*Função responsavel por processar o arquivo, a mesma recebe o arquivo como parametro,
* pega cada palavra presente no arquivo separa dos simbolos ?!+.-... e chama a função
* inserirHT para inserir a palavra separada na tabela hash*/
void processarArquivo(FILE *fp)
{
const char *seperators = " ?!'\";,.:+-*&%(){}[]<>\\\t\n"; // caractertes que deveram ser separados
char line[MAX_LINE_SIZ];
char *s;
while((fgets(line,MAX_LINE_SIZ, fp)) != NULL) //pegando a linha do arquivo
{
for (s=strtok(line,seperators); s; s=strtok(NULL,seperators)){ // separando a palavra
/*printf("Palavra a ser inserida %s \n",s); printf utilizado para mostrar
* a palavra que foi seperada e será inserida*/
inserirHashTable(s);//Chamando a função inserir
}
}
}
/* Função responsavel por criar a chave de cada palavra que vai para tabela,
recebe como parametro um ponteiro para string, logo em seguida pega cada
caractere da string e gera um unsigned int para ele, retorna por fim o
modulo desse unsigned int pelo tamanho da tabela*/
unsigned int hash(char *tok)
{
unsigned int hv = 0;
while (*tok)
hv = (hv << 4) | toupper(*tok++);
/*printf("conversao: %d \n",hv); Printf utilizado para mostrar o valor de hv antes de ser retorna como modulo*/
return hv % HTABLE_SIZE;
}
/* funcao responsavel por isenrir a palavra lida do arquivo na hash_table,
* a funçãp recebe como parametro um ponteiro para estra palavra*/
void inserirHashTable(char *palavra) {
/*printf("Inserindo a palavra %s \n",palavra); Printf utilzado para mostrar a palavra a ser inserida na tabela*/
tamanhoChaves++; /*Assim que uma palavra é inserida o numero de chaves é incrementado*/
chaves[tamanhoChaves] = hash(palavra);/*A palavra é convertida na função hash e sua armazenada no vetor de chaves*/
unsigned int hashval = chaves[tamanhoChaves]; /*Chave da apalvra*/
if (htable[hashval]==NULL){
/*printf("indice %u de %s \n",hashval,palavra);Printf utilizado para mostrar a chave e a palavra a ser inserida*/
htable[hashval] = malloc(sizeof(palavra)); /*Alocando memoria para palavrra*/
htable[hashval]->palavra = palavra ; /*Inserindo a palavra*/
htable[hashval]->freq = 1; /*Incrementado sua frequencia*/
size++;
}else {
/*If a words already exists in the table, i just incremente her frequency and the size. I guess the problem for repeated word is in here*/
htable[hashval]->freq++;
size++;
}
/*A tabela é impressa a cada instante que uma palavra é inserida*/
printf("\nAtualização da tabela\n");
print_ht();/*Impressao das palavras já recebidas, a cada instante, com a quantidade de ocorrências*/
}
/* Function responsible to print the words that were addedd to the hash table*/
void print_ht() {
int i=0;
/*Tabela auxiliar que servira para impressao das palavras e suas chaves*/
HASH_TABLE *auxTable = (HASH_TABLE*) malloc(sizeof(HASH_TABLE)*size);
unsigned int hashval; /* variavel utilizada para pegar a chave das palavras no vetor de chaves */
for(i; i < size; i++){
hashval = chaves[i]; /*Pegando a chave*/
/*printf("indice %u de %s \n",hashval,htable[hashval]->token);Printf utilizado para ver a chave e a palavra*/
auxTable[i] = htable[hashval]; /*Atribuindo a palavra e a freq para tabela auxiliar*/
}
/*qsort(auxTable,size,sizeof(link),compare);*/
/*Imprimindo a tabela*/
printf("Palavra | Frequencia\n");
for (i=0; i < size; i++)
printf("%s \t %d\n",auxTable[i]->palavra,auxTable[i]->freq);
free(auxTable);
}
/*Funcion responsible to print the words with the frequency received in the paramater*/
void print_freq(int freq){
printf("Palavras com a frequencia: %d\n", freq);
int i, j =0;
HASH_TABLE *auxTable = (HASH_TABLE*) malloc(sizeof(HASH_TABLE)*size);
unsigned int hashval;
for(i; i < size; i++){
hashval = chaves[i];
/*printf("indice %u de %s \n",hashval,htable[hashval]->palavra);*/
auxTable[i] = htable[hashval]; /*Problem is in here, when I do this, the auxTable[i]->palavra(word) = "", but the freq has been saved normally n*/
}
printf("Palavra | Frequencia\n");
for (i=0; i < size; i++) {
if(auxTable[i]->freq == freq) {
printf("%s \t %d\n",auxTable[i]->palavra,auxTable[i]->freq); /*When I print, only the frequency is showed*/
}
}
free(auxTable);
}
int main(int argc, char *argv[])
{
int i;
FILE *fp;
fp = fopen("input.txt","r");
if (NULL == fp)
{
fprintf(stderr,"Error ao abrir o arquivo: %s\n",fp);
}
printf("Imprimindo processo \n");
processarArquivo(fp); /* debuuga aqui pra tu entender o q rola*/
fclose(fp);
print_freq(3); //should print the word with freq equal to 3
//print_ht();
/*clear_ht();*/
return 0;
}
出力:
あなたが実際にハッシュテーブルをスキャンしません。 'chaves []'配列をスキャンします。この配列には、遭遇した順序で各単語のハッシュ値が含まれています。補助テーブルは必要ありません。 htable [hashval] - > palavra、htable [hashval] - 単純な 'for(hashval = 0; hashval freq); 'で十分です。 –
残念ながら、基本的なバグもあります.2つの単語が同じ値にハッシュした場合、同じ単語として扱います。これは* [ハッシュコリジョン](https://en.wikipedia.org/wiki/Hash_table#Collision_resolution)*と呼ばれ、それを解決する方法はいくつかあります。私のお気に入りは、ノードを単一リンクリストにすることです。 (ところで、混合言語で書かれたコードを読むのは非常に難しいです。私は英語のネイティブスピーカーではありません.Cのキーワードは既に英語で書かれています。英語でのみ)。 –
助けてくれてありがとうございました。私はこのコメントを申し訳なく思っています。そのすべてはポルトガルにあります。 '、btw、それは私の問題です。私はハッシュコリジョンをどう扱わないか、このための材料やコードはありますか? –