Đọc về ngăn xếp spaguetti/xương rồng Tôi đã đưa ra một biến thể có thể phục vụ cho mục đích này, bao gồm khả năng ánh xạ khóa của bạn theo thứ tự bất kỳ để map.lookup ("a", "b") và bản đồ .lookup ("b", "a") trả về cùng một phần tử. Nó cũng làm việc với bất kỳ số lượng các phím không chỉ là hai.
Tôi sử dụng nó như một ngăn xếp để thử nghiệm với lập trình dataflow nhưng đây là một phiên bản nhanh và bẩn hoạt động như một bản đồ đa khóa (cần được cải thiện: Bộ thay vì mảng nên được sử dụng để tránh tìm kiếm các ocurrences trùng lặp a key)
public class MultiKeyMap <K,E> {
class Mapping {
E element;
int numKeys;
public Mapping(E element,int numKeys){
this.element = element;
this.numKeys = numKeys;
}
}
class KeySlot{
Mapping parent;
public KeySlot(Mapping mapping) {
parent = mapping;
}
}
class KeySlotList extends LinkedList<KeySlot>{}
class MultiMap extends HashMap<K,KeySlotList>{}
class MappingTrackMap extends HashMap<Mapping,Integer>{}
MultiMap map = new MultiMap();
public void put(E element, K ...keys){
Mapping mapping = new Mapping(element,keys.length);
for(int i=0;i<keys.length;i++){
KeySlot k = new KeySlot(mapping);
KeySlotList l = map.get(keys[i]);
if(l==null){
l = new KeySlotList();
map.put(keys[i], l);
}
l.add(k);
}
}
public E lookup(K ...keys){
MappingTrackMap tmp = new MappingTrackMap();
for(K key:keys){
KeySlotList l = map.get(key);
if(l==null)return null;
for(KeySlot keySlot:l){
Mapping parent = keySlot.parent;
Integer count = tmp.get(parent);
if(parent.numKeys!=keys.length)continue;
if(count == null){
count = parent.numKeys-1;
}else{
count--;
}
if(count == 0){
return parent.element;
}else{
tmp.put(parent, count);
}
}
}
return null;
}
public static void main(String[] args) {
MultiKeyMap<String,String> m = new MultiKeyMap<String,String>();
m.put("brazil", "yellow", "green");
m.put("canada", "red", "white");
m.put("USA", "red" ,"white" ,"blue");
m.put("argentina", "white","blue");
System.out.println(m.lookup("red","white")); // canada
System.out.println(m.lookup("white","red")); // canada
System.out.println(m.lookup("white","red","blue")); // USA
}
}
Nguồn
2014-06-04 17:14:43
Có vấn đề gì do mã băm cho ABC, D và AB, CD là giống nhau không? Hay bằng bình đẳng là giải quyết khác nhau? –
@smackfu: Điều đó phụ thuộc. Nó sẽ chỉ là một vấn đề nếu bạn có nhiều cặp dây như vậy, bởi vì chúng sẽ băm vào cùng một chỗ trong bảng và làm cho việc tra cứu kém hiệu quả hơn. – Tudor
@Tudor bạn có thể nghĩ ra bất kỳ lợi thế nào mà giải pháp này có trên giải pháp được trình bày bởi EdgeCase mà về cơ bản chỉ nối hai chuỗi được phân tách bằng ký tự dấu ngã? – Zak