给出奇数输出的链表哈希表

时间:2016-07-22 23:04:50

标签: c data-structures hash io linked-list

我正在创建一个哈希表,它使用链接列表从单词中删除所有标点符号,并计算给定文本文件中每个单词的出现次数,然后将该信息打印到新文件中。如果这个词是"你好=! - AB"然后它应该算作"" helloab"我得到一些奇怪的输出 enter image description here

应该有单词而不是^ 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;
}

我知道我有内存泄漏。我要修复我的删除功能

1 个答案:

答案 0 :(得分:0)

  

我仍然得到&#34; ,数&#34;

由于使用removep()函数中删除所有标点符号,因此完全由标点字符组成的单词最后会显示为空字符串,这正确显示在此

, number
行。