鱼C论坛

 找回密码
 立即注册
查看: 925|回复: 2

[已解决]拜托大家看一下这个为什么查询不了?

[复制链接]
发表于 2019-12-31 11:19:54 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
typedef struct node
{
    char num[11],name[15],address[20],city[15],etp[20];
    struct node *next;
}NUM;


struct NUM *num_list[19];

int hash(char num[])
{
    int i,k=0;
    for(i=0;num[i]!='\0';i++)
    {
        k=10*k+num[i]-48;   //字符转化为数字
    }
    k=(k%19);       //除余法求散列地址
    return k;
}//除留余数法处理电话号码


//创建
void create()
{
    struct node *p1;
    int k1,m=0;
    while(m==0)
    {
     printf("请输入你想添加人的信息:电话 姓名 地址 城市 邮箱,\n");
     p1=(struct node *)malloc(sizeof(struct node));
     scanf("%s",p1->num);
     scanf("%s",p1->name);
     scanf("%s",p1->address);
     scanf("%s",p1->city);
     scanf("%s",p1->etp);
     k1=hash(p1->num);//用num数组值作为参数传递给哈希函数得到k1
     p1->next=num_list[k1];//將k1得到的值作为数组的储存地址赋值给头结点的下一个节点
     num_list[k1]=p1;//再將p1的数据传递给数组,故p1可以释放作为下一个节点产生
     printf("结束请按1,再次输入请按0\n");
     scanf("%d",&m);
    }
    printf("通讯表已经创建\n");
}


//添加
void add()
{
    char num[11],name[15],address[20],city[15],etp[20];
    struct node *p1;
    int k1;
    printf("请输入新添加的人的信息:电话 姓名 地址 城市 邮箱\n");
     p1=(struct node *)malloc(sizeof(struct node));
     scanf("%s%s%s%s%s",num,name,address,city,etp);
    strcpy(p1->num,num);
    strcpy(p1->name,name);
    strcpy(p1->address,address);
    strcpy(p1->city,city);
    strcpy(p1->etp,etp);
    k1=hash(p1->num);
    p1->next=num_list[k1];
    num_list[k1]=p1;

    printf("ok\n");
}



//查找
void search()
{
    char num[11];
    int k1;
    int find=0;
    struct node *f;
        printf("请输入查询人的电话号码:");
        scanf("%s",num);
        k1=hash(num);
        f=num_list[k1];
        while(f!=NULL)
        {
            if(strcmp(f->num,num)==0)
            {
                printf("所要查找的联系人信息 :num:%s name:%s address:%s city:%s etp:%s\n",f->num,f->name,f->address,f->city,f->etp);
                find=1;
            }
            f=f->next;
        }
        if(find=0)
            printf("此联系人没有找到!");
}


//主函数菜单   
void main()
{
    int i;
    char x;
    for(i=0;i<19;i++)
    {
        num_list[i]=NULL;
    }
    while(1)
    {
//                    system("cls");
                    printf("\n");
                printf("★★★★★★★★★通讯录★★★★★★★★★\n");
                printf("★◆----------------------------------◆★\n");
                printf("★|       1.建立       |★\n");
                printf("★|                 |★\n");
                printf("★|       2.查找       |★\n");
                printf("★|                 |★\n");
                printf("★|       3.添加       |★\n");
                printf("★|                 |★\n");
                printf("★|       4.结束       |★\n");
                printf("★◆----------------------------------◆★\n");
                printf("★★★★★★★★★★★★★★★★★★★★★\n");

//        x=getchar();
        scanf("%s",&x);
        switch(x)
        {
            case '1': create();break;
            case '2': search();break;
            case '3': add();break;
            case '4': return;
            default:printf("请重新输入;\n");
        }
    }
}
最佳答案
2019-12-31 22:51:24
第一:
  1. typedef struct node
  2. {
  3.     char num[11],name[15],address[20],city[15],etp[20];
  4.     struct node *next;
  5. }NUM;
复制代码

电话号码的长度你只给了11位,只能容纳10位数字,但正常手机号码有11位,考虑国家代码有14位。座机+区号更是能达到15位。
正常输入手机号会溢出
你其他的字符串也过短,现在电脑真的不差那点内存,加个0我觉得都是合适的。

第二:
  1. int hash(char num[])
  2. {
  3.     int i,k=0;
  4.     for(i=0;num[i]!='\0';i++)
  5.     {
  6.         k=10*k+num[i]-48;   //字符转化为数字
  7.     }
  8.     k=(k%19);       //除余法求散列地址
  9.     return k;
  10. }//除留余数法处理电话号码
复制代码

11位手机号已经能让k的值出现整数溢出。如果只是溢出,不会出现问题(只要同样的字符串得到同样的结果),但溢出后,k可能成为负数,对19取余数仍然是负数,
返回的hash值也会是负数。
要修改的话,k可以直接设置位unsigned int,如果对溢出进行处理是更好的方案。

第三
  1.   if(find=0)
复制代码

“=”改成“==”

查询.png
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2019-12-31 14:27:01 | 显示全部楼层
k1=hash(num)
同一个号码  hash出来的值不一样   
你可以打印看下
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-12-31 22:51:24 | 显示全部楼层    本楼为最佳答案   
第一:
  1. typedef struct node
  2. {
  3.     char num[11],name[15],address[20],city[15],etp[20];
  4.     struct node *next;
  5. }NUM;
复制代码

电话号码的长度你只给了11位,只能容纳10位数字,但正常手机号码有11位,考虑国家代码有14位。座机+区号更是能达到15位。
正常输入手机号会溢出
你其他的字符串也过短,现在电脑真的不差那点内存,加个0我觉得都是合适的。

第二:
  1. int hash(char num[])
  2. {
  3.     int i,k=0;
  4.     for(i=0;num[i]!='\0';i++)
  5.     {
  6.         k=10*k+num[i]-48;   //字符转化为数字
  7.     }
  8.     k=(k%19);       //除余法求散列地址
  9.     return k;
  10. }//除留余数法处理电话号码
复制代码

11位手机号已经能让k的值出现整数溢出。如果只是溢出,不会出现问题(只要同样的字符串得到同样的结果),但溢出后,k可能成为负数,对19取余数仍然是负数,
返回的hash值也会是负数。
要修改的话,k可以直接设置位unsigned int,如果对溢出进行处理是更好的方案。

第三
  1.   if(find=0)
复制代码

“=”改成“==”

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-5-13 20:38

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表