我正在创建一个哈希表,它使用链接列表从单词中删除所有标点符号,并计算给定文本文件中每个单词的出现次数,然后将该信息打印到新文件中。如果这个词是"你好=! - AB"然后它应该算作"" helloab"我得到一些奇怪的输出
应该有单词而不是^ P.我有时候根本不会说一句话,它只是",45"或一些数字
这是哈希
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<ctype.h>
#include"hash.h"
/*
struct listnode{
char * word;
int count;
struct listnode * next;
};
*/
void hashCreate(struct listnode * hashTable[], int size){
int i;
for(i=0;i<size;i++){
hashTable[i]=(struct listnode *)malloc(sizeof(struct listnode));
hashTable[i]->word=NULL;
hashTable[i]->count=0;
hashTable[i]->next=NULL;
}
}
int hash(char * data, int size) {
unsigned long hash = 5381;
char * p;
for (p = data; *p != '\0'; ++p) {
hash = (hash * 33) + *p;
}
return (int)(hash % size);
}
struct listnode * hashSearch(char * data, struct listnode * hashTable[], int key){
struct listnode * cur;
cur=hashTable[key];
if(hashTable[key]->word==NULL)
return NULL;
while(cur!=NULL && strcmp(cur->word,data)!=0){
cur=cur->next;
}
if(cur!=NULL && strcmp(cur->word, data)==0)
return cur;
return NULL;
}
void hashAdd(char * data, struct listnode * hashTable[], int size){
int key=hash(data, size);
if (hashTable[key]->word == NULL) {
// First time with this key
hashTable[key]->word=strdup(data);
hashTable[key]->count+=1;
}
else {
// Key already used once
if (strcmp(data, hashTable[key]->word) == 0) {
// Same word
hashTable[key]->count+=1;
} else {
struct listnode * temp=(struct listnode *)malloc(sizeof(struct listnode));
temp->word=data;
temp->count=1;
temp->next=hashTable[key]->next;
hashTable[key]->next=temp;
}
}
}
void hashPrint(struct listnode * hashTable[], int size){
int i;
for(i=0;i<size;i++){
if(hashTable[i]->count!=0)
printf("%s, %d\n",hashTable[i]->word,hashTable[i]->count);
}
}
void hashDelete(struct listnode * hashTable[],int size){
int i;
for(i=0;i<size;i++){
free(hashTable[i]->word);
free(hashTable[i]);
}
}
这是使用它的文件
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<ctype.h>
#include"hash.h"
#define SIZE 5000
void removePunct(char * str);
void fileRead(char * filename);
void fileWrite();
void removep(char * p);
struct listnode * hashTable[9000];
int main(int argc, char ** argv){
int i;
if(argc<2)
fprintf(stderr,"Enter filename \n");
hashCreate(hashTable, SIZE);
for(i=1; i<argc; i++){
fileRead(argv[i]);
}
fileWrite();
hashDelete(hashTable, SIZE);
return 0;
}
void fileWrite(){
FILE * file=fopen("wordfrequency.txt","w");
int i;
struct listnode * temp;
for(i=0;i<SIZE;i++){
temp=hashTable[i];
if(hashTable[i]->count!=0){
for(temp=hashTable[i]; temp!=NULL; temp=temp->next){
fprintf(file,"%s, %d\n",temp->word, temp->count);
}
}
}
fclose(file);
}
void fileRead(char * filename){
FILE * file = fopen(filename,"r");
char word[500];
if(!file){
fprintf(stderr,"Error opening file \n");
return;
}
while(fscanf(file, "%s", word)==1){
removep(word);
hashAdd(word,hashTable,SIZE);
}
fclose(file);
}
//I dont like this one. Im using the other one below
void removePunct(char * str){
int i,p=0;
for(i=0; i<strlen(str);i++){
if(isdigit(str[i]) || isalpha(str[i])/* || str[i]==' '*/){
str[p]=tolower(str[i]);
p++;
}
}
str[p]='\0';
}
void removep(char *p)
{
char *src = p, *dst = p;
while (*src)
{
if (ispunct((unsigned char)*src))
{
/* Skip this character */
src++;
}
else if (isupper((unsigned char)*src))
{
/* Make it lowercase */
*dst++ = tolower((unsigned char)*src);
src++;
}
else if (src == dst)
{
/* Increment both pointers without copying */
src++;
dst++;
}
else
{
/* Copy character */
*dst++ = *src++;
}
}
*dst = 0;
}
我知道我有内存泄漏。我要修复我的删除功能
答案 0 :(得分:0)
我仍然得到&#34; ,数&#34;
由于使用removep()
函数从中删除所有标点符号,因此完全由标点字符组成的单词最后会显示为空字符串,这正确显示在此
, number行。