数组中重复的数字(哈希表)

本人小白,仅供自己学习参考!

使用STL库的vector 和 unordered_map

先巩固一下基础知识!!!

1.创建一个vector并直接赋值

std::vector<int> b{ 1,2,3,4,5,6,7,1 };

2.用数组给向量赋值

int a[6]={1,2,3,4,5,6};

 vector<int>c(a,a+4);//把数组a的前四个数据赋值给向量c

3.定义一个全是1的向量

vector<int>a(10,1);

4.用向量b给向量a赋值,向量a中的值完全等于向量b中的值

vector<int>a(b);

5.将向量b的前三个数值赋值给向量a

vector<int>a(b.begin() , b.begin()+3 );

 vector对象的常用内置函数使用(举例说明)

#include<vector>
vector<int> a,b;
//b为向量,将b的0-2个元素赋值给向量a
a.assign(b.begin(),b.begin()+3);
//a含有4个值为2的元素
a.assign(4,2);
//返回a的最后一个元素
a.back();
//返回a的第一个元素
a.front();
//返回a的第i元素,当且仅当a存在
a[i];
//清空a中的元素
a.clear();
//判断a是否为空,空则返回true,非空则返回false
a.empty();
//删除a向量的最后一个元素
a.pop_back();
//删除a中第一个(从第0个算起)到第二个元素,也就是说删除的元素从a.begin()+1算起(包括它)一直到a.begin()+3(不包括它)结束
a.erase(a.begin()+1,a.begin()+3);
//在a的最后一个向量后插入一个元素,其值为5
a.push_back(5);
//在a的第一个元素(从第0个算起)位置插入数值5,
a.insert(a.begin()+1,5);
//在a的第一个元素(从第0个算起)位置插入3个数,其值都为5
a.insert(a.begin()+1,3,5);
//b为数组,在a的第一个元素(从第0个元素算起)的位置插入b的第三个元素到第5个元素(不包括b+6)
a.insert(a.begin()+1,b+3,b+6);
//返回a中元素的个数
a.size();
//返回a在内存中总共可以容纳的元素个数
a.capacity();
//将a的现有元素个数调整至10个,多则删,少则补,其值随机
a.resize(10);
//将a的现有元素个数调整至10个,多则删,少则补,其值为2
a.resize(10,2);
//将a的容量扩充至100,
a.reserve(100);
//b为向量,将a中的元素和b中的元素整体交换
a.swap(b);
//b为向量,向量的比较操作还有 != >= > <= <
a==b;

顺序访问vector的几种方式,举例说明

1.向向量a中添加元素

vector<int>a;
for(int i=0;i<10;++i)

{

a.push_back(i);

}

2.从文件中读取元素向向量中添加

ifstream in("data.txt");
vector<int>a;
for(int i; in>>i)

{

a.push_back(i);

}

3 从向量中读取元素
3.1通过下标方式获取

int a[6]={1,2,3,4,5,6};
vector<int>b(a,a+4);
for(int i=0; i<=b.size()-1; ++i)

{

cout<<b[i]<<endl;

}

3.2通过迭代器方式读取

int a[6]={1,2,3,4,5,6};
 vector<int>b(a,a+4);
 for(vector<int>::iterator it = b.begin(); it != b.end(); it++)

{

cout<<*it<<"  ";

}

4 map
优点:有序性,这是map结构最大的优点,其元素的有序性在很多应用中都会简化很多的操作。红黑树,内部实现一个红黑书使得map的很多操作在lgn的时间复杂度下就可以实现,因此效率非常的高。
缺点:空间占用率高,因为map内部实现了红黑树,虽然提高了运行效率,但是因为每一个节点都需要额外保存父节点,孩子节点以及红/黑性质,使得每一个节点都占用大量的空间
适用处:对于那些有顺序要求的问题,用map会更高效一些。

5 unordered_map

优点:内部实现了哈希表,因此其查找速度是常量级别的。
缺点:哈希表的建立比较耗费时间
适用处:对于查找问题,unordered_map会更加高效一些,因此遇到查找问题,常会考虑一下用unordered_map

特性

  1. 关联性:通过key去检索value,而不是通过绝对地址(和顺序容器不同)
  2. 无序性:使用hash表存储,内部无序
  3. Map : 每个值对应一个键值
  4. 键唯一性:不存在两个元素的键一样
  5. 动态内存管理:使用内存管理模型来动态管理所需要的内存空间

6 Hashtable和bucket

由于unordered_map内部采用的hashtable的数据结构存储,所以,每个特定的key会通过一些特定的哈希运算映射到一个特定的位置,我们知道,hashtable是可能存在冲突的(多个key通过计算映射到同一个位置),在同一个位置的元素会按顺序链在后面。所以把这个位置称为一个bucket是十分形象的(像桶子一样,可以装多个元素)。

这里写图片描述

所以unordered_map内部其实是由很多哈希桶组成的,每个哈希桶中可能没有元素,也可能有多个元素。

unordered_map实现原理
unordered_map内部是一个hash_table,是由一个大vector,vector的每个元素节点挂一个链表来实现的(就是开链法实现的哈希桶)。

unordered_map的插入过程:
1.得到key值
2.通过hash函数得到hash值,即为对应的bucket索引号
3.存放key和value在bucket内。

unordered_map的查询过程:
1.得到key值
2.通过hash函数得到hash值,即为对应的bucket索引号
3.比较buckut内元素key值是否和要查找的key值相等,若都不相等则没找到
4.若相等则取出相等key值对应的value。
 

 找到数组中相同的元素

方法一:哈希表

​
#include<iostream>
#include<vector>  //向量头文件
#include<unordered_map>//无序字典头文件

class Solution {

public:
    void findRepeatNumber(std::vector<int>& nums) {
        std::unordered_map<int, bool> map;
        map.reserve(nums.size());
        for (int i = 0; i < nums.size(); ++i) {    //遍历     
            if (map.find(nums[i]) == map.end()) {  //如果找不到该元素,就把该元素插入
                map.insert({ nums[i] , true });
            }
            else {
                std::cout << nums[i]<<std::endl;  //如果能找到该元素,就是重复的,输入它
            }
        }
    }
};
void main()
{
    int a[7] = { 3,2,2,4,4,5,6,};
    std::vector<int> b(a,a+7);   //用数组给vector向量赋值
  //  for (int i = 0; i <= b.size() - 1; ++i) { std::cout << b[i] << std::endl; }
    Solution cc;
    cc.findRepeatNumber(b);

}

​

方法二:遍历对比

遍历两次,取数组中每一个数与数组后面的数进行对比

#include<iostream>
#include<vector>


class Solution {

public:
  
    void findRepeatNumber(std::vector<int>& nums) {
        for (int i = 0; i < nums.size(); i++) {
            for (int j = i+1; j < nums.size(); j++) {
                if (nums[i] == nums[j]) { //遍历两次,取数组中每一个数与数组后面的数进行对比
                    std::cout << nums[j] << std::endl;
                }
            }
        }
    }
};
void main()
{
    std::vector<int> b{ 1,2,3,4,1,1,2 ,3,44,5,5};
    //for (int i = 0; i < b.size() ; i++) { std::cout << b[i] << std::endl; }
    Solution cc;
    cc.findRepeatNumber(b);
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值