icoding测试代码---哈希表

本程序可以适用于

icoding的数据结构并没有一个测试代码,其都是直接编写一个函数的形式,因此很难知道自己的实际输出是什么。针对部分题目,我编写了一系列测试代码以供大家进行数据输出的测试。

HashTable* create_hash(int size){
   //TODO

}

HASH_RESULT hash_add_int(HashTable *table, const char *key,  int value){
    //TODO

}

请将您的函数代码复制到上述函数中,然后修改main函数的相关内容,完成测试样例的输入

请注意,对于hash表添加:在添加过程中,如果要添加的键值key已在哈希表中,且对应的值value也已存在,则函数返回 HASH_ALREADY_ADDED如果要添加的键值key已在哈希表中,但对应的值value不同,则函数将value值更新到哈希表中,之后返回 HASH_REPLACED_VALUE如果要添加的键值key不在哈希表中,则函数创建 HashEntry 类型,并将其加入到哈希表中,且函数返回 HASH_ADDED。

哈希函数

long hash_string(const char *str)
{
    long hash = 5381;
    int c;

    while (c = *str++)
        hash = ((hash << 5) + hash) + c; /* hash * 33 + c */
    if(hash < 0)
        hash *= -1;
    return hash;
}

已经实现并且已经添加到下方的代码中。

———————————————————————————————————————————

如果插入后打印链表为空链表,且插入操作正确。说明您对hash_string函数返回值处理错误

#include<stdio.h>
#include<stdbool.h>
#include<string.h>
#include <stdlib.h>

typedef enum{
    HASH_OK,
    HASH_ERROR,
    HASH_ADDED,
    HASH_REPLACED_VALUE,
    HASH_ALREADY_ADDED,
    HASH_DELETED,
    HASH_NOT_FOUND,
} HASH_RESULT;

typedef struct __HashEntry HashEntry;
struct __HashEntry{
    union{
        char  *str_value;
        double dbl_value;
        int       int_value;
    } key;
    union{
        char  *str_value;
        double dbl_value;
        int       int_value;
        long   long_value;
        void  *ptr_value;
    } value;
    HashEntry *next;
};

struct __HashTable{
    HashEntry **bucket;        
    int size;
    HASH_RESULT last_error;
};
typedef struct __HashTable HashTable;



long hash_string(const char *str)
{
    long hash = 5381;
    int c;
    while ((c = *str++) != 0)
        hash = ((hash << 5) + hash) + c; /* hash * 33 + c */
    return hash;
}
//hash表添加

//打印hash表
void print_hash(HashTable *table){
    int i;
    for(i=0;i<table->size;i++){
        HashEntry *p = table->bucket[i];
        if(i>=10)printf("[%d]| ",i);
        else{
            printf("[0%d]| ",i);
        }
        if(p==NULL) printf("^ ");
        while(p!=NULL){
            if(p->next!=NULL){
            printf("%d(%s)-> ", p->value.int_value, p->key.str_value);
            p = p->next;
            }
            if(p->next==NULL){
                printf("%d(%s) ^ ", p->value.int_value, p->key.str_value);
            p = p->next;
            }
        }
        putchar('\n');
    }
}

//----------以上为辅助函数-----------------
HashTable* create_hash(int size){
   //TODO

}

HASH_RESULT hash_add_int(HashTable *table, const char *key,  int value){
     //TODO 

}



