ホームページ  >  に質問  >  本文

c++ - 做一个电话号码本,用姓名和电话号码建立两个哈希表,进行查找,添加等操作,不知道自己的代码哪里错了,求助~

#include<iostream>
#include<string.h>
#define max 40
using namespace std;

struct User/*电话薄结构*/
{
    char name[8];
    char tel[11];
    char add[20];
    User *next;
}user;
struct Node/*哈希表结构*/
{
    User user;
    Node *next;
};

int user_num;
Node *hashtable1[max];
Node *hashtable2[max];

int hashname(char *name)//按名字建立哈希表
{
    int sum = 0;
    for (int i = 0; i < 8; i++)
    {
        sum = sum + name[i];
    }
    return sum % 17;
}

int hashtel(char *tel)//按号码建立哈希表
{
    int sum = 0;
    for (int i = 0; i < 11; i++)
    {
        sum = sum + tel[i];
    }
    return sum % 17;
}

void add_record(char *name, char *tel,char *add )//添加一个记录
{
    int key1 = hashname(name);
    Node *node1 = new Node;
    strcpy_s(node1->user.name, name);
    strcpy_s(node1->user.tel, tel);
    strcpy_s(node1->user.add, add);
    node1->next = hashtable1[key1];
    hashtable1[key1] = node1;
    int key2 = hashname(tel);
    Node *node2 = new Node;
    strcpy_s(node2->user.name, name);
    strcpy_s(node2->user.tel, tel);
    strcpy_s(node2->user.add, add);
    node2->next = hashtable2[key2];
    hashtable2[key2] = node2;
}

void QueryByName(char *name)//按姓名查找
{
    int key1 = hashname(name);
    Node *p = hashtable1[key1];
    while (p != NULL)
    {
        if (strcmp(name, p->user.name)==0);
        {
            cout << p->user.name << "_" << p->user.add << "_" << p->user.tel << endl;
            break;
        }
        p = p->next;
    }
    cout << "NULL" << endl;
}

void QueryByTel(char *tel)//按电话号码查找
{
    int key2 = hashtel(tel);
    Node *p = hashtable1[key2];
    while (p != NULL)
    {
        if (strcmp(tel, p->user.tel) == 0);
        {
            cout << p->user.name << "_" << p->user.add << "_" << p->user.tel << endl;
            break;
        }
        p = p->next;
    }
    cout << "NULL" << endl;
}

int main()
{
    int opt;
    char name[8], tel[11], add[20];
    memset(hashtable1, 0, sizeof(hashtable1));
    memset(hashtable2, 0, sizeof(hashtable2));
    cout << "系统初始化:请输入用户的个数" << endl;
    cin >> user_num;
    cout << "请输入用户的姓名、地址、电话号码:" << endl;
    for (int i = 0; i < user_num; i++)
    {
        cin >> name >> add >> tel;
        add_record(name, tel, add);
    }
    cout << "系统初始化完毕!" << endl;
    while (1)
    {
        cout << "请选择要进行的操作:" << endl;
        cout << "0:增加一条记录" << endl;
        cout << "1:根据输入的姓名搜索记录并输出" << endl;
        cout << "2:根据输入的电话搜索记录并输出" << endl;
        cout << "3:根据姓名查找表输出全部记录" << endl;
        cout << "4:根据电话查找表输出全部记录" << endl;
        cout << "5:退出" << endl;
        cin >> opt;
        switch (opt)
        {
        case 0:
            cin >> name >> add >> tel;
            add_record(name, tel, add);
            break;
        case 1:
            cin >> name;
            QueryByName(name);
            break;
        case 2:
            cin >> tel;
            QueryByTel(tel);
            break;
        case 3:
        {
              int key1 = 0;
              Node *p = hashtable1[key1];
              while (p != NULL)
              {
                 cout << p->user.name << "_" << p->user.add << "_" << p->user.tel << endl;
                  p = p->next;
              }
              break;
        }
            
        case 4:
        {
              int key2 = 0;
              Node *p2 = hashtable2[key2];
              while (p2 != NULL)
              {
                  cout << p2->user.name << "_" << p2->user.add << "_" << p2->user.tel << endl;
                  p2 = p2->next;
              }
              break;
        }
        case 5:
            break;
        default:
            cout << "请输入0-5之间的数字!" << endl;
            break;
        }
    }
    return 0;

}
![图片描述][1]

PHPzPHPz2714日前870

全員に返信(2)返信します

  • 黄舟

    黄舟2017-04-17 13:10:23

    编译器问题,MinGW下把strcpy_s 改成strcpy,貌似strcpy_s 是VS下的
    --更新--
    void QueryByName(char *name),无论是否查询成功都会输出一个NULL,解决方法,第一种在函数内部设立一个bool型的变量做标志,第二种,找到后直接return

    其次有一个问题,第二个选项,你添加纪录的时候,编码用的是hashname编码(也就是你Name,Tel,Add全部都是放在了以Name做索引的那个空间),而你在QueryByTel 里面确实用hashtel 进行解码,对应不来啊。

    --12.5更新--
    你说的改法也可以,但我建议这样

    void QueryByName(char *name)//按姓名查找
    {
     int key1 = hashname(name);
     Node *p = hashtable1[key1];
     while (p != NULL)
     {
      if (strcmp(name, p->user.name)==0)
      {
        cout << p->user.name << "_" << p->user.add << "_" << p->user.tel << endl;
        return;
       }
       p = p->next;
      }
     cout << "NULL" << endl;
    }
    
    

    或者

    bool QueryByName(char *name,Node *&result)//按姓名查找
    {
        int key1 = hashname(name);
        Node *p = hashtable1[key1];
        while (p != NULL)
        {
            if (strcmp(name, p->user.name)==0);
            {
                result = p;
                return true;
            }
            p = p->next;
        }
        return false;

    }

    然后再在主函数里用if判断,是否输出NULL还是reult的成员值

    至于你说说建立了两个哈希表的应该不会混乱的问题
    你的确是建立了两个哈希表,可是你在QueryByTel(char tel)*里是这么写的

    Node *p = hashtable1[key2];

    你访问的还是第一个用名字建立索引的哈希表,应该是

    Node *p = hashtable2[key2];
    

    还有在add_record(char name, char tel,char add )里面

    int key2 = hashname(tel);

    按照你的意思应该是

    int key2 = hashntel(tel);
    

    如果觉得有所帮助,希望你能点一个赞,新人需要点声望,谢谢。

    返事
    0
  • PHP中文网

    PHP中文网2017-04-17 13:10:23

    能给个完整版么?给个邮箱 540746963@qq.com 谢谢

    返事
    0
  • キャンセル返事