我正在使用std :: map.有时我会做一个操作:找到所有项目的中值.例如,如果我添加
1 "s"
2 "sdf"
3 "sdfb"
4 "njw"
5 "loo"
Run Code Online (Sandbox Code Playgroud)
那么中位数是3.
是否有一些解决方案没有迭代地图中的一半以上的项目?
我认为你可以用两个来解决这个问题std::map.一个用于较小的一半项目(mapL),另一个用于另一半(mapU).当你有插入操作.它将是这两种情况:
如果地图具有不同的大小,并且您将元素插入到具有较少元素数的元素,则跳过移动部分.基本思路是保持地图平衡,因此最大尺寸差异为1个元素.据我所知STL所有操作都应该在O(ln(n))时间内工作.可以使用迭代器来访问映射中最小和最大的元素.当你有第n个位置查询时,只需检查地图大小并返回mapL中的最大元素或mapR中的最小元素.
上面的使用场景仅用于插入,但您可以将其扩展为删除项目,但您必须跟踪哪个地图包含项目或尝试从两者中删除.
这是我的代码用例:
#include <iostream>
#include <string>
#include <map>
using namespace std;
typedef pair<int,string> pis;
typedef map<int,string>::iterator itis;
map<int,string>Left;
map<int,string>Right;
itis get_last(map<int,string> &m){
return (--m.end());
}
int add_element(int key, string val){
if (Left.empty()){
Left.insert(make_pair(key,val));
return 1;
}
pis maxl = *get_last(Left);
if (key <= maxl.first){
Left.insert(make_pair(key,val));
if (Left.size() > Right.size() + 1){
itis to_rem = get_last(Left);
pis cpy = *to_rem;
Left.erase(to_rem);
Right.insert(cpy);
}
return 1;
} else {
Right.insert(make_pair(key,val));
if (Right.size() > Left.size()){
itis to_rem = Right.begin();
pis cpy = *to_rem;
Right.erase(to_rem);
Left.insert(*to_rem);
}
return 2;
}
}
pis get_mid(){
int size = Left.size() + Right.size();
if (Left.size() >= size / 2){
return *(get_last(Left));
}
return *(Right.begin());
}
int main(){
Left.clear();
Right.clear();
int key;
string val;
while (!cin.eof()){
cin >> key >> val;
add_element(key,val);
pis mid = get_mid();
cout << "mid " << mid.first << " " << mid.second << endl;
}
}
Run Code Online (Sandbox Code Playgroud)