c# - 我的排序有什么问题?

标签 c# list sorting unity3d

首先,我必须说明我在 Unity 5.3 中工作,而新的 MonoDevelop 不允许我进行调试。 Unity 崩溃了:(

所以我有一个“目标”列表,我需要根据 3 个标准对其进行排序:

  1. 首先应列出“事件”目标
  2. 然后按难度排序
  3. 最终随机获得相同级别的目标

这是我的代码:

public class Goal {
    public int ID;
    public int Level;
    public bool Active;
}

...

List<Goal> goals;

goals.Sort((a, b) => {
    // first chooses the Active ones (if any)
    var sort = b.Active.CompareTo(a.Active);
    if (sort == 0) {
        // then sort by level
        sort = (a.Level).CompareTo(b.Level);
        // if same level, randomize. Returns -1, 0 or 1
        return sort == 0 ? UnityEngine.Random.Range(-1, 2) : sort;
    } else {
        return sort;
    }
});

当我运行这段代码时,有时我会在非事件目标之后获得一个或多个事件目标,但我不明白为什么。

最佳答案

要正确工作,排序算法不应依赖于变异 状态。解释为什么在比较值时使用随机生成器不是一个好主意 is given here .

问题可以通过两种方式解决:

选项 1:预先计算随机数

    var tmp = goals.Select( g=> new {goal = g, weight = rnd.NextDouble()})
        .OrderByDescending(t=>t.goal.Active) // Active first
        .ThenBy(t=>t.goal.Level)
        .ThenBy(t=>t.weight)
        .Select(t=>t.goal)
        .ToList();



    goals.Clear();
    goals.AddRange(tmp);

Working sample

选项 2:排序然后打乱关系

Random rnd = new Random();

Comparison<Goal> comparison =  (a, b) => {
// first chooses the Active ones (if any)
var sort = b.Active.CompareTo(a.Active);

if (sort == 0) {
// then sort by level
    return sort = (a.Level).CompareTo(b.Level);
  } else 
{
   return sort;
}
};



int startIndex = 0;
int endIndex = 0;

goals.Sort(comparison);

while (startIndex < goals.Count)
{
    for (endIndex = startIndex + 1; endIndex < goals.Count; ++endIndex)
    {
       if (comparison(goals[startIndex], goals[endIndex]) != 0)
       {
          //End of tie
          break;
       }
    }

    if (endIndex - startIndex > 1)
    {
       // Shuffle goals of the same level
       ShuffleRange(goals, startIndex, endIndex - startIndex, rnd);
    }

    startIndex = endIndex;
}   

static void ShuffleRange<T>(List<T> list, int startIndex, int count, Random rnd)
{
     int n = startIndex + count;  
     while (n > startIndex + 1) 
     {  
        int k = rnd.Next(startIndex, n--);  
        T value = list[k];  
        list[k] = list[n];  
        list[n] = value;  
    }  
}           

Working sample

Shuffle算法借鉴自here

关于c# - 我的排序有什么问题?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35092917/

相关文章:

algorithm - 这里使用了哪种排序算法

c# - 使用多个 Web Config C#

c# - 及时计算组合

r - 如何多次运行一个函数并将结果写入列表?

c# - 为具有泛型集合的 C# 项目生成 Doxygen

java - 如何根据值对 HashMap 的元素进行排序?

java - 如何在 Java 中按值(ArrayList)大小对 map 进行排序?

c# - 在 Winforms 中画一条线

c# - 在 ScrollViewer Windows Phone 8.0 中将文本换行

jQuery 选择框问题