代码之家  ›  专栏  ›  技术社区  ›  anon

如何在字典中查找重复对?

  •  2
  • anon  · 技术社区  · 14 年前

    我想计算一下TCC度量:

    紧密的阶级凝聚力(TCC) 测量 直接连接的方法对 类ndc(c)中的可见方法和 最大可能方法数 之间的连接对 NP(C)类的可见方法。二 可见方法是直接 已连接,如果他们正在访问 类的相同实例变量。 n是可见方法的数目 导致:

    NP(C) = (n(n-1))/2
    

    TCC(C) = NDC(C) / NP(C)
    

    所以我写了一个方法,它解析了类中我想要检查的所有方法。此方法存储该类中的所有方法,并且在字典中使用的字段如下所示:

    Dictionary<MethodDefinition, IList<FieldReference>> references = new Dictionary<MethodDefinition, IList<FieldReference>>();
    

    那么,现在,我如何迭代这个词汇来检查上面提到的条件呢?如果我理解正确,我必须找到这两对使用相同字段集的方法?那我怎样才能做到最好呢?我想我必须反复检查字典,看看ilist是否包含相同的集合?(即使顺序不同)?

    有什么想法吗?

    我的代码如下,但无法正常工作:

    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;
            }
        }
    
    4 回复  |  直到 14 年前
        1
  •  1
  •   Cheng Chen    14 年前

    既然你没告诉我们,我们怎么能告诉两个呢 FieldReference s是重复的,我将使用默认值。

    LINQ版本:

    int duplicated = references.SelectMany( p => p.Value )
                               .GroupBy(x => x)
                               .Where(g => g.Count() > 1)
                               .Count();
    
        2
  •  2
  •   Jake Kurzer    14 年前

    好吧,如果你不介意再保留一本字典,我们可以用一把大锤子来敲这个东西。
    简单地说,如果我们设想一个字典,其中有序的_集(字段引用)是键,而我们保留每个键的值列表……不用说,这不是最聪明的方法,但它快速、简单,并且使用您已经熟悉的数据结构。

    如:
    hashset< hashset < FieldReference >, Ilist< methods >> Favorite_delicatessen

    为方法生成引用集
    在最喜爱的熟食店中查找参考资料集
    如果有:
    将方法添加到方法列表
    其他:
    添加引用集、方法对

    因此,您的方法列表就是共享相同状态签名的方法列表,如果您允许我创建一个术语的话。

        3
  •  1
  •   johnny    14 年前

    你能用吗 ContainsValue 是否要检查重复项?从您描述的内容来看,只有在 价值观 都是一样的。

        4
  •  1
  •   Dean Chalk    14 年前

    如何获取一个字典,其中键是重复项,值是包含重复项的原始字典中的键列表:

    var dupes = references
        .SelectMany(k => k.Value)
        .GroupBy(v => v)
        .Where(g => g.Count() > 1)
        .ToDictionary(i => i.Key, i => references
            .Where(f => f.Value.Contains(i.Key))
            .Select(o => o.Key));