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