java比较HashMap中的键和值
我有一个如下的HashMap-
HashMap<String, Integer> BC = new HashMap<String, Integer>();
它存储为键——“令牌/标记”和值——“每个令牌/标记的频率”
范例-
"the/at" 153
"that/cs" 45
"Ann/np" 3
现在,我解析每个键,检查同一标记是否使用“the”,是否与多个标记关联,然后取两个标记中最大的一个
范例-
"the/at" 153
"the/det" 80
然后,我使用值为153
的键"the/at"
我为此编写的代码如下-
private HashMap<String, Integer> Unigram_Tagger = new HashMap<String, Integer>();
for(String curr_key: BC.keySet())
{
for(String next_key: BC.keySet())
{
if(curr_key.equals(next_key))
continue;
else
{
String[] split_key_curr_key = curr_key.split("/");
String[] split_key_next_key = next_key.split("/");
//out.println("CK- " + curr_key + ", NK- " + next_key);
if(split_key_curr_key[0].equals(split_key_next_key[0]))
{
int ck_v = 0, nk_v = 0;
ck_v = BC.get(curr_key);
nk_v = BC.get(next_key);
if(ck_v > nk_v)
Unigram_Tagger.put(curr_key, BC.get(curr_key));
else
Unigram_Tagger.put(next_key, BC.get(next_key));
}
}
}
}
但这段代码的计算时间太长,因为最初的HashMap“BC”有68442个条目,大约等于其平方=4684307364倍(加上更多)
我的问题是——我能用更有效的方法完成同样的输出吗
谢谢
# 1 楼答案
创建一个新的
这将把代币映射到它们的最大数量
只需通过钥匙一次
将每个密钥拆分为其组件令牌
对于每个标记,请查看
highMap
。如果密钥不存在,请添加其计数。如果条目已存在,且当前计数大于上一个最大值,请替换映射中的最大值完成单次传递后,
highCount
将包含所有唯一的令牌,以及每个令牌的最高计数注:此答案旨在为您提供一个起点,从中开发一个完整的解决方案。关键的概念是,您创建并填充一个从令牌到某种“值”类型(不一定只是
Integer
)的新映射,该映射为您提供所需的功能。值类型很可能是存储标记和计数的新自定义类# 2 楼答案
当前方法中最慢的部分是键的成对比较。首先,定义一个
Tuple
类:因此,您可以尝试一种算法:
HashMap<String, Tuple<String, Integer>> result
(key, value)
,其中key="a/b"
,检查result.keySet().contains(a)
和result.keySet().contains(b)
李>a
和b
都不存在,result.put(a, new Tuple<String, Integer>(b, value)
和result.put(b, new Tuple<String, Integer>(a, value))
a
,比较value
和v = result.get(a)
。如果value > v
,从result
中删除a
和b
,然后执行步骤3。对b
执行同样的操作。否则,获取下一个键值对李>在遍历旧的哈希映射并插入所有内容之后,通过转换
result
中的键值,可以轻松地重建所需的输出# 3 楼答案
算法的基本思想:
您应该获取HashMap的entrySet()并将其转换为列表:
现在你应该按字母顺序对列表进行排序。我们这样做是因为HashMap没有顺序,所以可以预期相应的键可能相距很远。但通过对它们进行排序,所有相关的键都是直接相邻的
由于按字母顺序排序,条目“The/at”和“The/det”将彼此相邻
现在,你可以在记住最好的项目的同时遍历整个列表,直到找到更好的项目,或者找到第一个前缀不相同的项目(例如“the”)
现在你应该有一张地图列表。表示所需条目的条目对象。复杂性应为n(对数n),并受排序算法的限制,而分组/收集项目的复杂性为n。
# 4 楼答案