我需要一个包含三个操作的线程安全数据结构:remove,getRandom,reset。 我现在只有两个想法。
首先:seq in syncronized var。
val all: Array[String] = ... //all possible.
var current: Array[String] = Array.empty[String]
def getRandom(): = {
val currentAvailable = current
currentAvailable(Random.nextInt(currentAvailable.length))
}
def remove(s: String) = {
this.syncronized {
current = current diff Seq(s)
}
}
def reset(s: String) = {
this.syncronized {
current = all
}
}
第二: 保持一些Map [String,Boolean],当元素当前存在时,bool为true。主要问题是制作一个快速的getRandom方法(在最坏的情况下不是O(n))。
有没有更好的方法来实现这个?
答案 0 :(得分:6)
Scala's Trie是一种无锁数据结构,支持快照(又名您的currentAvailable
)和快速删除
答案 1 :(得分:3)
由于我不是Scala专家所以这个答案是通用的,我使用的是Java编码。
简而言之,答案是肯定的。 如果您使用地图,例如:
Map<Integer,String> map=new HashMap<Integer,String>(); //is used to get random in constant time
Map<String,Integer> map1=new HashMap<String,Integer>(); //is used to remove in constant time
存储日期, 主要思想是将密钥(在本例中为整数)保持同步为{1 ... map of map} 例如,为了填充这个结构,你需要这样的东西:
int counter=0; //this is a global variable
for(/* all your string (s) in all */ ){
map.put(counter++, s);
}
//then , if you want the removal to be in constant time you need to fill the second map
for(Entry e : map.EntrySet(){
map1.put(e.getValue(),e.getKey());
}
上面的代码是初始化。每次你想要设置你需要做的事情
然后你可以用O(1)复杂度
来实现随机值String getRandom(){
int i; /*random number between 0 to counter*/
return map.get(i);
}
现在删除你使用map1的东西,以恒定的时间O(1);
void remove(String s){
if(!map1.containsKey(s))
return; //s doesn't exists
String val=map.get(counter); //value of the last
map.remove(counter) //removing the last element
int thisCounter= map1.get(s); //pointer to this
map1.remove(s); // remove from map1
map.remove(counter); //remove from map
map1.put(thisCounter,val); //the val of the last element with the current pointer
counter--; //reducing the counter by one
}
显然,这里的主要问题是确保同步。但是通过仔细分析代码,你应该能够做到这一点。