en?vector和 HashTable以及insert模板

Vector 和 HashTable

2017年02月24日 11:09:43 请叫我王老魔 阅读数:329 标签: hashtable vector 更多

个人分类: java

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/woshiluoye9/article/details/56835046

其实Vector 和 HashTable现在已经很少使用了,他们是同属于一个时代的,一般我们使用ArrayList 和HashMap 而且建议使用这两个,他们两个是一个时代的。

Vector
Vector 和ArrayList的区别: Vector是线程同步的,而ArrayList不是线程同步的,其他方面的实现两个基本一样,从下面的代码可以看到,它的底层实现也是数组。

protected Object[] elementData;

vector的扩容方式:默认的扩容的大小是变为原来的二倍,如果自己定义了它增加的个数,它会按照我们要求的增长个数进行增长

// 容量的增长模式
  private void grow(int minCapacity) {
        // overflow-conscious code
        int oldCapacity = elementData.length;
        // 如果capacityIncrement>0,则每次容量增加capacityIncrement, 如果不是则容量增加 一倍 oldCapacity   
        int newCapacity = oldCapacity + ((capacityIncrement > 0) ? capacityIncrement : oldCapacity);
        if (newCapacity - minCapacity < 0)
            newCapacity = minCapacity;
        if (newCapacity - MAX_ARRAY_SIZE > 0)
            newCapacity = hugeCapacity(minCapacity);
        elementData = Arrays.copyOf(elementData, newCapacity);
    }
  • 那么capacityIncrement这个函数是什么含义呢?这是是Vector定义的数组自增大小,而且提供了一个构造函数,我们可以自己设置它增长的大小。
    public Vector(int initialCapacity, int capacityIncrement) {
        super();
        if (initialCapacity < 0)
            throw new IllegalArgumentException("Illegal Capacity: "+
                                               initialCapacity);
        this.elementData = new Object[initialCapacity];
        this.capacityIncrement = capacityIncrement;
    }

HashTable
HashMap 类与 Hashtable 大致相同,
但是Hashtable是同步的,HashMap是不同步的,
Hashtable不允许使用 null 键,HashMap允许使用 null 键,

Properties 是Hashtable的一个子类,属性类,经常被使用在配置文件中
getProperties(String key),一般读取文件的时候,都是获取字符串

获取系统的环境变量:
System.getProperties获取系统的环境变量

 

 

===========================================================================================================================================================================================================================================================================

 

 

 

C++数据结构 之 哈希表(散列表)_Hash Table

源代码只包含头文件

注:需要C++11的支持
一、哈希表

哈希表是一种高效的数据结构,能在平均时间复杂度O(n)的情况下存储与查询。它是根据关健值(key)进行访问的。存在一函数,当key传入函数之后,函数输出一个独一无二的值val,函数叫哈希函数。当给定所存储容器V大小为m时,那么输入元素所在的位置就是val % m。
当输入很多元素之后, 同一位置下就可能会存入多个元素,因而产生冲突(collision),那么这时候就需要用链接(chaining)来解决问题:使用链表将同一位置下的元素链起来。

支持的操作:
1、insert 插入元素
2、erase 删除元素
3、search 搜索元素

示意图:
哈希表
二、源代码:

#ifndef HASH_TABLE_H
#define HASH_TABLE_H

#include <vector>
#include <list>
#include <utility>
#include <stdexcept>
#include <algorithm>
#include <functional>

using std::vector;
using std::list;
using std::hash;
using std::pair;

template<typename T>
class Sgl_HashTable {
    typedef typename list<T>::iterator iterator;
public:
    Sgl_HashTable() { resize(); }
    Sgl_HashTable(const size_t &temp_bucket) {
        bucket = temp_bucket;
        elem.resize(bucket);
    }
    ~Sgl_HashTable() = default;

    size_t Hash_Val(const T &x) {
        return hash<T>()(x) % bucket;
    }

    void insert(const T &x) {
        auto Hval = Hash_Val(x);
        elem[Hval].push_back(x);
    }

    pair<size_t, iterator> search(const T &x) {
        auto Hval = Hash_Val(x);
        auto pos = find(elem[Hval].begin(), elem[Hval].end(), x);
        try {
            if (pos == elem[Hval].end()) {
                throw runtime_error("The element was not found.");
            }
        }
        catch (runtime_error &err) {
            cout << err.what() << endl;
        }

        return std::make_pair(Hval, pos);
    }

    void erase_one(const T &x) {
        auto p = search(x);
        if (p.second != elem[p.first].end()) {
            elem[p.first].erase(p.second);
        }
    }

    void erase(const T &x) {
        auto p = search(x);
        auto pos = p.second;
        if (pos != elem[p.first].end()) {
            while (pos != elem[p.first].end() && *pos == x) {
                    pos = elem[p.first].erase(pos);
            }
        }
    }

private:
    vector<list<T>> elem;
    size_t bucket = 100;
    void resize() { elem.resize(bucket); }
};

