博客作业05--查找

1.学习总结

1.1查找的思维导图

1.2 查找学习体会

我还是来谈谈STL容器之map中查找如何用的,从百度获取的知识可知,我目前知道的查找方式有两种,一种是map.find(关键字),还有一种是map.count(关键字),1.我尝试过cout<<map.find(关键字),发现会提示错误,说明这不是一种可以输出类型的东西它返回的一个迭代器,当数据出现时,它返回数据所在位置的迭代器,如果map中没有要查找的数据,它返回的迭代器等于end函数返回的迭代器,即查找不到的话,满足map.find(number)==map.end(),至于这个迭代器是什么呢?百度是这样解释的:迭代器类似于指针类型,它也提供了对对象的间接访问。2.用count函数来判定关键字是否出现,其缺点是无法定位数据出现位置,由于map的特性,一对一的映射关系,就决定了count函数的返回值只有两个,要么是0,要么是1,出现的情况,当然是返回1了cout<<map.cout(关键字)验证,也确实如此。

2.PTA实验作业ma

2.11题目:6-3 二叉搜索树中的最近公共祖先

2.12 设计思路(伪代码或流程图)

int LCA( Tree T,  int u, int v )
{
        定义Tree BST=T,BRT=T
        if(T不为空)
        {
            通过BST遍历树查找u,如果BST为空,返回ERROR

           通过BRT遍历树查找v,如果BRT为空,返回ERROR

            if(树中值大于u同时小于v或者小于u同时大于v) 
            {
                找到最近公共祖先,返回树中的值
             } 

            else if(树中值同时大于u和v) 
             {
                递归进右子树寻找最近公共祖先
                return LCA(T->Right,u,v)
             } 
             else if(树中值同时小于u和v)
             {
                递归进左子树寻找最近公共祖先
                return LCA(T->Left,u,v)
             }
}

2.13代码截图

2.14 PTA提交列表说明

部分正确原因:把u或v不在树中的情况放在最后面考虑,导致输入1和9先满足了下图中的条件(此时的9不在树中),也能得出最近公共祖先6的答案,导致答案错误。

解决方案:应该将u或v不在树中的情况放在最前面判断,通过遍历树来查找元素是否存在于该树中,存在继续运行程序,不存在则返回ERROR。

2.21题目:7-1 QQ帐户的申请与登陆

2.22 设计思路(伪代码或流程图)

#include<iostream>  
#include<map>     使用map
#include<string>  

定义map<string,string>QQ
for i=0 to count 
{
       输入命令order以及账号number和密码code,number作为map的关键字,code作为关键字对应的内容
       if(order=='N')
        {
            如果map容器QQ中找不到number,注册账号QQ[number]=code,输出New: OK
            否则输出ERROR: Exist
        }
        if(order=='L')
        {
            如果map容器QQ中找不到number,输出ERROR: Not Exist
            或者如果账号密码匹配,输出Login: OK
            或者如果密码错误,输出ERROR: Wrong PW
         }
}

2.23代码截图

2.24PTA提交列表说明

此题虽然一遍过,但是调试过程中发现了一些好东西哦!


原本的判断方式如图2所示,是三个if 语句,答案是错误的,有趣的是第一个账号我并没有输入进map中,但是下一次命令输入跳出下图红框中的ERROR: Exist,说明这个账号已经记录在map中,但是我并没有QQ[number]=code类似的输入,这是为什么呢?我百度了一下,原来就算之前关键字不存在于map中,只要经过[](就是QQ[number]中的[]),就会被map记录,所以我之前3个if语句时,下图红框中的判断语句就将number记录于map中,而题目本意并不想记录,导致答案错误,后来改为图1中if语句与else if语句连用,避免了此类错误,成功解决

2.31题目:7-2 航空公司VIP客户查询

2.32 设计思路(伪代码或流程图)

#include<iostream>  
#include<stdio.h>
#include<map>  
#include<string>  
using namespace std
int main
{
    定义map<string,int>airplan
    for i=0 to count
    {
        输入身份证number和飞行里程mileage
        如果map容器airplan中找不到number,则初始化airplan[number]=0;
        如果飞行里程mileage小于最低里程K,则让行里程mileage等于K
        最后飞行里程求和
     }
     while(count--)
    {
        输入身份证number
        如果map容器airplan中存在number作为关键字的记录,则输出对应的内容
        否则输出No Info
     }
}

2.33代码截图

2.34PTA提交列表说明


部分错误:运行超时,听老师说但注意不能cout,string,过不了大数据测试点,所以map定义仍然是string类型,但是输入的身份证number定义为字符数组,长度为19,为number[19],输入用scanf("%s",number),输出用printf,发现答案正确

3.截图本周题目集的PTA最后排名

3.1 PTA排名(截图带自己名字的排名)

3.2 我的总分:145

4. 阅读代码

//采用除数取留法确定地址,利用线性开放地址法处理冲突问题
#include <stdio.h>  
#include <stdlib.h>  
#include <io.h>  
#include <math.h>  
#include<time.h>  
  
#define HASHSIZE 15  
#define NULLKEY -32768  
  
typedef struct  
{  
    int *elem; //数据元素存储地址  
    int count;//当前元素个数  
}HashTable;  
int L = 0; //表的长度  
  
bool init(HashTable *hashTable)//哈希表的初始化  
{  
    int i;  
    L = HASHSIZE;  
    hashTable->elem = (int*)malloc(L*sizeof(int));//申请内存  
    hashTable->count = L;  
    for (i = 0; i < L; i++)  
    {  
        hashTable->elem[i]=NULLKEY;  
    }  
    return true;  
}  
  
//哈希函数,除留余数法,最常用的哈希函数,还有其它的。  
int Hash(int data)  
{  
    return data%L;  
}  
  
void insert( HashTable *hashTable, int data)  
{  
    int Addr = Hash(data);//求哈希地址  
    while (hashTable->elem[Addr] != NULLKEY)//求得地址不是初始化时的空,则表示有元素已经插入,会有冲突  
    {  
        Addr = (Addr + 1) % L;//开放地址线性探测,还可以二次探测  
    }  
    hashTable->elem[Addr] = data;  
}  
  
int  find(HashTable *hashTable, int data)  
{  
    int Addr = Hash(data);  
    while (hashTable->elem[Addr] != data)  
    {  
        Addr = (Addr + 1) % L;  
        if (hashTable->elem[Addr] == NULLKEY || Addr == Hash(data))  //找到空的指针或者遍历一遍回到起点说明找不到元素 
            return 0;  
    }  
    return Addr;  
}  
  
void display(HashTable *hashTable)  
{  
    int i;  
    printf(".........结果展示.........\n");  
    for (i = 0; i < hashTable->count; i++)  
    {  
        printf("%d\n", hashTable->elem[i]);  
    }  
}  
  
void main()  
{  
    int i, j, result, x;  
    HashTable hashTable;  
    int arr[HASHSIZE];  
    printf("请输入少于15个,初始化哈希表的元素:\n");  
    for (j = 0; j < HASHSIZE; j++)  
    {  
        scanf("%d", &arr[j]);  
    }  
    init(&hashTable);  //初始化哈希表 
    for (i = 0; i < HASHSIZE; i++)  
    {  
        insert(&hashTable, arr[i]);  
    }  
    display(&hashTable);  
    printf("请输入你要查找的元素:\n");  
    scanf("%d", &x);  
    result = find(&hashTable, x);  
    if (result)  
        printf("查找元素%d在哈希表中的位置为%d\n",x,result);  
    else   
        printf("没找到!\n");  
}  

自己认为还对哈希表的操作集还不是很熟练,所以找了一篇关于哈希表查找的源代码,跟PTA上哈希表的操作有不同之处,个人感觉这种比较好理解,用来加深自己对哈希表操作的印象

这是一个很简单的哈希表查找的代码,其中使用了init()[初始化哈希表] 、Hash()[除留余数法]、insert()[哈希表元素插入]、find()[查找元素]等函数,现在来逐个介绍各个函数的实现过程。

1.init函数中先对哈希表指针申请内存,接着将哈希表每个元素的地址初始化为空。

2.Hash函数中直接利用公式data%L进行计算并返回值

3.insert函数中先利用Hash函数求出下标。当下标对应的指针为空时,插入,否则利用线性探查法Addr = (Addr + 1) % L,找到为空的指针为止,然后插入。

4.find函数中先利用Hash函数求出要查找元素的下标,在找不到元素的情况下,遍历哈希表,直到找到空的指针或者遍历一遍回到起点,这都说明找不到该元素,返回0,否则返回下标

5. 代码Git提交记录截图

posted @ 2018-05-26 22:21  朱杰伟  阅读(205)  评论(0编辑  收藏  举报