如何实现Multi-Key Multi-Map

来源:互联网 发布:淘宝客佣金查看工具 编辑:程序博客网 时间:2024/04/29 19:16

问题描述:

发信人: cellulose (▄︻┻┳═一), 信区: CPlusPlus
标  题: 请问如何实现这种Multi-Key Multi-Map
发信站: 水木社区 (Tue May 29 14:13:44 2007), 站内

名字可能不是太准确,但差不多就是这个意思

Multi-Key Multi-Map

即一个multimap支持multikey

先考虑两个key的情况
基本上可以这么实现

multimap<pair<pKey, sKey>, Data>

key部分按照pair默认的 < 排序,即先排pKey,再排sKey

现在有个要求就是可以选择一行,即找出所有pKey 为某值的 iterator,
显然这组值是连续的,可以用一个范围来表示

问题是要求知道 sKey对应类型的最大值和最小值,才能很方便的选择一行

例如假设multimap是这种情况

typedef multimap<pair<string,unsigned char>, string> MKMap;
typedef MKMap::Iterator MKIterator;

那么选择某sKey可以这么实现
MKMap mkMap;
//填入数据
//。。。

//
pair<MKIterator, MKIterator> SelectRow(string pkey)
{
        return make_pair(mkMap.lower_bound(make_pair(pkey,0)),
                         mkMap.upper_bound(make_pair(pkey,0xff)));
}

这里的0和0xff就是sKey对应类型的最小值和最大值
如果考虑使用与任何类型,应该怎么实现?


其实我本来是考虑做一个多string为key的一个multimap
那么string里面最小的就是空串了,最大的是什么呢? 

分析解决:

 

 

Curvelet@smth:

找找 boost 的 Multi-index Containers

value 和 key 可以相互映射的叫 bidirectional map,不是 mulit-key map.

楼主这里的 multikey 用 muliti-index 说更合适,指的是 key 有多维,可以按每一维来做查询,应该不是指 bidirectional map。

 

 

 

wew@smth:


我以前一个项目就是类似的,
每个value对应2个key,目标是无论知道哪个key都可以返回这个value

和你说的多维key,知道其中一维,的区别应该就是2个和多个。

我的做法是直接写一个类继承自apache的MultiKeyMap

import java.util.*;
import org.apache.commons.collections.keyvalue.MultiKey;
import org.apache.commons.collections.map.*;

/**
 * 多个key的映射
 * @author Administrator
 *
 */
public class MultiMap extends MultiKeyMap {
    private static final long serialVersionUID = -3218199231038721040L;//changed a little bit

        public MultiMap(){
                super();
        }
        
        public synchronized Object put(Object key1,Object key2,Object value){
                return super.put(key1,key2,value);
        }

        /**
         * 是否包含key
         *
         * @param key
         * @return
         */
        public boolean contains(Object key){
                if(map.containsKey(key)){
                        return true;
                }
                if(map.keySet().contains(key)){
                        return true;
                }
                Iterator it = map.keySet().iterator();
                while(it.hasNext()){
                        Object tmp = it.next();
                        if(tmp instanceof MultiKey){
                                Object[] keys = ((MultiKey)tmp).getKeys();
                                for(int i=keys.length-1;i>=0;i--){
                                        if(key.equals(keys[i])){
                                                return true;
                                        }
                                }

                        }
                }
                return false;
        }

        /**
         * 根据key,取出对应的value
         */
        public Object get(Object key){
                Iterator it = map.keySet().iterator();
                while(it.hasNext()){
                        Object tmp = it.next();
                        MultiKey obj = null;
                        if(tmp instanceof MultiKey){
                                obj = (MultiKey)tmp;
                                Object[] keys = obj.getKeys();
                                boolean has = false;
                                for(int i=keys.length-1;i>=0;i--){
                                        if(key.equals(keys[i])){
                                                has = true;
                                                break;
                                        }
                                }
                                if(has){
                                        return super.get(obj);
                                }

                        }
                }
                return null;
        }


}