Left base topic class5- 2 Fortune structure design RandomPool method, may be added, deleted, access key, complexity is O (1)

1. Title: RandomPool structure design, can be added, deleted, access key, complexity is O (1)

RandomPool structural design a structure has the following three functions in the structure:
INSERT (key): the addition of a key to the structure, do not repeat added;
Delete (key): originally in the structure of a key removed;
getRandom (): returns the probability of any other key structures.
[Requirements] time complexity Insert, delete and getRandom methods is O (1).

2.Map in brief

Due to the requirement to add, remove complexity are O (1), consider using Map.
Map is an associative STL containers, primarily for case-one mapping of data

  • All map elements are pair
  • the first element is a pair key (key), play a role in the index, the second element is the value (real value)
  • map <T1, T2> mp; // map default constructor:
#include<iostream>
#include<map>
#include<string>
int main()
{
	//构造方式key为string类型,value为int类型
	map<string,int> mm;
	mm[string("www")] = 2;
	mm[string("eee")] = 4;
	mm.insert(pair<string,int>("rrr",7));
	mm[string("ttt")] = 0;


	return 0;
}

3. Analyze

The title structure assumed key value stored in a, b, c, d, e, using the map structure, and delete are only added complexity of O (1), but for the other return probability is not easy to do, consider two map structure, as shown below, when added simultaneously adding two map and a second map storing the key value of the value of the first map, a value of the first key value storage map, this object is by value value map2 anti-obtained key value of map1.
For the return of probability, etc., assuming a total number of 26, value stored values 0,1,2,3,4,5. . . 25, the rand () function is a random number between 0-25, and then find the corresponding values from the MAP2, so that you can return a random key value of map1. At this value values as No. barrels, buckets to pick different things inside that is key to pour out, the barrel is A. No. eg.0 However, there has been the emergence of new problems, sometimes after deletion, it may be the result of random out of the barrel does not exist, in order to solve this problem, we need to ensure uninterrupted barrel number. When removed, the maximum number of barrels barrels barrels Change the number to be deleted. Example, if you delete B, No. 1 barrel, the current maximum number of 25 Z barrel barrel number is changed to 1, so the bucket number is still continuous 0-24.

Here Insert Picture Description

(1) pool design

As the above analysis, we need to map to achieve the two, is increasing, when you delete, delete two map with the same increase in random return, use map2 return its value value purpose. In addition, the need for size storage bucket number.

class Pool
{
public:
	Pool()
	{
		this->size = 0;
	}
	void map_insert(string word);
	void map_delete(string word);
	void getRandom();
private:
	map<string,int> keyValueMap;
	map<int,string> valuekeyMap;
	int size ;//桶号

};

(2) add design

For map1, when you want to add map1 key does not exist in the key, the call to add a map that comes with insert function, this time value is the current number of barrels of size, and map2, key values ​​and value map1 opposite. map itself does not allow duplicate key values ​​used here find () function to find the value to be added, if the find iterator is empty added.

void Pool::map_insert(string word)
{
	//find(key)存在返回该键的元素的迭代器;不存在返回m.end();
	//if(this->keyValueMap.end() != this->keyValueMap.find(word))
	map<string,int>::iterator pos = keyValueMap.find(word);
	if(pos == keyValueMap.end())
	{
		keyValueMap.insert(pair<string,int>(word,size));
		valuekeyMap.insert(pair<int,string>(size++,word));
	}
}

(3) delete design

map deleted by the iterator delete, delete find iterator position m.erase(pos), and specify the key value to delete m.erase(key)two kinds.
Because the underlying red-black tree map, value map value may be modified, and the key value can not be modified. So the original idea was to put out a method to delete the group of the largest group of barrels covered in c ++ does not work, consider using an iterator first recording position map1 delete, and then separately record the maximum value of the barrel and remove the key value is used as the final value again Add, delete four sections B, Z, and finally add the two parts of the revised number Z of the barrel. Next, four positioning portions need to be deleted, for map1 from B, the title delete statement delete(word)can be deleted directly word values, in the map2 portion, the recording position by the iterator map1 map1 may identify the second parameter value or 1; and Z lookup value map1 the value of the maximum number of buckets by map2, namely key value map1, and finally map2 25 can be obtained directly by the greatest number of barrels.
Note, first I want to remove the two groups, covering the two groups can not be taken for granted using a reverse iterator that is directly delete the last group, map1, map2 lateral necessarily aligned. The final four with the most primitive delete the code to add two most concise.
Here Insert Picture Description

