| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 1239 人关注过本帖
标题:求解程序在读取第一行数据的时候正常,读取后面的数据时显示乱码
只看楼主 加入收藏
Christan
Rank: 1
等 级:新手上路
帖 子:2
专家分:0
注 册:2020-3-12
收藏
 问题点数:0 回复次数:1 
求解程序在读取第一行数据的时候正常,读取后面的数据时显示乱码
这个程序(思路注释的很清楚)
在显示搜索结果的时候,查找第一个搜索结果时不会有乱码,但是在查找之后的搜索结果时就会有乱码,找了好久没找到错误,求大神帮忙,谢谢



// MyHashTable.cpp : 定义控制台应用程序的入口点。  
////设计哈希表实现电话号码查询系统  
//说明:一是从文件old.txt中读取的数据自己在程序运行前建立



#include<fstream>  
#include<iostream>  
#include <string>  
using namespace std;

const int D[] = { 3,5,8,11,13,14,19,21 };//预定再随机数  
const int HASH_MAXSIZE = 50;//哈希表长度  

//记录信息类型  
class DataInfo
{
public:
    DataInfo();//默认构造函数  
    friend ostream& operator<<(ostream& out, const DataInfo& dataInfo); //重载输出操作符  
    //friend class HashTable;  

//private:  
    string name;//姓名  
    string phone;//电话号码  
    string address;//地址   
    char sign;//冲突的标志位,'1'表示冲突,'0'表示无冲突  
};

DataInfo::DataInfo() :name(""), phone(""), address(""), sign('0')
{

}

ostream& operator<<(ostream& out, const DataInfo& dataInfo) //重载输出操作符  
{
    cout << "姓名:" << dataInfo.name << "   电话:" << dataInfo.phone
        << "    地址:" << dataInfo.address << endl;
    return out;
}

//存放记录的哈希表类型  
class HashTable
{
public:
    HashTable();//默认构造函数  
    ~HashTable();//析构函数  
    int Random(int key, int i);// 伪随机数探测再散列法处理冲突  
    void Hashname(DataInfo *dataInfo);//以名字为关键字建立哈希表      
    int Rehash(int key, string str);// 再哈希法处理冲突   注意处理冲突还有链地址法等  
    void Hashphone(DataInfo *dataInfo);//以电话为关键字建立哈希表         
    void Hash(int n);// 建立哈希表      
    int Findname(string name);// 根据姓名查找哈希表中的记录对应的关键码  
    int Findphone(string phone);// 根据电话查找哈希表中的记录对应的关键码  
    void Outhash(int key);// 输出哈希表中关键字码对应的一条记录  

//private:  
    DataInfo *value[HASH_MAXSIZE];
    int length;//哈希表长度  
};

HashTable::HashTable() :length(0)//默认构造函数  
{
    //memset(value, NULL, HASH_MAXSIZE*sizeof(DataInfo*));  
    for (int i = 0; i < HASH_MAXSIZE; i++)
    {
        value[i] = new DataInfo();
    }
}

HashTable::~HashTable()//析构函数  
{
    delete[] * value;
}




int HashTable::Random(int key, int i)// 伪随机数探测再散列法处理冲突  
{//key是冲突时的哈希表关键码,i是冲突的次数,N是哈希表长度  
    //成功处理冲突返回新的关键码,未进行冲突处理则返回-1  
    int h;
    if (value[key]->sign == '1')//有冲突  
    {
        h = (key + D[i]) % HASH_MAXSIZE;
        return h;
    }
    return -1;
}

void HashTable::Hashname(DataInfo *dataInfo)//以名字为关键字建立哈希表  
{//利用除留取余法建立以名字为关键字建立的哈希函数,在发生冲突时调用Random函数处理冲突  
    int i = 0;
    int key = 0;

    for (int t = 0; dataInfo->name[t] != '\0'; t++)
    {
        key = key + dataInfo->name[t];
    }
    key = key % 42;
    while (value[key]->sign == '1')//有冲突  
    {
        key = Random(key, i++);//处理冲突  
    }
    if (key == -1) exit(1);//无冲突  
    length++;//当前数据个数加  
    value[key]->name = dataInfo->name;
    value[key]->address = dataInfo->address;
    value[key]->phone = dataInfo->phone;
    value[key]->sign = '1';//表示该位置有值  
    //cout << value[key]->name << "  " << value[key]->phone << "  "  << value[key]->address << endl;  
}

