| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 1974 人关注过本帖
标题:分享:哈希表运用(宏定义)
只看楼主 加入收藏
Emotiona
Rank: 7Rank: 7Rank: 7
等 级:黑侠
帖 子:311
专家分:581
注 册:2017-3-7
结帖率:97.5%
收藏
已结贴  问题点数:20 回复次数:9 
分享:哈希表运用(宏定义)
功能:宏定义和宏定义删除
终于把结构体这章弄完了,太耗时了。不过,这章和数组及指针那章学到的东西很多,不愧是金典!!!

Hashtab_Def.h:
程序代码:
#ifndef HASHTAB_DEFINE
#define    HASHTAB_DEFINE
#define MAXWORD        100
#define    HASHSIZE    101

typedef struct Hlist
{
    char *name;
    char *def;
    struct Hlist *next;
}HList;

Hlist *install(char *, char *);
Hlist *lookup(char *);
void error(int, char *);
int getch(void);
void ungetch(int);
int getword(char *, int);
void skipblanks(void);
void getdef(void);
void undef(char *);
void ungets(char *);
unsigned hash(char *s);
char *strdup(char *s);

static Hlist *hashtab[HASHSIZE];
#endif



Hashtab_Def.cpp:
程序代码:
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
#include "Hashtab_Def.h"

int main()
{
    char w[MAXWORD];
    int i;
    Hlist *p;

    while (getword(w, MAXWORD) != EOF)
        if (strcmp(w, "#") == 0)
            getdef();
        else 
            printf("%s :not is define name\n", w);

    printf("Please end EOF to printf result\n");
        for (i = 0; i < HASHSIZE; i++)
            for (p = hashtab[i]; p != NULL; p = p->next)
                printf("%s %s\n", p->name, p->def);

        return 0;
    
}

void getdef(void)
{
    int c, i;

    char name[MAXWORD], def[MAXWORD], dir[MAXWORD];

    skipblanks();

    if (!isalpha(getword(dir, MAXWORD)))
        error(dir[0], "getdef :non-alpha - name expected");
    else if (strcmp(dir, "define") == 0)
    {
        skipblanks();
        if (!isalpha(getword(name, MAXWORD)))
            error(name[0], "getdef: non -alpha -name expected");
        else
        {
            skipblanks();
            for (i = 0; i < MAXWORD; i++)
                if ((def[i] = getch()) == EOF || def[i] == '\n')
                    break;
            c = def[i];
            def[i] = '\0';
            if (c == '\n' && i == 0)
                error('\n', "define cannot is line feed\n");
            else
                install(name, def);
        }
    }
    else if (strcmp(dir, "undef") == 0)
    {
        skipblanks();
        if (!isalpha(getword(name, MAXWORD)))
            error(name[0], "getdef :non-alpha in undef");
        else
            undef(name);
    }
    else
        error(dir[0], "error : not is #define or #undef");

        
}

void skipblanks()
{
    int c;

    while ((c = getch()) == '\t' || c == ' ')
        ;
    ungetch(c);
}

void error(int c, char *s)
{
    printf("error:%s\n", s);
    while (c != EOF && c != '\n')
        c = getchar();
}

Hlist *install(char *name, char *def)
{
    Hlist *p;
    unsigned hashval;

    if ((p = lookup(name)) == NULL)
    {
        p = (Hlist *)malloc(sizeof(Hlist));
        if (p == NULL || (p->name = strdup(name)) == NULL)
            return NULL;
        hashval = hash(name);
        p->next = hashtab[hashval];
        hashtab[hashval] = p;
        printf("define successed\n");
    }
    else
        free(p->def);
    if ((p->def = strdup(def)) == NULL)
    {
        printf("redefine successed\n");
        return NULL;
    }
        
    return p;
}

Hlist *lookup(char *s)
{
    Hlist *p;

    for (p = hashtab[hash(s)]; p != NULL; p = p->next)
        if (!strcmp(s, p->name))
            return p;
    return NULL;
}

unsigned hash(char *s)
{
    unsigned hashval;

    for (hashval = 0; *s != '\0'; s++)
        hashval = *s + 31 * hashval;
    return hashval % HASHSIZE;
}

void undef(char *s)
{
    int h;
    Hlist *prev, *p;

    prev = NULL;
    h = hash(s);
    for (p = hashtab[h]; p != NULL; p = p->next)
    {
        if (!strcmp(s, p->name))
            break;
        prev = p;
    }
    if (p != NULL) {
        if (prev == NULL)
            hashtab[h] = p->next;
        else
            prev->next = p->next;
        free(p->name);
        free(p->def);
        free(p);
        printf("Undef successed\n");
    }
}


GetWord.cpp:
程序代码:
#include <ctype.h>
#include <stdio.h>

int getword(char *word, int lim)
{
    int c, getch();
    void ungetch(int);
    char *w = word;

    while (isspace(c = getch()))
        ;
    if (c != EOF)
        *w++ = c;
    if (!isalnum(c)) {
        *w = '\0';
        return c;
    }
    for (; --lim; w++)
        if (!isalnum(*w = getch()))
        {
            ungetch(*w);
            break;
        }
    *w = '\0';
    return word[0];
}


Getch.cpp:
程序代码:
#include<string.h>
#include <stdio.h>

#define BUFSIZE 100

char buf[BUFSIZE];
int bufp = 0;

int getch()
{
    return (bufp > 0) ? buf[--bufp] : getchar();
}

void ungetch(int c)
{
    if (bufp >= BUFSIZE)
        printf("ungetch: too many charaters\n");
    else
        buf[bufp++] = c;
}