template<typename key, typename T>
class Dbl_HashTable {
    typedef typename list<pair<key, T>>::iterator iterator;
public:
    Dbl_HashTable() { resize(); }
    Dbl_HashTable(const key &temp_bucket) {
        bucket = temp_bucket;
        elem.resize(bucket);
    }

    size_t Hash_Val(const key &x) {
        return hash<T>()(x) % bucket;
    }

    void insert(const key &x1, const T &x2) {
        auto Hval = Hash_Val(x1);
        elem[Hval].push_back(std::make_pair(x1, x2));
    }

    pair<size_t, iterator> search(const key &x) {
        auto Hval = Hash_Val(x);
        auto pos = find_if(elem[Hval].begin(), elem[Hval].end(), [&](pair<key, T> temp_p)->bool {
            return temp_p.first == x;
        });
        try {
            if (pos == elem[Hval].end()) {
                throw runtime_error("The element was not found.");
            }
        }
        catch (runtime_error &err) {
            cout << err.what() << endl;
        }

        return std::make_pair(Hval, pos);
    }

    void erase_one(const key &x) {
        auto p = search(x);
        if (p.second != elem[p.first].end()) {
            elem[p.first].erase(p.second);
        }
    }

    void erase(const key &x) {
        auto p = search(x);
        auto pos = p.second;
        if (pos != elem[p.first].end()) {
            while (pos != elem[p.first].end() && pos->first == x) {
                pos = elem[p.first].erase(pos);
            }
        }
    }

private:
    vector<list<pair<key, T>>> elem;
    size_t bucket = 100;
    void resize() { elem.resize(bucket); }
};

#endif // !HASH_TABLE_H

 

注解:支持两种元素类型,一种是单元素(key),一种是双元素(key, T),分别对应于Sgl_HashTable和Dbl_HashTable。
---------------------
作者:_MICHAEL_LIU_
来源:CSDN
原文:https://blog.csdn.net/liu798675179/article/details/52189700
版权声明:本文为博主原创文章,转载请附上博文链接!

 

==============

迭代适配器(一) back_insert和front_insert的简单实现

当我们调用copy函数时,要确保目标容器足够大,例如:

//将vec的所有元素拷贝到以coll.begin()为起始地址的位置
copy(vec.begin(), vec.end(), coll.begin());

如果之前没有为coll分配好足够的内存,就会引发越界错误。

如果我们无法提前为coll预分配内存,可使用如下代码:

//将vec的所有元素拷贝到以coll.begin()为起始地址的位置
copy(vec.begin(), vec.end(), back_insert(coll.begin()));

back_insert是一种插入迭代器,插入迭代器就是帮我们屏蔽插入元素的细节,使得iter看起来总是指向一个"可用的位置"。

需要注意一下几点:

1.插入迭代器本质上是一种适配器,但是它看起来像一个迭代器,行为像一个迭代器,那么他就符合迭代器的定义。

2.插入迭代器的赋值,内部采用了插入元素的做法,可能调用容器的push_back push_front或者insert等。

3.插入迭代器的++操作,只是个幌子,但必不可少。以上面的copy为例,内部肯定调用了iter++,因为copy函数只是把它当做普通迭代器。

4.解引用操作同样也是幌子。

back_insert和front_insert实现代码如下:

复制代码

 1 #ifndef ITERATOR_H
 2 #define ITERATOR_H
 3 #include <iterator>
 4 
 5 //BackInsertIterator
 6 template <typename Container>
 7 class BackInsertIterator
 8 {
 9 public:
10     typedef typename Container::value_type value_type;
11 
12     explicit BackInsertIterator(Container &cont)
13         :_cont(cont)
14     { }
15 
16     BackInsertIterator<Container> &operator= (const value_type &val)
17     {
18         _cont.insert(_cont.end(), val);
19         return *this;
20     }
21 
22     BackInsertIterator<Container> &operator*()
23     { return *this; }
24 
25     BackInsertIterator<Container> &operator++()
26     { return *this; }
27 
28     BackInsertIterator<Container> &operator++(int)
29     { return *this; }
30 private:
31     Container &_cont;
32 };
33 
34 template <typename Container>
35 BackInsertIterator<Container> backInsert(Container &c)
36 { return BackInsertIterator<Container>(c); }
37 
38 
39 //FrontInsertIterator
40 template <typename Container>
41 class FrontInsertIterator
42 {
43 public:
44     typedef typename Container::value_type value_type;
45 
46     explicit FrontInsertIterator(Container &cont)
47         :_cont(cont)
48     { }
49 
50     FrontInsertIterator<Container> &operator= (const value_type &val)
51     {
52         _cont.insert(_cont.begin(), val);
53         return *this;
54     }
55 
56     FrontInsertIterator<Container> &operator*()
57     { return *this; }
58 
59     FrontInsertIterator<Container> &operator++()
60     { return *this; }
61 
62     FrontInsertIterator<Container> &operator++(int)
63     { return *this; }
64 private:
65     Container &_cont;
66 };
67 
68 template <typename Container>
69 FrontInsertIterator<Container> frontInsert(Container &c)
70 { return FrontInsertIterator<Container>(c); }
71 
72 #endif

复制代码

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值