int HashTable::Rehash(int key, string str)// 再哈希法处理冲突  
{//再哈希时使用的是折叠法建立哈希函数      
    int h;
    int num1 = (str[0] - '0') * 1000 + (str[1] - '0') * 100 + (str[2] - '0') * 10 + (str[3] - '0');
    int num2 = (str[4] - '0') * 1000 + (str[5] - '0') * 100 + (str[6] - '0') * 10 + (str[7] - '0');
    int num3 = (str[8] - '0') * 100 + (str[9] - '0') * 10 + (str[10] - '0');
    h = num1 + num2 + num3;
    h = (h + key) % HASH_MAXSIZE;
    return h;
}

void HashTable::Hashphone(DataInfo *dataInfo)//以电话为关键字建立哈希表  
{//利用除留取余法建立以电话为关键字建立的哈希函数,在发生冲突时调用Rehash函数处理冲突  
    int key = 0;
    int t;

    for (t = 0; dataInfo->phone[t] != '\0'; t++)
    {
        key = key + dataInfo->phone[t];
    }
    key = key % 42;
    while (value[key]->sign == '1')//有冲突  
    {
        key = Rehash(key, dataInfo->phone);
    }
    length++;//当前数据个数加  
    value[key]->name = dataInfo->name;
    value[key]->address = dataInfo->address;
    value[key]->phone = dataInfo->phone;
    value[key]->sign = '1';//表示该位置有值   
}



void HashTable::Outhash(int key)//输出哈希表中关键字码对应的记录  
{
    if ((key == -1) || (value[key]->sign == '0'))
        cout << "没有找到这条记录!" << endl;
    else
    {
        for (unsigned int i = 0; value[key]->name[i] != '\0'; i++)
        {
            cout << value[key]->name[i];
        }

        for (unsigned int i = 0; i < 10; i++)
        {
            cout << " ";
        }

        cout << value[key]->phone;

        for (int i = 0; i < 10; i++)
        {
            cout << " ";
        }

        cout << value[key]->address << endl;
    }
}



void HashTable::Hash(int n)//建立哈希表  
//fname是数据储存的文件的名称,用于输入数据,n是用户选择的查找方式  
//函数输入数据,并根据选择调用Hashname或Hashphone函数进行哈希表的建立  
{
    ifstream fin;
    int i;
    fin.open("1.txt");//读文件流对象  
    if (fin.fail())
    {
        cout << "文件打开失败!" << endl;
        exit(1);
    }
    while (!fin.eof())//按行读入数据  
    {
        DataInfo *dataInfo = new DataInfo();
        char* str = new char[100];
        fin.getline(str, 40, '\n');//读取一行数据  

        if (str[0] == '\0')//判断数据结束  
        {
            break;
        }

        i = 0;//记录字符串数组的下标  
        //a-z:97-122     A-Z:65-90      
        //本程序的姓名和地址都使用小写字母  
        while ((str[i] < 97) || (str[i] > 122))//读入名字  
        {
            i++;
        }

        for (; str[i] != ' '; i++)
        {
            dataInfo->name += str[i];
        }

        while (str[i] == ' ')
        {
            i++;
        }

        for (int j = 0; str[i] != ' '; j++, i++)//读入电话号码  
        {
            dataInfo->phone += str[i];
        }

        while (str[i] == ' ')
        {
            i++;
        }

        for (int j = 0; str[i] != ' '; j++, i++)//读入地址  
        {
            dataInfo->address += str[i];
        }

        if (n == 1)
        {
            Hashname(dataInfo);
        }
        else
        {
            Hashphone(dataInfo);//以电话为关键字  
        }

        delete[]str;
        delete dataInfo;
    }
    fin.close();
}

