字典与优先事项

时间:2013-09-17 15:04:14

标签: c# algorithm dictionary

我有一个类Item和一个Items字典。字典中的每个项目都具有唯一的优先级(1到N)。当我从字典中删除项目时,所有其他优先级都会更新。我想在字典中实现一些增加/减少优先级。如果我想增加单个项目的优先级,我将优先级与下一个较低项目交换。问题是增加项目集合的优先级

public class Item
{
    public string key;
    public string data;
    public int Priority;
}

Dictionary<string, Item> allItems = new Dictionary<string, Item>();

public void AddToQueue(Item item)
{
    item.Priority = allItems.Count + 1;
    allItems[item.key] = item;
}

public void PriorityUp(Item it)
{
    if(it.Priority <= 1)
        return;

    it.Priority--;

    foreach(var item in allItems )
        if(item.Value.Priority == it.Priority)
        {
            item.Value.Priority++;
            break;
        }
}

public void PriorityUp(IEnumerable<Item> items)
{
    //TODO
}

我有字典以便有效地找到一个项目。 提高某些项目的优先级必须对其他项目的优先级做出一些改变

更清楚:我有N个项目的集合(列表,数组,字典......)我选择了字典,因为我还必须做一些其他的操作。每个项目具有字段优先级,其具有一些唯一值1&lt; = P&lt; = N。

当我选择一些并增加/减少P时,我想找到所有项目的结果优先级(1到N)。

3 个答案:

答案 0 :(得分:5)

为什么不使用OrderedDictionary呢?然后字典中的顺序可以是您的优先级,如果您需要交换优先级,您可以只交换项目。但是,它确实意味着如果您添加/删除/插入它将只为您处理优先级。

这种方法可以提高优先级,你可以调用RemoveAt(oldPriority)和Insert(newPriority)。

答案 1 :(得分:1)

使用字典不会特别有效。我建议像(自我平衡)binary search tree(BST)。

我说“类似”,因为我们实际上并不想明确存储优先级,因为否则我们需要经常更新其中的许多优先级。

每个节点都需要有一个count个子节点,因此,当在树上向下插入或删除时,我们知道是基于节点的count向左还是向右移动。删除后,我们还可以返回树并更新count s。

根据BST,插入和删除将采用O(log n)

您需要自己实现此数据结构,因为它是BST的修改版本,但实现类似red-black tree的内容并不太难。

同样,可能只是任何修改过的已排序容器都可以。

除了当前容器之外,您可能还需要此结构,因为您似乎需要按string进行查找。

这是更有效的解决方案,但需要付出更多努力。

答案 2 :(得分:0)

好的,参考OP的评论,我猜他们需要的是:

public void PriorityUp(Item it)
{
    if (DecreasePriority(it))
    {
        IncreaseOther(it.Priority, new[] { it });
    }
}

public void PriorityUp(IEnumerable<Item> items)
{
    List<int> toDecrease = new List<int>();
    foreach (var item in items)
    {
        if (DecreasePriority(item))
        {
            toDecrease.Add(item.Priority);
        }
    }

    foreach(var p in toDecrease)
    {
        IncreaseOther(p, items);
    }
}

private bool DecreasePriority(Item it)
{
    if(it.Priority <= 1)
    {
        return false;
    }

    it.Priority--;

    return true;
}

private void IncreaseOther(int priority, IEnumerable<Item> toIgnore)
{
    foreach (var item in allItems.Values.Except(toIgnore))
    {
        if (item.Priority == priority)
        {
            item.Value.Priority++;
        }
    }
}

但我不知道这一切是什么。也许考虑其他答案中提出的设计。