【问题标题】:IEqualityComparer That Will Find The Next Closest ElementIEqualityComparer 将找到下一个最接近的元素
【发布时间】:2014-06-26 04:37:43
【问题描述】:

是否可以为SortedList <double, GameObject> 编写一个IEqualityComparer 以返回“下一个最近”double

例如;

SortedList <double, GameObject> list = new SortedList <double, GameObject>(new MyComparer());
list[0.00] = go1;
list[1.00] = go2;

list[0.55]; // should return go2. Ie, find the next-closest key, value pair 
            // and return that

可以这样做吗?我是否使用IEqualityComparer 来实现这一点?

#region Comparator
public class MyComparer : IEqualityComparer<double> // should this be Pair<double, GameObject> instead?
{
    public bool Equals(double a, double b)
    {
        return (Math.Abs(a-b) <= 0.01);
    }

}
#endregion

PS:如果我添加我自己的自定义比较器 (IEqualityComparer) - 我的 SortedList 的排序和搜索算法是否仍保留为二分搜索?通过更改比较器,我是否使SortedList 的效率大大降低?我刚刚降低了lookupinsertion 的效率吗?

【问题讨论】:

  • 排序算法因 .NET 框架版本而异。相等比较器与排序无关。排序使用 IComparer(或间接使用 IComparer、IComparable、IComparable)
  • 你应该非常小心地做这样的事情,改变这样的接口的含义,特别是平等。我强烈建议您不要这样做,无论您最终要更改哪个界面。例如,如果x == yy == z 那么你应该有x == z,但是如果你开始进行“足够接近”的比较,你可能不允许这样做。例如,如果“足够接近”介于 0.5 或更低之间,则 0.5 == 1.01.0 == 1.50.5 != 1.5 (使用新的 == 和 != 运算符)。 不要这样做!找到表达意图的不同方式。

标签: c# comparator binary-search


【解决方案1】:

请使用以下程序进行此修复。是的,由于四舍五入,会有一点开销。如果您检索到 0.45,它将返回您 A,而 1.55 将返回您 C。

  class SortedListTest
    {
        public static void Test()
        {
            var list = new SortedList<double, string>(new MyComparer());

            list[0.00] = "A";
            list[1.00] = "B";
            list[2.00] = "C";

            Console.WriteLine(list[0.55]);
        }
        private static void Main()
        {
            SortedListTest.Test();
        }
    }

    internal class MyComparer : IComparer<double>
    {
        public int Compare(double x, double y)
        {
            return (int) (Math.Round(x) - Math.Round(y));
        }

    }

【讨论】:

  • 如果您的列表不包含您要四舍五入的键,则会出现异常。
  • @KajalSinha 感谢您的回答,但这仅适用于整数。
  • @Jake M :它适用于双倍并且您正在比较双倍。如果您愿意,您甚至可以比较小数位。 compare 方法返回小于 0 或 0 或大于 0。小于 0 表示在比较过程中选择下限,大于 0 表示选择上限。
【解决方案2】:

我强烈怀疑这是可能的。 IQualityComparerEquals 方法在使用双精度索引 SortedList 时甚至不会被调用!

我建议创建一个继承自 SortedList 并覆盖 Indexer 的新类 ([])。

此示例将返回下一个最高键的值。如果没有更高的键,则返回最高键的值:

   class Program
   {
      static void Main(string[] args)
      {
         var list = new MySortedList();

         list[0.5] = "A";
         list[1.0] = "B";
         list[3.0] = "C";

         Console.WriteLine(list[-0.6]); // writes: A
         Console.WriteLine(list[0.1]); // writes: A
         Console.WriteLine(list[0.6]); // writes: B
         Console.WriteLine(list[1.1]); // writes: C
         Console.WriteLine(list[1.2]); // writes: C
         Console.WriteLine(list[4.0]); // writes: C
      }
   }

   class MySortedList : SortedList<double, string>
   {
      new public string this[double key]
      {
         get
         {
            double newKey = Keys.FirstOrDefault(p => p >= key);
            if (!Keys.Contains(newKey)) newKey = Keys.Max();
            return base[newKey];
         }
         set
         {
            base[key] = value;
         }
      }
   }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-10-24
    • 1970-01-01
    • 2023-03-20
    • 1970-01-01
    • 2019-10-27
    • 2021-02-16
    • 1970-01-01
    相关资源
    最近更新 更多