浙大数据结构:11-散列4 Hashing - Hard Version

news/2024/10/16 22:18:56 标签: 数据结构, 哈希算法, 算法

这道题主要在于思路,感觉像个模拟题,用到了线性探测的算法
机翻
在这里插入图片描述

1、条件准备

visit数组看这个位置有没有放进来数,num存非负整数,s存未到放入时机的数。
answer存答案。n为总共数量。

#include <iostream>
#include<set>
#include<vector>
#include<algorithm>
#include<climits>
using namespace std;
#define endl '\n'

int visit[1005];
vector<int> num;
set<int> s;
vector<int> answer;
int n;

2、主函数

先输入存入Hash,也就是放原始哈希表,然后调用init函数,再建立answer数组,最后输出。

int main()
{
  std::ios::sync_with_stdio(false);
  cin.tie(0);
  cout.tie(0);
   cin>>n;
  vector<int> Hash(n);
  init(Hash,num);
  insertanswer(Hash);
   for(int i=0;i<answer.size()-1;i++)
      cout<<answer[i]<<' ';
   cout<<answer[answer.size()-1];
  return 0;
}

3、init函数

初始化Hash数组,把非负整数放进num数组中,然后排序,因为我们要数尽可能小的优先输出,所以要从小到大进行判断

void init(vector<int>&Hash,vector<int>&num)
{
  for(int i=0;i<n;i++)
  {
    cin>>Hash[i];
    if(Hash[i]>=0)
     num.push_back(Hash[i]);
  }
  sort(num.begin(),num.end());
}

4、initanswer函数

遍历num数组,看能不能直接放入哈希表,即调用inserthash函数,如果不能就把数放进set中备用。
当我们遍历到后面某个数时,看看set中的数能不能插入哈希表,因为输出是多种可能数小的先输出,所以遍历set数组直到里面的数都不能放入哈希表,因为set里面的数比当前数大,再来判断当前数能否放入

void insertanswer(vector<int>& Hash)
{

  for(int i=0;i<num.size();i++)
  {
    while(setinsert(Hash,num[i]));
    if(inserthash(Hash,num[i]))
      answer.push_back(num[i]);
    else
       s.insert(num[i]);
  }
  while(s.size())
    setinsert(Hash,INT_MAX);
  
}

5、inserthash函数

先算出应该放入的下标,若这个下标对应的数不为当前数,则下标加1再取模。如果该位置的数还没放进来,说明当前数此时放早了,还不能放进来,返回0.
如果当前数与哈希表当前位置一样,则return 1,否则0.

bool inserthash(vector<int> &Hash,int elem)
{
     int idx=elem%n;
     while(Hash[idx]!=elem)
     {
        if(visit[idx]==0)return 0;
        idx=(idx+1)%n;
     }
     if(elem==Hash[idx])
    {visit[idx]=1; return 1;}
     return 0;
}

6、setinsert函数

先把数都放进数组里,然后循环判断,如果不能放就继续,能放就放,并删除该元素,返回1.
都不能放返回0

bool setinsert(vector<int>& Hash,int up)
{
    vector<int> t(s.begin(),s.end());
    for(int i=0;i<t.size();i++)
    {
       int elem=t[i];
      if(inserthash(Hash,elem)==0||elem>up)continue;
      s.erase(elem);
      answer.push_back(elem);
      return 1;
    }
    return 0;
}

7、总结

感觉像个模拟题,算法方面性不强,偏思维题+推导
完整代码如下

#include <iostream>
#include<set>
#include<vector>
#include<algorithm>
#include<climits>
using namespace std;
#define endl '\n'

int visit[1005];
vector<int> num;
set<int> s;
vector<int> answer;
int n;

bool inserthash(vector<int> &Hash,int elem)
{
     int idx=elem%n;
     while(Hash[idx]!=elem)
     {
        if(visit[idx]==0)return 0;
        idx=(idx+1)%n;
     }
     if(elem==Hash[idx])
    {visit[idx]=1; return 1;}
     return 0;
}
bool setinsert(vector<int>& Hash,int up)
{
    vector<int> t(s.begin(),s.end());
    for(int i=0;i<t.size();i++)
    {
       int elem=t[i];
      if(inserthash(Hash,elem)==0||elem>up)continue;
      s.erase(elem);
      answer.push_back(elem);
      return 1;
    }
    return 0;
}