int main(){
//----------------以 下 内 容 可 修 改-----------------
    int size=10;//hash表大小,可修改,需要是正整数
    bool print_empty_table=true;//是否打印空表?true:打印,false:不打印
    //用以判断初始化是否正确
    
    bool flag = true;//是否测试添加函数hash_add_int?true:测试,false:不测试
    
    //若初始化函数错误,请勿进行相关测试
    int val[]={1,2,3,4,1,1,258};//要添加的数据的value
    char key[][7]={"a","bb","ccc","dddd","k","a","bb"};//要添加的数据的key
    //注意key为字符串!所以需要用双引号引起
    //key的第二个数据需要手动填写,内容为字符串总个数
    //key的第二个数据需要手动填写,内容为字符串总个数
    //key的第二个数据需要手动填写,内容为字符串总个数
    //key的第二个数据需要手动填写,内容为字符串总个数
    //程序会将相同下标的val和key视为一组,比如("a",1)是一组
    //保证两个数组的长度相同(程序会检测)

    //程序会循环添加数据,直到添加成功为止。可以依次查看hash_add_int函数是否正确。
//----------------以 上 内 容 可 修 改-----------------

    printf("icoding\nHash Table\n");
    printf("*提示*  本题hash_add_int的val为int类型,key为字符串;本题添加函数需要对key相同和val相同的数据进行替换操作,请仔细审题\n----开始测试----\n");

    if(size<=0){
        printf("size值必须为大于0的正整数,请修改main函数的size值\n程序自动终止,请修改\n");
        return -1;
    }

    int len1 = sizeof(val)/sizeof(int);
    //定义len2,统计key的字符串个数
    int len2 = sizeof(key)/sizeof(key[1]);
    if(len1!=len2){
        printf("数组长度不一致,其中val长度为%d,key长度为%d,请检查\n程序自动终止,请修改源代码\n",len1,len2);
        return 0;
    }

    printf(">>创建hash表,将创建%d个空位\n",size); 
    HashTable *table = create_hash(size);
    if(table==NULL){
        printf("创建hash表失败,返回值为NULL\n程序自动终止,请修改源代码\n");
        return 0;
    }else if(table->bucket==NULL){
        printf("创建hash表失败,table->bucket为NULL\n程序自动终止,请修改源代码\n");
        return 0;
    }
    else if(table->size!=size){
        printf("您的hash表的table->size值为%d,正确应该为%d,赋值错误\n请检查是否正确赋值\n程序自动终止,请修改源代码\n",table->size,size);
        return 0;
    }else{
        printf("创建hash表成功\n·table->bucket地址为 %p \n·table->size  大小为 %d\t [%s]\n",table->bucket,table->size,size==table->size?"赋值正确":"赋值错误,请检查!");
    }
    if(print_empty_table){
        printf("\n···打印空的hash表···\n");
        print_hash(table);
    }
    
    printf("\n\n");
    if(flag){
    printf(">>添加元素\n");
    printf("下方会显示添加的结果\n添加成功不显示,序号从0开始,若不显示请检测是否正确返回值\n-------------------------------------------------\n");
    printf("序号\t[状  态]\tKey\tVal\t  说明\n");
        bool is_print=false;//是否输出了错误数据?
    for(int i=0;i<len1;i++){
        HASH_RESULT result = hash_add_int(table,key[i],val[i]);
        //hash_add_int(table, key[i], val[i]);
        if(result==HASH_ALREADY_ADDED){
            printf("%d\t[已存在]\t%s\t%d\t重复添加val和key相同的数据\n",i,key[i],val[i]);
            is_print=true;
        }
        else if(result==HASH_ERROR){
            is_print=true;
            printf("%d\t[失  败]\t%s\t%d\t函数返回ERROR,可能无法开辟空间\n",i,key[i],val[i]);
        }else if(result==HASH_REPLACED_VALUE){
            is_print=true;
            printf("%d\t[值替换]\t%s\t%d\t键相同,值不同,替换成最新值\n",i,key[i],val[i]);
        }
        else{
            continue;
        }

    }
            if(!is_print){
                printf("\n   ····所有数据均正确插入,函数未返回错误····   \n\n");
            }
        printf("-------------------------------------------------\n···打印hash表···\n^表示空或终止,数字代表Val值,()内表示key值。val为int类型,key为字符串\n");
        print_hash(table);
    }
    else{
        printf("您未进行添加元素的函数运行,若需要请修改main函数的flag");
    }
    printf("\n");
    
    printf("本程序仅用于可视化输出,不进行正确与错误的准确判断\n----测试结束----\n");
    return 0;

}

如果不对函数内置测试样例进行更改,那么将有以下输出

 解释:【"a",1】插入两次,为重复插入。只进行一次。【"bb",1】【"bb",258】两组数据先后被输入,他们的key相同,但value不同,替换为最新的。【"k",1】【"a",1】key不同,因此不替换正常插入,但由于hash相同,链接在同一个bucket里面。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

谨慎谦虚

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值