int HashTable::Findname(string name)//根据姓名查找哈希表中的记录对应的关键码  
{
    int i = 0;
    int j = 1;
    int t;
    int key = 0;

    for (key = 0, t = 0; name[t] != '\0'; t++)
    {
        key = key + name[t];
    }
    key = key % 42;
    while ((value[key]->sign == '1') && (value[key]->name != name))
    {
        key = Random(key, i++);
        j++;
        if (j >= length) return -1;
    }
    return key;
}

int HashTable::Findphone(string phone)//根据电话查找哈希表中的记录对应的关键码  
{
    int key = 0;
    int t;

    for (t = 0; phone[t] != '\0'; t++)
    {
        key = key + phone[t];
    }
    key = key % 42;
    int j = 1;
    while ((value[key]->sign == '1') && (value[key]->phone != phone))
    {
        key = Rehash(key, phone);
        j++;
        if (j >= length)
        {
            return -1;
        }
    }
    return key;
}

void main()
{
        
    int k;
    int ch;
    char *Fname;
    HashTable *ht = new HashTable;
    while (1)
    {
        system("cls");//cls命令清除屏幕上所有的文字  
        cout << "欢迎使用本系统!" << endl << endl;
        cout << "1.开始" << endl;
        cout << "0.结束" << endl;
        cout << "输入相应序号选择功能:";
        cin >> k;
        switch (k)
        {
        case 0:
            return;

        default:
            break;
        }

        do
        {
            system("cls");
            cout << " 请选择查找方式" << endl;
            cout << "1.通过姓名查找" << endl;
            cout << "2.通过电话查找" << endl;
            cout << "输入相应序号选择功能:";
            cin >> ch;
            if ((ch != 1) && (ch != 2))
                cout << "输入序号有误!" << endl;
        } while ((ch != 1) && (ch != 2));

        ht->Hash(ch);
        while (ch == 1)
        {
            int choice;
            cout << endl << "请选择功能" << endl;
            cout << "1.输入姓名查找数据" << endl;
            cout << "0.退出" << endl;
            cin >> choice;
            switch (choice)
            {
            case 1:
            {//注意此处应该加上大括号  
                int key1;
                string name;
                cout << "请输入姓名:";
                cin >> name;
                key1 = ht->Findname(name);
                ht->Outhash(key1);
            }
            break;

            default:
                cout << endl << "您的输入有误!" << endl;
            }

            if (choice == 0)
            {
                return;
            }
        }

        while (ch == 2)
        {
            int choice;
            cout << endl << "请选择功能" << endl;
            cout << "1.输入电话查找数据" << endl;
            cout << "0.退出" << endl;
            cout << "输入相应序号选择功能:";
            cin >> choice;
            switch (choice)
            {
            case 1:
            {
                int key2;
                string phone;
                cout << "请输入11位的电话号码:";

                do
                {
                    cin >> phone;
                    if (phone.length() != 11)
                    {
                        cout << "电话号码应为11位!\n请重新输入:";
                    }

                } while (phone.length() != 11);

                key2 = ht->Findphone(phone);
                ht->Outhash(key2);
            }
            break;

   

            default:
                cout << endl << "您的输入有误!" << endl;
            }

            if (choice == 0)
            {
                return;
            }
        }

        while ((ch != 1) && (ch != 2))
        {
            cout << "您的输入有误!请输入相应需要选择功能:";
        }
    }
    system("pause");
}
搜索更多相关主题的帖子: str cout int value key 
2020-03-12 09:45
Christan
Rank: 1
等 级:新手上路
帖 子:2
专家分:0
注 册:2020-3-12
收藏
得分:0 
其中用到了资源文件1.txt
1.zip (158 Bytes)
2020-03-12 09:47
快速回复:求解程序在读取第一行数据的时候正常,读取后面的数据时显示乱码
数据加载中...
 
   



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

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