D 如何删除关联数组中最近访问最少的键?
我有一个限制为x数量的键的关联数组,并希望删除最近访问最少的键以添加另一个键。我在mintl找到了HashAA,它可以在D1中完成任务,但在D2中我什么也没找到。现在是否有任何东西支持此功能,或者我需要维护第二个阵列来完成此工作?我没有真正的答案,但我认为在几分钟内尝试并实现它会很有趣(可能效率很低,可能有问题):D 如何删除关联数组中最近访问最少的键?,d,D,我有一个限制为x数量的键的关联数组,并希望删除最近访问最少的键以添加另一个键。我在mintl找到了HashAA,它可以在D1中完成任务,但在D2中我什么也没找到。现在是否有任何东西支持此功能,或者我需要维护第二个阵列来完成此工作?我没有真正的答案,但我认为在几分钟内尝试并实现它会很有趣(可能效率很低,可能有问题): 导入标准stdio; 输入性病性状; 结构MyHash(AA,大小限制) 如果(isAssociativeArray!AA) { 别名KeyType!AA密钥; 别名ValueTyp
导入标准stdio;
输入性病性状;
结构MyHash(AA,大小限制)
如果(isAssociativeArray!AA)
{
别名KeyType!AA密钥;
别名ValueType!AA值;
void opIndexAssign(值、键)
{
如果(hash.length>=限制)
{
密钥leastUsed=leastUsedKey;
散列。删除(已删除);
计数。移除(已移除);
}
散列[键]=值;
}
值opIndex(键)
{
计数[键]+;
返回散列[键];
}
值[键]散列;
别名散列这个;
私人:
@属性键leastUsedKey()
{
关键成果;
size\u t maxCount=size\u t.max;
foreach(key;hash.byKey)
{
if(自动计数=输入计数)
{
如果(*计数<最大计数)
{
maxCount=*计数;
结果=键;
}
}
其他的
{
返回键;
}
}
返回结果;
}
大小[键]计数;
}
//只是为了避免在main()中声明变量
@属性void consume(int key){}
void main()
{
MyHash!(int[int],3)hash;
散列[0]=0;
散列[1]=0;
散列[2]=0;
writeln(散列键);
散列[2]。消费;
散列[5]=0;
writeln(hash.keys);//保留2次,添加5次
hash.clear();
散列[0]=0;
散列[1]=0;
散列[2]=0;
散列[0]。消耗;
散列[1]。消费;
散列[1]。消费;
散列[2]。消费;
散列[2]。消费;
散列[2]。消费;
散列[5]=0;
writeln(散列);//(已删除0)
}
内置AAs将在需要时重新刷新以适应更多元素,大小不固定,也不会跟踪您访问或添加元素的方式,而且由于该语言内置了AAs,替代哈希表实现将相对较少(大多数人都只使用内置AAs)
所以,我非常确定您需要自己做这件事——可能是围绕内置的AA类型创建一个包装器,让包装器跟踪对它的所有访问,以便它知道最近访问了哪个密钥
您可以随时查看一些替代容器实现(IIRC it中确实有一个哈希表,但我怀疑它是否能满足您的需要)。就我个人而言,我从来没有听说过哈希表按照您希望的方式运行,所以我认为您所寻找的至少有点不正常。但它应该足够简单,可以围绕AAs创建一个包装器,按照您想要的方式运行。删除最近使用最少的添加值是标准缓存行为
import std.stdio;
import std.traits;
struct MyHash(AA, size_t Limit)
if (isAssociativeArray!AA)
{
alias KeyType!AA Key;
alias ValueType!AA Value;
void opIndexAssign(Value value, Key key)
{
if (hash.length >= Limit)
{
Key leastUsed = leastUsedKey;
hash.remove(leastUsed);
counts.remove(leastUsed);
}
hash[key] = value;
}
Value opIndex(Key key)
{
counts[key]++;
return hash[key];
}
Value[Key] hash;
alias hash this;
private:
@property Key leastUsedKey()
{
Key result;
size_t maxCount = size_t.max;
foreach (key; hash.byKey)
{
if (auto count = key in counts)
{
if (*count < maxCount)
{
maxCount = *count;
result = key;
}
}
else
{
return key;
}
}
return result;
}
size_t[Key] counts;
}
// just to avoid declaring variables in main()
@property void consume(int key) { }
void main()
{
MyHash!(int[int], 3) hash;
hash[0] = 0;
hash[1] = 0;
hash[2] = 0;
writeln(hash.keys);
hash[2].consume;
hash[5] = 0;
writeln(hash.keys); // 2 stays, 5 added
hash.clear();
hash[0] = 0;
hash[1] = 0;
hash[2] = 0;
hash[0].consume;
hash[1].consume;
hash[1].consume;
hash[2].consume;
hash[2].consume;
hash[2].consume;
hash[5] = 0;
writeln(hash); // (0 removed)
}