c# - 根据变量变化排序和更新对象列表

标签 c# algorithm list int

我正在研究一种算法来解决我遇到的问题,但我发现自己有点卡住了。这是场景:

我有一个对象,其中包含一个名为 order 的变量。

public class Item
{
     public int Order{get; set;};

     public int ID{get; set;}; // not incremented can be any value!
}

所以我有一个列表:

List<Item> list = new List<Item>().OrderBy((o) => o.Order);

并且可以随时更改订单值。 因此,如果我想更改第一个项目的订单值,所有其他订单值都应相应更新,以免重复。

for (int i = 0; i <= list .Count - 1; i++)
{
    if (list [i].ID == inputID)
    {
        list [i].Order = inputNewPosition;
    }
    else
    {
        if (list [i].Order < inputNewPosition)
        {
            list [i].Order --;
        }
        else
        {
             list [i].Order ++;
        }
    }
}

如果我将最后一个项目顺序更改为第一个,则会失败,因为这会使第一个项目顺序为 0!

有人能帮忙吗?

谢谢

最佳答案

让我们看看列表中某个元素的四种情况(当我们遍历它们时)。如果(为了简洁起见)我们将 old 作为移动的项目的旧位置,将 new 作为其新位置,我们在列表中的项目有以下情况(将它们画在纸上以明确这一点)。

  1. 当前项是要移动的项:直接移动
  2. 当前项目的顺序是<和<:不要移动它
  3. 当前项目的顺序 ≥ new 和 <old:向右移动
  4. 当前项目的顺序≤且>:将其向左移动
  5. 当前项目的顺序是 > new 和 > old:不要移动它

当我们开始枚举时,我们知道要移动的项目将最终到达哪里(new),但我们不知道它来自哪里(old) ).但是,当我们从列表的开头 开始枚举时,我们知道在每一步它都必须在列表中更靠后的位置,直到我们真正看到它!所以我们可以用一个标志(seen)来表示我们是否已经看到了。所以 seen 的 false 意味着 <old 而 true 意味着 >= old

bool seen = false;
for (int i = 0; i < items.Length; i++)
{
    if (items[i].ID == inputID)
    {
        items[i].Order = inputNewPosition;
        seen = true;
    }
}

这个标志告诉我们当前项目是否 >= 。所以现在可以根据这些知识和上述规则开始分流东西。 (所以上面讨论中的 newinputNewPosition 并且无论我们是在 old 之前还是之后,我们都用我们的 seen 来表示变量。)

bool seen;
for (int i = 0; i < items.Count; i++)
{
    if (items[i].ID == inputID) // case 1
    {
        items[i].Order = inputNewPosition;
        seen = true;
    }
    else if (seen) // cases 4 & 5
    {
        if (items[i].Order <= inputNewPosition) // case 4
        {
           items[i].Order--; // move it left
        }
    }
    else // case 2 & 3
    {
        if (items[i].Order >= inputNewPosition) // case 3
        {
            items[i].Order++; // move it right
        }            
    }
}

综上所述,根据每次更改对集合进行排序可能更简单。对于几乎已排序的集合,默认的排序算法应该非常简洁。

关于c# - 根据变量变化排序和更新对象列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14880735/

相关文章:

c# - 警告 CS0618 : 'FirebaseInstanceIdService' is obsolete: 'This class is obsoleted in this android platform

c# - 不支持的媒体类型 ASP.NET Core Web API

c# - 时间线中可调整大小的片段 : bind segment size to view model

c - 嵌套的 while 循环。内循环不满足条件

java - 从文件中读取不同类型的数据

python - 如何附加到深度嵌套在字典中的列表并保留嵌套结构?

c# - 当搜索没有结果时抛出一个弹出窗口

algorithm - 我可以一次又一次地应用霍夫曼编码吗?

python - 如何将 python 列表中的第 n 个条目相互添加?

r - 对子元素具有相同名称的列表元素求和