Algorithm 添加顺序整数会使字符串唯一吗?
动态列表意味着可以添加、删除或更改列表中的元素 这个问题类似于在windows中如何处理重复的文件名。 例如:Algorithm 添加顺序整数会使字符串唯一吗?,algorithm,Algorithm,动态列表意味着可以添加、删除或更改列表中的元素 这个问题类似于在windows中如何处理重复的文件名。 例如: file file (1) file (2) file (3) 如果删除文件(2),然后添加另一个名为文件的文件,则生成的文件名将为文件(2)。(但不要认为这会发生在windows中) 是否有一个优雅的方式来完成这个过程而不必在每个插入列表中搜索整个列表?< P>我将使用一个自平衡二叉树作为集合表示(例如,C++标准 STD::SET/COM>容器)。 该集合将由所有“未分配”数字组
file
file (1)
file (2)
file (3)
如果删除文件(2)
,然后添加另一个名为文件
的文件,则生成的文件名将为文件(2)
。(但不要认为这会发生在windows中)
是否有一个优雅的方式来完成这个过程而不必在每个插入列表中搜索整个列表?
< P>我将使用一个自平衡二叉树作为集合表示(例如,C++标准<代码> STD::SET/COM>容器)。 该集合将由所有“未分配”数字组成,最多包括一个大于最大分配数字的数字 初始化集合以包含0
(或1
,无论您的偏好如何)
要分配一个新号码,请抓取集合中最小的元素并将其删除。打那个号码n
。如果集合现在为空,则将n+1
放入集合中
要取消分配号码,请将其添加到集合中。然后执行以下清理算法:
步骤1:如果集合有一个元素,则停止
步骤2:如果集合中的最大元素减去第二大元素大于1,则停止
步骤3:移除最大的元素
步骤4:转到步骤2
使用此数据结构和算法,任何k
allocate/deallocate操作序列都需要O(k logk)时间。(即使“清理”操作本身是O(k log k)时间,您也只能在插入元素后删除它,因此总时间不超过O(k log k)。)
换句话说,每个分配/取消分配都需要对数摊销时间。您可以使用队列存储释放的整数,并使用计数器记住最后一个:
Queue s;
int lastUsedInt; //Initialize to 0
void delete( int fileNumber ){
s.push(fileNumber);
}
int getIntForNewFile(){
if( s.empty() ){ //If our queue is empty then there are no unused spaces
return lastUsedInt++; //Return lastUsedInt and increment it by 1
}
else{
int i = s.top(); //Get current top of the queue
s.pop(); //Delete current top of the queue
return i; //Return the retrieved number
}
}
这里有一些Cpp伪代码:)
这将按照删除的顺序“填充”空白点。
因此,如果您有文件1到10,那么删除5和2:5将首先填充,然后是2
如果希望按顺序填充,可以使用已排序的容器。
在C++中,将是一个.使用一个MIN堆存储被删除的项。如果堆为空,则没有可用项。否则,以第一个为例 一个简单的最小堆实现在 要使用它:
BinaryHeap<int> MyHeap = new BinaryHeap<int>();
要获取下一个号码:
if (MyHeap.Count > 0)
nextNumber = MyHeap.RemoveRoot();
else
nextNumber = List.Count;
这保证了您将始终获得最小的可用数字。这实际上只是“查找集合中未使用的最小整数”,尽管如果从字符串开始,我会尝试。。。尝试再试一次。希望有一个小的n;-)这并不能保证您总是分配最小的未使用的数字,我认为这是最大的goal@Nemo:true,已为此添加批注。当用户尝试删除原始列表中的最后一项时,应修剪堆。应删除堆中大于原始列表中新的最后一项的所有项。
if (MyHeap.Count > 0)
nextNumber = MyHeap.RemoveRoot();
else
nextNumber = List.Count;