防止在字典c#中作为值添加的对象的重复变量

Posted

技术标签:

【中文标题】防止在字典c#中作为值添加的对象的重复变量【英文标题】:Prevent duplicate variables of the objects added as Values in a dictionary c# 【发布时间】:2021-12-18 17:09:53 【问题描述】:

我的Individual 班级中有一个Dictionary<int,int>

 public class Individual
    
       Dictionary<int,int> pattern = new Dictionary<int,int>();
    

我想在我的 population 字典中添加一个 &lt;int,Individual&gt; 对:

Dictionary<int,Individual> population = new Dictionary<int, Individual>();

当且仅当字典中没有其他 Individual 具有类似的 pattern 变量。

我目前的方法是天真地迭代每个Individual 中的每个pattern 已经存在于population,但我相信使用不同的方法可以更快地完成。

public bool same_dict(Dictionary<int, int> p1, Dictionary<int, int> p2)
//Meant to compare patterns

    if (p1.Count != p1.Count) return false;
    foreach (var feature in p1)
    
        if (p2.ContainsKey(feature.Key))
        
            if (feature.Value != p2[feature.Key]) return false;
        
        else return false;
    
    return true;


public bool matched is_duplicated(Individual ind, Dictionary<int, Individual> pop)

//Meant to compare Individuals
    foreach (var ind2 in pop)
    
        if (same_dict(ind.pattern, ind2.Value.pattern))
        
            return true;
        
    
    return false;
 

我必须使用ints 作为population 字典的键,因为我使用它来链接Individual 对象与程序的其他部分。 pattern 字典可以包含任意数量的键:值对,这就是我验证它们的 .Count 属性是否相同的原因。

【问题讨论】:

【参考方案1】:

我不确定我是否正确理解了您的问题,但是...

当且仅当字典中没有其他个人具有 相似模式变量

“类似的模式变量”意味着,我认为,两个IndividualPattern 字典,其中包含相同的键和值(不知道,它可以有多少“模式”商店)。

所以我尝试使用 LINQ 的.Any() 扩展方法来检查population 字典中的任何IndividualPattern 字典与添加的Individual 具有相同的键和值。听起来很复杂,所以这里是代码示例(控制台):

public class Individual

    public Dictionary<int, int> Pattern  get; set;  = new Dictionary<int, int>();


static void Main()

    var population = new Dictionary<int, Individual>();
    var key = 0;

    for (; key < 5; key++) // Fill population with some Individuals
    
        var individual = new Individual();
        individual.Pattern.Add(key + 1, key + 2);

        population.Add(key, individual);
    

    // Print current population:
    Console.WriteLine("Population Dictionary:");
    foreach (var kvp in population)
        Console.WriteLine(kvp.Key + ": " +
                          string.Join(" | ", kvp.Value.Pattern.Select(pattern => pattern.Key + "," + pattern.Value)));

    // Creating new Individuals, which we will try to add to population
    var newIndividual1 = new Individual();
    newIndividual1.Pattern.Add(5, 6);
    var newIndividual2 = new Individual();
    newIndividual2.Pattern.Add(5, 5);
    var newIndividual3 = new Individual();
    newIndividual3.Pattern.Add(8, 9);

    Console.WriteLine();
    Console.WriteLine("Adding new Individuals:");

    if (AddIndividual(population, key, newIndividual1))
        key++;

    if (AddIndividual(population, key, newIndividual2))
        key++;

    if (AddIndividual(population, key, newIndividual3))
        key++;

    Console.ReadKey();


static bool AddIndividual(Dictionary<int, Individual> population, int newKey, Individual newIndividual)

    // Compare each Individual in population with newIndividual
    if (!population.Any(p => newIndividual.Pattern.Keys.Any(k => p.Value.Pattern.ContainsKey(k)) &&
                             newIndividual.Pattern.Values.Any(v => p.Value.Pattern.ContainsValue(v))))
    
        population.Add(newKey, newIndividual);
        Console.WriteLine("Individual with pattern " +
                          string.Join(" | ", newIndividual.Pattern.Select(pattern => pattern.Key + "," + pattern.Value)) +
                          " successfully added to Population Dictionary.");

        return true;
    
    else
    
        Console.WriteLine("Individual with pattern " +
                          string.Join(" | ", newIndividual.Pattern.Select(pattern => pattern.Key + "," + pattern.Value)) +
                          " already exists in Population Dictionary.");

        return false;
    

输出样本:

编辑。

您可以将.Any 方法的键值比较替换为.SequenceEqual

if (!population.Any(p => p.Value.Pattern.OrderBy(kvp => kvp.Key).SequenceEqual(newIndividual.Pattern.OrderBy(kvp => kvp.Key))))

    population.Add(newKey, newIndividual);

【讨论】:

你的问题是对的。如果一个人的模式字典具有相同的键和相同的值,则他们与另一个人相似。所述字典可以包含任意数量的键、值对。我首先验证两个字典的计数是否相等,从而加快了这个过程。如果是,我会遍历每个键:值对。您的解决方案有效,并且与我正在做的非常相似,但使用“.Any”而不是手动迭代。这是否意味着没有更快的方法在字典中查找重复项?我期待某种哈希表解决方案,但我无法想象它是这样的。 您对此有性能问题吗?为什么需要更快? 您还可以将.Any 的比较键和值替换为.SequenceEqual。例如检查编辑。

以上是关于防止在字典c#中作为值添加的对象的重复变量的主要内容,如果未能解决你的问题,请参考以下文章

防止在数组中添加重复值

c#如何从根本上防止重复提交相同的数据

防止将重复的对象添加到 state react redux

将 os.system 的输出分配给一个变量并防止它显示在屏幕上[重复]

无法防止双重输入 c# listview

防止线程并发导致事务的重复执行