void ungets(char *s)
{
    int len;
    extern void ungetch(int);
    while ((len = strlen(s)) > 0)
        ungetch(s[--len]);
}


Strdup.cpp:
程序代码:
#include <malloc.h>
#include <string.h>

char *strdup(char *s)
{
    char *p;

    p = (char *)malloc(strlen(s) + 1);
    if (p != NULL)
        strcpy(p, s);
    return p;
}
搜索更多相关主题的帖子: 结构体 
2017-05-21 13:30
九转星河
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:长长久久
等 级:贵宾
威 望:52
帖 子:5023
专家分:14003
注 册:2016-10-22
收藏
得分:10 
现在已经感觉在数据结构跟不上了~还是问问这个是课本上的例题么??~

[code]/*~个性签名:bug是什么意思?bug是看上去没有可能的东西实际上是有可能做到的 就是这样~2018-08-08更~*/[/code]
2017-05-21 13:59
Emotiona
Rank: 7Rank: 7Rank: 7
等 级:黑侠
帖 子:311
专家分:581
注 册:2017-3-7
收藏
得分:0 
回复 2楼 九转星河
这是k & r习题。这本书小白看的话还是够呛~~~~~~~~~~~,可以算是基础的深层次理解

[此贴子已经被作者于2017-5-21 14:04编辑过]

2017-05-21 14:00
九转星河
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:长长久久
等 级:贵宾
威 望:52
帖 子:5023
专家分:14003
注 册:2016-10-22
收藏
得分:0 
回复 3楼 Emotiona
问一下~

程序代码:
unsigned hash(char *s)
{
    unsigned hashval;

    for (hashval = 0; *s != '\0'; s++)
        hashval = *s + 31 * hashval;
    return hashval % HASHSIZE;
}


这个31是怎么算出来的?~似乎这和哈希的性质有关…………~~

这个31=2^5-1~~~设为32的话……看上去32位最多能容6个字符~~~~~~~

[此贴子已经被作者于2017-5-21 14:39编辑过]


[code]/*~个性签名:bug是什么意思?bug是看上去没有可能的东西实际上是有可能做到的 就是这样~2018-08-08更~*/[/code]
2017-05-21 14:36
Emotiona
Rank: 7Rank: 7Rank: 7
等 级:黑侠
帖 子:311
专家分:581
注 册:2017-3-7
收藏
得分:0 
回复 4楼 九转星河
这是求散列值。完美散列表,关系是一对一,没有冲突。这样完美的基本没有,只是尽量减少冲突。但是要设计一个这样求散列值的函数要精心安排的。这种只是常用的取余法
假如0,1,2,3,4,5,6下标的数组,分对应7个数据,没有冲突的情况下,是一一对应,直接用下标就能找到数据。假如这几数据为,1,2,3,3,4,5,6,要一一对应改怎么存放。放一个地址?这就是那个哈希函数的目的,减少冲突。函数不一定要那个,你自己设计
2017-05-21 17:17
Emotiona
Rank: 7Rank: 7Rank: 7
等 级:黑侠
帖 子:311
专家分:581
注 册:2017-3-7
收藏
得分:0 
回复 5楼 Emotiona
我都不考虑31怎么来的,他不就是为了减少冲突来的,和HASHSIZE一样也是设置101  尽量单数。你想想素数

[此贴子已经被作者于2017-5-21 17:20编辑过]

2017-05-21 17:18
九转星河
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:长长久久
等 级:贵宾
威 望:52
帖 子:5023
专家分:14003
注 册:2016-10-22
收藏
得分:0 
回复 5楼 Emotiona
现在可以理解了~冲突情况就要要在此基础上多申请一个空间~有点像桶结构~不过和桶排序相比这个对于处理值域要求没有限制罢了~

[code]/*~个性签名:bug是什么意思?bug是看上去没有可能的东西实际上是有可能做到的 就是这样~2018-08-08更~*/[/code]
2017-05-21 18:27
renkejun1942
Rank: 14Rank: 14Rank: 14Rank: 14
来 自:不是这样
等 级:贵宾
威 望:33
帖 子:1645
专家分:5297
注 册:2016-12-1
收藏
得分:10 
就改了下main函数中的一丁点儿,以及各个函数的变量名。
抄答案和该小节的散列表函数以及其他章节的一些函数,的确挺累的。

PS:strdup()在string.h中是有这个函数的,不需要再抄书。(虽然这个函数并非标准函数,但几乎所有编译器都自带这个函数)

[此贴子已经被作者于2017-5-21 23:06编辑过]


09:30 05/21 种下琵琶种子,能种活么?等待中……
21:50 05/27 没有发芽。
20:51 05/28 没有发芽。
23:03 05/29 没有发芽。
23:30 06/09 我有预感,要发芽了。
2017-05-21 23:04
Emotiona
Rank: 7Rank: 7Rank: 7
等 级:黑侠
帖 子:311
专家分:581
注 册:2017-3-7
收藏
得分:0 
回复 8楼 renkejun1942
我都是看懂了,跟着思路走一遍,加深印象。
2017-05-22 00:14
九转星河
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:长长久久
等 级:贵宾
威 望:52
帖 子:5023
专家分:14003
注 册:2016-10-22
收藏
得分:0 
回复 8楼 renkejun1942
积累了strdup函数~感觉又学到新东西了~~

[code]/*~个性签名:bug是什么意思?bug是看上去没有可能的东西实际上是有可能做到的 就是这样~2018-08-08更~*/[/code]
2017-05-22 03:17
快速回复:分享:哈希表运用(宏定义)
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.020889 second(s), 9 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved