- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试构建一个通用数据结构,它需要保存键和值,同时跟踪键和值被放入的索引的索引,就像 arraylist 所做的那样,复杂度为 O(log n) 或更少。
我试图解决这个问题,并创建了各种具有整数的 TreeMaps - 索引和值,反之亦然,并且与键相同。
为了更清楚,索引象征着来自用户的插入顺序。所以如果我有 3 个元素,那么它们的索引是 0 1 2,如果元素 0 被删除,那么我需要将 1 推到 0 和 2 推到 1,并且一个新元素将添加索引 2。
我的问题是当我删除一个键和它的值时,如果我想在正确的索引中插入下一个键和值,我必须确保所有旧的都被设置为 1。我不知道该怎么做并且不会陷入 O(n) 复杂性。
我的目标是使用现有的数据结构并将它们混合以获得此结果,请查看我在需要时实现的方法。
我正在添加我的代码以供引用,任何帮助将不胜感激。
谢谢
汤姆
import java.util.Collection;
import java.util.HashMap;
import java.util.TreeMap;
import java.util.Map;
public class SuperStruct<K,V>
{
private Map<K,V> mInternalKeyToValueMap;//all the keys and their values
private Map<Integer,V> mIndexToValueMap;//index's for values according to the entrance order to
private Map<V,Integer> mValueToIndexMap;//values and their index's
private Map<Integer,K> mIndexToKeyMap;//index's and their keys according to entrance order
private Map<K,Integer> mKeyToIndexMap;//keys and their index's
private int mNextIndex;//index for the data structure according to the order data was received by user
public SuperStruct(){
mInternalKeyToValueMap = new TreeMap<K,V>();
mIndexToValueMap = new TreeMap<Integer,V>();
mValueToIndexMap = new TreeMap <V,Integer>();
mIndexToKeyMap = new TreeMap <Integer, K>();
mKeyToIndexMap = new TreeMap <K,Integer>();
}
public boolean containsKey(Object key) {
boolean containable = mInternalKeyToValueMap.containsKey(key);
return containable;
}
public boolean containsValue(Object value) {
boolean containable = mValueToIndexMap.containsKey(value);
return containable;
}
public V get(Object key) {
if(mInternalKeyToValueMap.containsKey(key)){
V value = mInternalKeyToValueMap.get(key);
return value;
}
return null;
}
public Collection<K> keySet() {
return mInternalKeyToValueMap.keySet();
}
/**
* This method is putting the key and the value in the main TreeMap "mInternalKeyToValueMap", while on the mean time updating 4 other TreeMaps
* with data regarding to the index in which data was received from the user.
* all in all this method runs in complexity of 6*(O(log n)) that sums down to O(log n) cause constants don't calculate over the whole
* Complexity calculation
* In case that a key already had a mapping to it and we overwrite the value we will run in complexity of 11*(O(log n)) which still sums down to O(log n)
* cause constants don't calculate over the whole
*/
public V put(K key, V value) {
if(mValueToIndexMap.containsKey(value))//preventing duplications of value
return value;
if(mInternalKeyToValueMap.containsKey(key)){//when a key already exist in system and we want to overwrite its value
int indexToDelete = mKeyToIndexMap.get(key);//we get the index of the value we over-write
V value1 = mIndexToValueMap.get(indexToDelete);//using this index we get the value
mValueToIndexMap.remove(value1);//we remove the value and its index
mIndexToValueMap.remove(indexToDelete);//we remove the index and its value
}
mInternalKeyToValueMap.put(key, value);//putting the new value for the key in the main TreeMap
mValueToIndexMap.put(value, mNextIndex);//populating the TreeMap of values and their index's - the order we received them from the user
mIndexToValueMap.put(mNextIndex, value);//This TreeMap holds the index's for each value according to the order of insertion by user
mIndexToKeyMap.put(mNextIndex, key);//This TreeMap holds the index's for each key according to the order of insertion by user
mKeyToIndexMap.put(key,mNextIndex);//populating the TreeMap of keys and their index's - the order we received them from the user
++mNextIndex;//advancing the index which mark the insertion order of arguments to structure
return null;
}
public V remove(Object key) {
if(mInternalKeyToValueMap.containsKey(key)==true && (mInternalKeyToValueMap.get(key)!=null))
{
V value = mInternalKeyToValueMap.get(key);
mInternalKeyToValueMap.remove(key);//removing map for the value
int mIndexToRemoveValue = mValueToIndexMap.get(value);//getting the right index to remove the value
mIndexToValueMap.remove(mIndexToRemoveValue);//vacating the value for this index
mIndexToKeyMap.remove(mIndexToRemoveValue);//vacating the key for this index
mKeyToIndexMap.remove(key);//removing a key and index in the keyToIndex Map
mValueToIndexMap.remove(value);//removing a key and index in the ValueToIndex Map
return value;
}
return null;
}
public Collection<V> values() {
return mInternalKeyToValueMap.values();
}
public Collection<V> getStrcutureSorted(){
return mValueToIndexMap.keySet();
}
public V getValueByIndex(int index){//return the index in which the value sits in, if not present null
V value = mIndexToValueMap.get(index);
return value;
}
public Integer getIndexByKey(K key){
Integer returnable = mKeyToIndexMap.get(key);
if(returnable == null)
return -1;
return returnable;
}
public K getKeyByIndex(int index){
return mIndexToKeyMap.get(index);
}
}
最佳答案
这是一个有趣的难题。感觉应该是有可能的,但细节是难以捉摸的。问题出在删除后的索引更新操作中。例如,如果索引存储在树节点中,那么在删除操作后平均需要更改 n/2 个索引,这会破坏您正在努力实现的 O(log n) 属性。
如果您同时在树和 ArrayList 中存储对象,您仍然会遇到在 ArrayList 中定位对象的问题,我无法在小于 O(n) 的时间内以直接方式工作。 ArrayList 可能有一些变化,也许是自定义构造,但这似乎需要做很多工作。
相反,我建议您考虑使用红黑树或类似的平衡树,并在 Red-black tree access by ordinal index 中注明修改。 :对于树的每个节点,还存储子树中以给定节点为根节点的节点数。在插入和删除操作期间,您必须更新受旋转操作影响的所有节点的计数。这仍然可以在 O(log n) 时间内完成,但它很复杂。
然后,对第 k 个最小(或最大)元素的二进制搜索也将像往常一样通过通常的递归算法在 O(log n) 时间内运行。
以下是该技术的更多引用资料:http://www.cs.usfca.edu/~galles/cs673/lecture/lecture8.pdf , http://fdatamining.blogspot.ca/2011/09/functional-red-black-tree-with-dynamic.html , http://en.wikipedia.org/wiki/Order_statistic_tree .这应该让你开始。
更新:实现细节
您需要做的是创建两棵树。一个可以是普通的平衡树(如红黑树),用于保存对具有键/值对的对象的引用。您可以搜索键并在 O(log n) 中获取相应的值;插入和删除也是 O(log n)。此外,第一棵树中的节点将保存对第二棵树(如下)中节点的引用。
第二棵树也将保存对第一棵树中节点的引用,但它将是上面讨论的顺序统计树。插入总是将新项目放在树的右端。
对该数据结构的插入操作将是通过键插入第一棵树的普通插入,插入到订单统计树的右侧,并且每个插入节点中的引用将被更新以指向另一个节点中的适当位置树。
可以在第一棵树上对 O(log n) 中的给定键进行搜索操作,这将返回适当的值,并遵循对另一棵树的引用,可用于查找节点的“顺序统计信息”在 O(log n) 时间的第二棵树中,通过向上遍历树到根并执行简单计算。
对于队列中的第 k 个位置,可以在 O(log n) 时间内在第二棵树上完成搜索操作,返回对第二棵树的引用,可以取消引用以获得关联的键/值对。
在任何一棵树中的删除都将先推迟对另一棵树的引用,然后删除第一棵树中的节点,然后删除另一棵树中的相应节点,都是 O(log n) 操作。
我想就是这样。一切都可以在 O(log n) 时间内完成。第二棵树的空间成本很小,但它只包含引用;空间仍然是 O(n)。
那样有用吗?
关于arraylist - 是否可以创建一个具有 log(n) 复杂度的 ArrayList 属性的 Map?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30676254/
我有一个 if 语句,如下所示 if (not(fullpath.lower().endswith(".pdf")) or not (fullpath.lower().endswith(tup
然而,在 PHP 中,可以: only appears if $foo is true. only appears if $foo is false. 在 Javascript 中,能否在一个脚
XML有很多好处。它既是机器可读的,也是人类可读的,它具有标准化的格式,并且用途广泛。 它也有一些缺点。它是冗长的,不是传输大量数据的非常有效的方法。 XML最有用的方面之一是模式语言。使用模式,您可
由于长期使用 SQL2000,我并没有真正深入了解公用表表达式。 我给出的答案here (#4025380)和 here (#4018793)违背了潮流,因为他们没有使用 CTE。 我很欣赏它们对于递
我有一个应用程序: void deleteObj(id){ MyObj obj = getObjById(id); if (obj == null) { throw n
我的代码如下。可能我以类似的方式多次使用它,即简单地说,我正在以这种方式管理 session 和事务: List users= null; try{ sess
在开发J2EE Web应用程序时,我通常会按以下方式组织我的包结构 com.jameselsey.. 控制器-控制器/操作转到此处 服务-事务服务类,由控制器调用 域-应用程序使用的我的域类/对象 D
这更多是出于好奇而不是任何重要问题,但我只是想知道 memmove 中的以下片段文档: Copying takes place as if an intermediate buffer were us
路径压缩涉及将根指定为路径上每个节点的新父节点——这可能会降低根的等级,并可能降低路径上所有节点的等级。有办法解决这个问题吗?有必要处理这个吗?或者,也许可以将等级视为树高的上限而不是确切的高度? 谢
我有两个类,A 和 B。A 是 B 的父类,我有一个函数接收指向 A 类型类的指针,检查它是否也是 B 类型,如果是将调用另一个函数,该函数接受一个指向类型 B 的类的指针。当函数调用另一个函数时,我
有没有办法让 valgrind 使用多个处理器? 我正在使用 valgrind 的 callgrind 进行一些瓶颈分析,并注意到我的应用程序中的资源使用行为与在 valgrind/callgrind
假设我们要使用 ReaderT [(a,b)]超过 Maybe monad,然后我们想在列表中进行查找。 现在,一个简单且不常见的方法是: 第一种可能性 find a = ReaderT (looku
我的代码似乎有问题。我需要说的是: if ( $('html').attr('lang').val() == 'fr-FR' ) { // do this } else { // do
根据this文章(2018 年 4 月)AKS 在可用性集中运行时能够跨故障域智能放置 Pod,但尚不考虑更新域。很快就会使用更新域将 Pod 放入 AKS 中吗? 最佳答案 当您设置集群时,它已经自
course | section | type comart2 : bsit201 : lec comart2 :
我正在开发自己的 SDK,而这又依赖于某些第 3 方 SDK。例如 - OkHttp。 我应该将 OkHttp 添加到我的 build.gradle 中,还是让我的 SDK 用户包含它?在这种情况下,
随着 Rust 越来越充实,我对它的兴趣开始激起。我喜欢它支持代数数据类型,尤其是那些匹配的事实,但是对其他功能习语有什么想法吗? 例如标准库中是否有标准过滤器/映射/归约函数的集合,更重要的是,您能
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 这个问题似乎与 help center 中定义的范围内的编程无关。 . 关闭 9 年前。 Improve
我一直在研究 PHP 中的对象。我见过的所有示例甚至在它们自己的对象上都使用了对象构造函数。 PHP 会强制您这样做吗?如果是,为什么? 例如: firstname = $firstname;
...比关联数组? 关联数组会占用更多内存吗? $arr = array(1, 1, 1); $arr[10] = 1; $arr[] = 1; // <- index is 11; does the
我是一名优秀的程序员,十分优秀!