【发布时间】:2016-11-26 22:41:29
【问题描述】:
我正在制作一个哈希表,它使用链表从单词中删除所有标点符号,并计算给定文本文件中每个单词的出现次数,然后将该信息打印到新文件中。如果这个词是 "hello=!-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;
}
我知道我有内存泄漏。我要修复我的删除功能
【问题讨论】:
-
不确定这是否会做任何事情,但在您的 hashCreate 函数中尝试将其添加到循环上方。 hashTable=(struct listnode *)malloc(sizeof(struct listnode) * size);
-
temp->word=data;-->temp->word=strdup(data); -
@FreeStyle4 - 这是错误的。
hashTable是从main传递给hashCreate的全局字符数组。通过这样做,您将处理一个空数组,而不是处理对全局数组的引用。 -
@BLUEPIXY 谢谢,这解决了 ^P 问题。我仍然收到“,number”
-
我仍然得到 " ,number" 这是单词的出现次数,对吗? (
fprintf(file,"%s, %d\n",temp->word, temp->count);)
标签: c data-structures hash io linked-list