void Pool::map_delete(string word)
{
	//map1需要删除的位置用pos记录
	map<string,int> ::iterator pos = keyValueMap.find(word);
	if(pos != keyValueMap.end())//表示需要删除的存在
	{
		//通过map2取出桶号最大的key值,再取出需要保存的桶号
		string key = valuekeyMap.find(size - 1)->second;
		int value = pos->second;

		//删除四个map部分,分别通过迭代器、按值查找获得
		keyValueMap.erase(word);
		keyValueMap.erase(key);
		valuekeyMap.erase(value);
		valuekeyMap.erase(--size);//桶号减一
		//删除的恰好是桶最大,就不需要添加,直接返回
		if(word == key)
			return;

		this->keyValueMap.insert(pair<string,int>(key,value));
		this->valuekeyMap.insert(pair<int,string>(value,key));
	}
}

(4) equal probability random return design

By rand () function returns the serial number of the tub, and then find the second map2 parameter value key value, that is map1

void Pool::getRandom()
{
	srand((unsigned)time(NULL));
	int num = rand() % size; //0 到 size-1
	cout<<valuekeyMap.find(num)->second;
}

4. The complete code

#include<iostream>
#include<map>
#include<string>
#include<time.h>
using namespace std;

class Pool
{
public:
	Pool()
	{
		this->size = 0;
	}
	void map_insert(string word);
	void map_delete(string word);
	void getRandom();
private:
	map<string,int> keyValueMap;
	map<int,string> valuekeyMap;
	int size ;//桶号

};
void Pool::getRandom()
{
	srand((unsigned)time(NULL));
	int num = rand() % size; //0 到 size-1
	cout<<valuekeyMap.find(num)->second;
}

void Pool::map_delete(string word)
{
	//map1需要删除的位置用pos记录
	map<string,int> ::iterator pos = keyValueMap.find(word);
	if(pos != keyValueMap.end())//表示需要删除的存在
	{
		//通过map2取出桶号最大的key值,再取出需要保存的桶号
		string key = valuekeyMap.find(size - 1)->second;//second是value值,first是key值
		int value = pos->second;

		//删除四个map部分,分别通过迭代器、按值查找获得
		keyValueMap.erase(word);
		keyValueMap.erase(key);
		valuekeyMap.erase(value);
		valuekeyMap.erase(--size);//桶号减一
		//删除的恰好是桶最大,就不需要添加,直接返回
		if(word == key)
			return;

		keyValueMap.insert(pair<string,int>(key,value));
		valuekeyMap.insert(pair<int,string>(value,key));
	}
}

void Pool::map_insert(string word)
{
	//find(key)存在返回该键的元素的迭代器;不存在返回m.end();
	//if(keyValueMap.end() != this->keyValueMap.find(word))
	map<string,int>::iterator pos = keyValueMap.find(word);
	if(pos == this->keyValueMap.end())
	{
		keyValueMap.insert(pair<string,int>(word,size));
		valuekeyMap.insert(pair<int,string>(size++,word));
	}
}

int main()
{
	Pool m1;
	m1.map_insert("aaa");
	m1.map_insert("bbb");
	m1.map_insert("ccc");
	m1.map_insert("ddd");
	m1.map_insert("eee");
	m1.map_insert("fff");
	m1.map_insert("ggg");
	m1.map_insert("hhh");
	m1.map_insert("iii");
	m1.map_insert("jjj");
	
	m1.map_delete("aaa");

	//测试添加key相同的元素
	m1.map_insert("hhh");
	m1.map_delete("ggg");

	//测试删除size最大数
	m1.map_insert("kkk");
	m1.map_delete("kkk");

	m1.getRandom();

	//test 使用[]可以修改value值,
	map<string,int> mm;
	mm[string("www")] = 2;
	mm[string("www")] = 4;
	mm.insert(pair<string,int>("www",7));
	mm[string("www")] = 7;


	system("pause");
	return 0;
}
Published 51 original articles · won praise 1 · views 1369

Guess you like

Origin blog.csdn.net/shi_xiao_xuan/article/details/104118493