Data structures 具有pull-first和Elest-java的数据结构
我正在寻找具有以下功能的数据结构: -有重点和价值 -可以在O(n)>t>O(logn)或O(1)中找到值 -可以拉动我插入的第一个元素和最后一个元素 TreeMep不好,因为如果我插入键(作为字符串)“b”,然后插入键“a”,如果我拉动第一个键,我将得到“a”而不是“b” ConcurrentSkipListMap不好,因为我不能依赖于size func' 非常感谢您的帮助Data structures 具有pull-first和Elest-java的数据结构,data-structures,map,Data Structures,Map,我正在寻找具有以下功能的数据结构: -有重点和价值 -可以在O(n)>t>O(logn)或O(1)中找到值 -可以拉动我插入的第一个元素和最后一个元素 TreeMep不好,因为如果我插入键(作为字符串)“b”,然后插入键“a”,如果我拉动第一个键,我将得到“a”而不是“b” ConcurrentSkipListMap不好,因为我不能依赖于size func' 非常感谢您的帮助 谢谢您可以使用一个deque(双端队列)与一个multimap(特别是一个二进制搜索树)交叉引用,它允许重复键 队列的每
谢谢您可以使用一个
deque
(双端队列)与一个multimap
(特别是一个二进制搜索树)交叉引用,它允许重复键
队列的每个元素都有一个对映射的相应元素的引用(迭代器),反之亦然
通过这种方式,您可以在O(logn)中的映射中进行搜索,并且可以在O(logn)中的序列两端进行推/拉操作
您可以决定将字符串存储在映射或队列中
下面是C++中的一个实现:
#include <string>
#include <map>
#include <deque>
typedef int my_key_type; // Key type
typedef std::string my_value_type; // Value type
struct queueitem; // Queue element
typedef std::deque<queueitem> my_queue; // Queue
typedef std::multimap <my_key_type,
my_queue::iterator> my_map; // Map
typedef std::pair <my_key_type,
my_queue::iterator> my_map_pair; // Map element
struct queueitem
{
my_value_type value;
my_map::iterator mapitem;
queueitem (const my_value_type & val) : value(val) {}
};
class mapqueue
{
public:
mapqueue () {}
my_value_type find (my_key_type key) const;
size_t index_of (my_key_type key) const;
my_value_type front_value () const { return Q.front().value; }
my_value_type back_value () const { return Q.back().value; }
my_key_type front_key () const
{ return Q.front().mapitem->first; }
my_key_type back_key () const
{ return Q.back().mapitem->first; }
void push_front (my_key_type key,
const my_value_type & value);
void push_back (my_key_type key,
const my_value_type & value);
void pop_front ();
void pop_back ();
private:
my_queue Q;
my_map M;
mapqueue (const mapqueue &) {}
mapqueue & operator= (const mapqueue &) { return *this; }
};
using namespace std;
my_value_type mapqueue::find (my_key_type key) const
{
my_map::const_iterator it = M.find (key);
if (it==M.end())
throw "Not found";
return it->second->value;
}
size_t mapqueue::index_of (my_key_type key) const
{
my_map::const_iterator it = M.find (key);
if (it==M.end())
throw "Not found";
return it->second - Q.begin();
}
void mapqueue::push_front (my_key_type key,
const my_value_type & value)
{
Q.push_front (queueitem(value));
my_queue::iterator qit = Q.begin ();
qit->mapitem = M.insert (my_map_pair(key,qit));
}
void mapqueue::push_back (my_key_type key,
const my_value_type & value)
{
Q.push_back (queueitem(value));
my_queue::iterator qit = Q.end () - 1;
qit->mapitem = M.insert (my_map_pair(key,qit));
}
void mapqueue::pop_front ()
{
M.erase (Q.front().mapitem);
Q.pop_front ();
}
void mapqueue::pop_back ()
{
M.erase (Q.back().mapitem);
Q.pop_back ();
}
#包括
#包括
#包括
typedef int my_key_type;//键类型
typedef std::string my_value_type;//值类型
结构queueitem;//队列元素
typedef std::定义我的队列;//队列
typedef std::multimap my_map;//地图
typedef std::pair my_map_pair;//地图元素
结构队列项
{
我的值类型值;
我的地图::迭代器地图项目;
queueitem(const my_value_type&val):值(val){}
};
类映射队列
{
公众:
映射队列(){}
my_value_type find(my_key_type key)常量;
(我的密钥类型密钥)常量的大小索引;
my_value_type front_value()常量{return Q.front().value;}
my_value_type back_value()常量{return Q.back().value;}
我的钥匙类型前钥匙()常数
{返回Q.front().mapitem->first;}
my_key_type back_key()常量
{返回Q.back().mapitem->first;}
无效向前推(我的钥匙类型钥匙,
const my_value(类型和值);
无效推回(我的钥匙类型钥匙,
const my_value(类型和值);
void pop_front();
void pop_back();
私人:
我的Q;
我的地图;
mapqueue(常量mapqueue&){}
mapqueue&运算符=(const mapqueue&){return*this;}
};
使用名称空间std;
我的值类型映射队列::查找(我的键类型键)常量
{
mymap::const\u迭代器it=M.find(key);
如果(it==M.end())
抛出“未找到”;
返回->秒->值;
}
大小映射队列::(我的密钥类型密钥)常量的索引
{
mymap::const\u迭代器it=M.find(key);
如果(it==M.end())
抛出“未找到”;
返回它->秒-Q.begin();
}
void mapqueue::push_front(my_key_type key,
常量我的值(类型和值)
{
Q.push_front(队列项(值));
我的队列::迭代器qit=Q.begin();
qit->mapitem=M.insert(我的映射对(key,qit));
}
void mapqueue::push_back(我的_键类型键,
常量我的值(类型和值)
{
Q.push_back(queueitem(value));
我的队列::迭代器qit=Q.end()-1;
qit->mapitem=M.insert(我的映射对(key,qit));
}
void mapqueue::pop_front()
{
M.erase(Q.front().mapitem);
Q.pop_front();
}
void mapqueue::pop_back()
{
M.erase(Q.back().mapitem);
Q.pop_back();
}
这还支持在O(logn)中的任何给定键的队列中查找索引。如果不需要,可以简化将字符串存储在映射中并删除映射到队列的引用的设计
更新:现在通过typedef
s指定键和值类型。这样很容易改变它们。在一个由这两种类型参数化的模板中转换整个内容会很有趣。这样,即使在同一个程序中,相同的代码也可以用于不同的键值类型对
更新:有一个用于一般情况的工具:更新。请参见文档中的。或者您可以使用映射,只需将插入的第一个和最新元素存储在一对变量中:)否,这还不够好,数据结构将在hashmap中,所以我不想为每个值保存第一个值和第二个值。一个与列表交叉引用的映射如何?有人能将其翻译成Java吗?我想OP需要一个java解决方案,但我是C++的人;键需要是字符串,所以我需要像objectEasy一样的键;-)只需更改第五行中
std::string
的int
。