如何在字典中找到重复的对? [英] How to find duplicate pairs in a Dictionary?

查看:140
本文介绍了如何在字典中找到重复的对?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想计算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 FieldReferences 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