void init(vector<int>&Hash,vector<int>&num)
{
  for(int i=0;i<n;i++)
  {
    cin>>Hash[i];
    if(Hash[i]>=0)
     num.push_back(Hash[i]);
  }
  sort(num.begin(),num.end());
}
void insertanswer(vector<int>& Hash)
{

  for(int i=0;i<num.size();i++)
  {
    while(setinsert(Hash,num[i]));
    if(inserthash(Hash,num[i]))
      answer.push_back(num[i]);
    else
       s.insert(num[i]);
  }
  while(s.size())
    setinsert(Hash,INT_MAX);
  
}
int main()
{
  std::ios::sync_with_stdio(false);
  cin.tie(0);
  cout.tie(0);
   cin>>n;
  vector<int> Hash(n);
  init(Hash,num);
  insertanswer(Hash);
   for(int i=0;i<answer.size()-1;i++)
      cout<<answer[i]<<' ';
   cout<<answer[answer.size()-1];
  return 0;
}


http://www.niftyadmin.cn/n/5708621.html

相关文章

zookeeper kafka集群配置

一.下载安装包 地址&#xff1a;https://download.csdn.net/download/cyw8998/16579797 二.配置文件 zookeeper.properties dataDir/data/kafka/zookeeper_data/zookeeper # the port at which the clients will connect clientPort2181 # disable the per-ip limit on the…

Vant 日期时间组件拓展

基于 "vant": "^4.8.3", 效果图 <template><!-- 弹出层 --><van-popupv-model:show"isPicker"position"bottom"><van-pickerref"picker":title"title"v-model"selectedValues"…

关于移动通信网络中各个组成部分的基础入门

移动通信网络的详细组成 移动通信网络是一个复杂的系统&#xff0c;由多个层次和组件构成&#xff0c;每个组件都有其特定的功能和作用。以下是对移动通信网络各个组成部分的详细阐述&#xff1a; 1. 终端设备&#xff08;End User Devices&#xff09; 定义&#xff1a; 终…

【返璞归真】-泰勒展开式

泰勒展开式是将一个函数在某点附近展开为一个无穷级数的方式&#xff0c;其原理是通过函数在该点的导数来近似函数值。公式为&#xff1a; f ( x ) f ( a ) f ′ ( a ) ( x − a ) f ′ ′ ( a ) 2 ! ( x − a ) 2 f ′ ′ ′ ( a ) 3 ! ( x − a ) 3 ⋯ f(x) f(a) f(a)…

架构设计笔记-11-未来信息综合技术

知识要点 云原生架构原则包括&#xff1a;服务化原则、弹性原则、可观测原则、韧性原则、所有过程自动化原则、零信任原则和架构持续演进原则。 区块链是一种按照时间顺序将数据区块以顺序相连的方式组合成的一种链式数据结构&#xff0c;并以密码学方式保证的不可篡改和不可…

Vue3使用element plus时el-menu导航选中后刷新页面及修改URL无法保持当前选中状态问题

问题1: 在使用element plus的el-menu菜单导航时&#xff0c;发现选中后刷新高亮部分无法保持当前选择状态 解决方法: 因为刷新页面后el-menu的:default-active"activeIndex"被刷新&#xff0c;无法记录所以导致高亮部分无法保持选择状态 所以为了保持下来这个值&…

mysql 09 独立表空间结构

表空间中的页实在是太多了&#xff0c;为了更好的管理这些页面&#xff0c;设计 InnoDB 的大叔们提出了 区 &#xff08;英文名&#xff1a; extent &#xff09;的概念。对于16KB的页来说&#xff0c;连续的64个页就是一个 区 &#xff0c;也就是说一个区默认占用1MB空间大小。…

网络爬虫-数美滑块验证码

仅供研究学习使用。 今天带来的是数美滑块验证码的逆向 目标站 --> 传送门 解决此类验证码 首先要解决滑动距离的判定 无论是使用selenium还是使用协议的方式来破解 都绕不开滑动距离的识别 滑动距离可以参考以前我博客上的方式&#xff0c;或者找一找开源的一些算法&am…