如何在字典中找到重复的对? [英] How to find duplicate pairs in a Dictionary?
问题描述
我想计算TCC指标:
紧班级凝聚力(TCC) 测量的数量的比值 方法对直接连接的 在一类的NDC(C)的可见的方法和 的最大可能的方法数 对之间的连接的 一类NP(C)可见的方法。二 可见的方法是直接 连接,如果它们正在访问 类的同一个实例变量。 n是可见的方法数 导致:
NP(C)=(N(N-1))/ 2
和
台泥(C)= NDC(C)/ NP(C)
所以我写了通过,我要检查的类的所有方法的分析方法。这种方法存储在类的所有方法,并有他们的字典,这些看起来像这样使用字段:
词典< MethodDefinition,IList的< FieldReference>>引用=新字典< MethodDefinition,IList的< FieldReference>>();
所以,现在,我怎么通过这个dictionnary重复检查上述条件?如果我理解正确的话我一定要找到这两对方法,这些方法都使用相同的字段集?然后,我怎么能做到这一点的最好方法是什么?我想我必须遍历字典,看看是否IList中包含了相同的一组? (即使是在不一样的顺序)?
任何奥德ideas`?
我的code是下面的,但它不能正常工作:
类TCC
{
公共静态INT计算(类型定义类型)
{
诠释计数= 0;
字典< MethodDefinition,HashSet的< FieldReference>>引用=新字典< MethodDefinition,HashSet的< FieldReference>>();
的foreach(在type.Methods MethodDefinition法)
{
如果(method.IsPublic)
{
references.Add(方法,calculateReferences(方法));
}
}
的for(int i = 0; I< references.Keys.Count;我++)
{
HashSet的< FieldReference>名单=新的HashSet< FieldReference>();
references.TryGetValue(references.Keys.ElementAt(i)中,出清单);
如果(isPair(引用列表)){
算上++;
}
}
如果(计数大于0)
{
数=计数/ 2;
}
返回计数;
}
私有静态布尔isPair(词典< MethodDefinition,HashSet的< FieldReference>>引用的HashSet< FieldReference>比较)
{
对于(INT J = 0; J< references.Keys.Count; J ++)
{
HashSet的< FieldReference> compareList =新的HashSet< FieldReference>();
references.TryGetValue(references.Keys.ElementAt(J),出compareList);
的for(int i = 0; I< compare.Count;我++)
{
如果(containsAllElements(compareList,比较)){
返回true;
}
}
}
返回false;
}
私有静态布尔containsAllElements(HashSet的< FieldReference> compareList,HashSet的< FieldReference>比较)
{
的for(int i = 0; I< compare.Count;我++)
{
如果(!compareList.Contains(compare.ElementAt(ⅰ)))
{
返回false;
}
}
返回true;
}
私有静态HashSet的< FieldReference> calculateReferences(MethodDefinition法)
{
HashSet的< FieldReference>引用=新的HashSet< FieldReference>();
的foreach(在method.Body.Instructions指令指令)
{
如果(instruction.Op code ==运算codes.Ldfld)
{
FieldReference场= instruction.Operand为FieldReference;
如果(场!= NULL)
{
references.Add(场);
}
}
}
返回参考;
}
}
既然你没有告诉我们,我们该怎么告诉两个 FieldReference
s的重复,我将用默认的。
LINQ版本:
INT重复= references.SelectMany(P => p.Value)
.GroupBy(X =&X的催化剂)
。凡(克=> g.Count()→1)
。计数();
I'd like to calculate the TCC metric:
The Tight Class Cohesion (TCC) measures the ratio of the number of method pairs of directly connected visible methods in a class NDC(C) and the number of maximal possible method pairs of connections between the visible methods of a class NP(C). Two visible methods are directly connected, if they are accessing the same instance variables of the class. n is the number of visible methods leading to:
NP(C) = (n(n-1))/2
and
TCC(C) = NDC(C) / NP(C)
So i wrote a method that parse through all methods in the class i want to check. This method stores all methods in that class and there fields they are using in a dictionary that looks like this:
Dictionary<MethodDefinition, IList<FieldReference>> references = new Dictionary<MethodDefinition, IList<FieldReference>>();
So now, how do I iterate through this dictionnary to check the condition mentioned above? If I understand it correctly I have to find these two pairs of methods that are using the same set of fields? Then how can I do this the best way? I think I have to iterate over the dictionary and see if the IList contains the same set? (even not in the same order)?
Any oder ideas`?
My code is the following, but it does not work correctly:
class TCC
{
public static int calculate(TypeDefinition type)
{
int count = 0;
Dictionary<MethodDefinition, HashSet<FieldReference>> references = new Dictionary<MethodDefinition, HashSet<FieldReference>>();
foreach (MethodDefinition method in type.Methods)
{
if (method.IsPublic)
{
references.Add(method, calculateReferences(method));
}
}
for (int i = 0; i < references.Keys.Count; i++)
{
HashSet<FieldReference> list = new HashSet<FieldReference>();
references.TryGetValue(references.Keys.ElementAt(i), out list);
if (isPair(references, list)) {
count++;
}
}
if (count > 0)
{
count = count / 2;
}
return count;
}
private static bool isPair(Dictionary<MethodDefinition, HashSet<FieldReference>> references, HashSet<FieldReference> compare)
{
for (int j = 0; j < references.Keys.Count; j++)
{
HashSet<FieldReference> compareList = new HashSet<FieldReference>();
references.TryGetValue(references.Keys.ElementAt(j), out compareList);
for (int i = 0; i < compare.Count; i++)
{
if (containsAllElements(compareList, compare)) {
return true;
}
}
}
return false;
}
private static bool containsAllElements(HashSet<FieldReference> compareList, HashSet<FieldReference> compare)
{
for (int i = 0; i < compare.Count; i++)
{
if (!compareList.Contains(compare.ElementAt(i)))
{
return false;
}
}
return true;
}
private static HashSet<FieldReference> calculateReferences(MethodDefinition method)
{
HashSet<FieldReference> references = new HashSet<FieldReference>();
foreach (Instruction instruction in method.Body.Instructions)
{
if (instruction.OpCode == OpCodes.Ldfld)
{
FieldReference field = instruction.Operand as FieldReference;
if (field != null)
{
references.Add(field);
}
}
}
return references;
}
}
Since you didn't tell us how can we tell two FieldReference
s are duplicated, I will use the default.
LINQ version:
int duplicated = references.SelectMany( p => p.Value )
.GroupBy(x => x)
.Where(g => g.Count() > 1)
.Count();
这篇关于如何在字典中找到重复的对?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!