Java 存储具有多个查询条件的多个实体时要使用哪些数据结构?
有一个存储单元,可存储N个项目。最初,这个单元是空的。 该空间以线性方式排列,即一个挨着另一个排列成一条直线。 每个存储空间都有一个数字,一直增加到N 当有人放下他们的包裹时,会为其分配第一个可用空间。包裹也可以取走,在这种情况下,空间变空了。 示例:如果总容量为4。1和2已满,第三个进来的人将被分配空间3。如果1号、2号和3号空间已满,而第二个空间空置,则下一个来的人将被分配空间2 它们丢弃的包有两个唯一的属性,用于立即识别。首先根据内容对其进行颜色编码,然后为其分配唯一标识号(UIN) 我们需要的是查询系统:Java 存储具有多个查询条件的多个实体时要使用哪些数据结构?,java,algorithm,data-structures,Java,Algorithm,Data Structures,有一个存储单元,可存储N个项目。最初,这个单元是空的。 该空间以线性方式排列,即一个挨着另一个排列成一条直线。 每个存储空间都有一个数字,一直增加到N 当有人放下他们的包裹时,会为其分配第一个可用空间。包裹也可以取走,在这种情况下,空间变空了。 示例:如果总容量为4。1和2已满,第三个进来的人将被分配空间3。如果1号、2号和3号空间已满,而第二个空间空置,则下一个来的人将被分配空间2 它们丢弃的包有两个唯一的属性,用于立即识别。首先根据内容对其进行颜色编码,然后为其分配唯一标识号(UIN) 我们
请注意,即使查询过程不是直接请求存储空间号,但当从存储中删除项目时,它是通过查询存储空间号来删除的。query 3:使用哈希映射,键是UIN,值是object(存储空间号、颜色)(以及包的任何其他信息). 查询、插入或删除的成本为O(1)。空格是O(k),其中k是当前UIN的数量 查询1和查询2:使用哈希映射+多链接列表 哈希映射,键是颜色,值是指向该颜色对应UIN的链接列表的指针(或Java中的引用) 每个链接列表都包含UIN 对于查询1:询问哈希映射,然后返回相应的链接列表。成本是O(k1),其中k1是查询颜色的UIN数。空间是O(m+k1),其中m是唯一颜色的数目 对于查询2:执行查询1,然后应用查询3。成本是O(k1),其中k1是查询颜色的UIN数。空间是O(m+k1),其中m是唯一颜色的数目 插入:给定颜色、数字和UIN,在查询3的哈希映射中插入一个对象(num、color);哈希(颜色)转到相应的链接列表并插入UIN 删除:给定UIN,向查询3询问颜色,然后让查询1删除链接列表中的UIN。然后在查询3的哈希映射中删除UIN
好处:要管理存储空间,情况与操作系统中的内存管理相同:这有点像家庭作业或糟糕的管理 不管是哪种方式,我已经决定做一个版本,其中您最关心的是查询速度,但不关心内存或插入和删除的一点额外开销。这并不是说我会疯狂地烧掉内存,或者花很长时间插入和删除,只是我最关注的是查询 Tl;DR-为了解决您的问题,我使用PriorityQueue、数组、HashMap和ArrayListMultimap(来自guava,一个公共外部库),每一个都可以解决不同的问题 下面的部分是工作代码,它将遍历一些简单的插入、查询和删除。下一部分实际上不是Java,因为我删掉了大部分导入、类声明等。此外,它引用了另一个名为“Packg”的类。这只是一个简单的数据结构,您应该能够从对它的调用中找出它 代码下面有解释
import com.google.common.collect.ArrayListMultimap;
私有优先队列开放插槽;
私人包裹;
地图当前包地图;
私有ArrayListMultimap currentColorMap;
私有对象$outsideCall;
公共CrazyDataStructure(可能的包数){
$outsideCall=新对象();
this.currentPackages=新包装千克[可能的包装数量];
openSlots=new PriorityQueue();
IntStream.range(0,可能的包数)。forEach(i->openSlots.add(i));//填充openSlots优先级队列
currentPackageMap=新的HashMap();
currentColorMap=ArrayListMultimap.create();
}
/*
*args[0]=整数,包的最大值
*/
公共静态void main(字符串[]args)
{
int howManyPackagesPossible=Integer.parseInt(args[0]);
CrazyDataStructure cds=新的CrazyDataStructure(可能有多少个包);
CD.addPackage(新包装(12345,“蓝色”);
CD.addPackage(新包装(12346,“黄色”);
CD.addPackage(新包装(12347,“橙色”);
CD.addPackage(新包装(12348,“蓝色”);
System.out.println(cds.getSlotsForColor(“blue”);//应该是{0,3}的列表
System.out.println(cds.getSlotForUIN(12346));//应该是1(记住,索引为0)
System.out.println(cds.getSlotsForColor(“橙色”);//应该是{2}的列表
System.out.println(cds.removePackage(2));//应该是橙色的
CD.addPackage(新包装(12349,“绿色”);
System.out.println(cds.getSlotForUIN(12349));//应该是2,因为它是打开的
}
公共内部添加包(Packg Packg)
{
同步($outsideCall)
{
int result=openSlots.poll();
包装千克整批(结果);
currentPackages[结果]=包装千克;
currentPackageMap.put(packg.getUIN(),packg);
currentColorMap.put(packg.getColor(),packg);
返回结果;
}
}
公共包移除包(内部插槽)
{
同步($outsideCall)
{
如果(currentPackages[slot]==null)
返回null;
其他的
{
Packg Packg=当前包[插槽];
当前颜色
import com.google.common.collect.ArrayListMultimap;
private PriorityQueue<Integer> openSlots;
private Packg[] currentPackages;
Map<Long, Packg> currentPackageMap;
private ArrayListMultimap<String, Packg> currentColorMap;
private Object $outsideCall;
public CrazyDataStructure(int howManyPackagesPossible) {
$outsideCall = new Object();
this.currentPackages = new Packg[howManyPackagesPossible];
openSlots = new PriorityQueue<>();
IntStream.range(0, howManyPackagesPossible).forEach(i -> openSlots.add(i));//populate the open slots priority queue
currentPackageMap = new HashMap<>();
currentColorMap = ArrayListMultimap.create();
}
/*
* args[0] = integer, maximum # of packages
*/
public static void main(String[] args)
{
int howManyPackagesPossible = Integer.parseInt(args[0]);
CrazyDataStructure cds = new CrazyDataStructure(howManyPackagesPossible);
cds.addPackage(new Packg(12345, "blue"));
cds.addPackage(new Packg(12346, "yellow"));
cds.addPackage(new Packg(12347, "orange"));
cds.addPackage(new Packg(12348, "blue"));
System.out.println(cds.getSlotsForColor("blue"));//should be a list of {0,3}
System.out.println(cds.getSlotForUIN(12346));//should be 1 (0-indexed, remember)
System.out.println(cds.getSlotsForColor("orange"));//should be a list of {2}
System.out.println(cds.removePackage(2));//should be the orange one
cds.addPackage(new Packg(12349, "green"));
System.out.println(cds.getSlotForUIN(12349));//should be 2, since that's open
}
public int addPackage(Packg packg)
{
synchronized($outsideCall)
{
int result = openSlots.poll();
packg.setSlot(result);
currentPackages[result] = packg;
currentPackageMap.put(packg.getUIN(), packg);
currentColorMap.put(packg.getColor(), packg);
return result;
}
}
public Packg removePackage(int slot)
{
synchronized($outsideCall)
{
if(currentPackages[slot] == null)
return null;
else
{
Packg packg = currentPackages[slot];
currentColorMap.remove(packg.getColor(), packg);
currentPackageMap.remove(packg.getUIN());
currentPackages[slot] = null;
openSlots.add(slot);//return slot to priority queue
return packg;
}
}
}
public List<Packg> getUINsForColor(String color)
{
synchronized($outsideCall)
{
return currentColorMap.get(color);
}
}
public List<Integer> getSlotsForColor(String color)
{
synchronized($outsideCall)
{
return currentColorMap.get(color).stream().map(packg -> packg.getSlot()).collect(Collectors.toList());
}
}
public int getSlotForUIN(long uin)
{
synchronized($outsideCall)
{
if(currentPackageMap.containsKey(uin))
return currentPackageMap.get(uin).getSlot();
else
return -1;
}
}
public class SegmentTree
{
private int Mid;
private int[] t;
public SegmentTree(int capacity)
{
this.Mid = 1;
while (Mid <= capacity) Mid *= 2;
this.t = new int[Mid + Mid];
for (int i = Mid; i < this.t.Length; i++) this.t[i] = int.MaxValue;
for (int i = 1; i <= capacity; i++) this.t[Mid + i] = i;
for (int i = Mid - 1; i > 0; i--) t[i] = Math.Min(t[i + i], t[i + i + 1]);
}
public int Capture()
{
int answer = this.t[1];
if (answer == int.MaxValue)
{
throw new Exception("Empty space not found.");
}
this.Update(answer, int.MaxValue);
return answer;
}
public void Erase(int index)
{
this.Update(index, index);
}
private void Update(int i, int value)
{
t[i + Mid] = value;
for (i = (i + Mid) >> 1; i >= 1; i = (i >> 1))
t[i] = Math.Min(t[i + i], t[i + i + 1]);
}
}
int n = 4;
var st = new SegmentTree(n);
Console.WriteLine(st.Capture());
Console.WriteLine(st.Capture());
Console.WriteLine(st.Capture());
st.Erase(2);
Console.WriteLine(st.Capture());
Console.WriteLine(st.Capture());