查看我的代码片段这里。它只是用于一级排序,没有进行优化。
OrderBy和ThenBy使用通用算法。您需要使用类似于我的特殊算法重新实现OrderBy和ThenBy。然后它可以像OrderBy().ThenBy()
一样工作。
算法详情:
在您的EpsilonComparer下排序序列(x1 x2 x3...)中,如果x4>x1,则x5>x1。如果x4=x1,则x3=x1,并且x5>x1或x5=x1。
使用epsilon(0.4),输入以下数字:0.1、0.6、1、1.1、1.6、2、2、2.6、3、3.1、3.6、4、4.1、4.6、5、5.1、5.6、6、6.1、6.6
结果:0.1 0.6 1 1.1 (1.6 2 2 ) 2.6 3 3.1 3.6 4 4.1 4.6 (5 5.1 ) 5.6 (6 6.1 ) 6.6
(a,b,c) 表示这些数字相等,数字的顺序不固定。它们可以是(a,b,c),(c,a,b)和任何其他顺序。
a b 表示 a < b 并且顺序固定。
using System;
using System.Collections.Generic;
using System.Linq;
namespace Rextester
{
class Program
{
public static void Main(string[] args)
{
new EpsilonSort(new EpsilonComparer(0.4), 0.1, 0.6, 1, 1.1, 1.6, 2, 2, 2.6, 3, 3.1, 3.6, 4, 4.1, 4.6, 5, 5.1, 5.6, 6, 6.1, 6.6).Sort();
}
}
public class EpsilonSort
{
private readonly IComparer<double> m_comparer;
private readonly double[] m_nums;
public EpsilonSort(IComparer<double> comparer, params double[] nums)
{
this.m_comparer = comparer;
this.m_nums = nums;
}
public void Sort()
{
Node root = new Node();
root.Datas = new List<double>(this.m_nums);
foreach (double i in (double[])this.m_nums.Clone())
{
this.ProcessNode(i, root);
}
this.OutputNodes(root);
}
private void OutputNodes(Node root)
{
if (root.Datas == null)
{
foreach (var i in root.Nodes)
{
this.OutputNodes(i);
}
}
else
{
if (root.Datas.Count == 1)
{
Console.WriteLine(root.Datas[0]);
}
else
{
Console.Write('(');
foreach (var i in root.Datas)
{
Console.Write(i);
Console.Write(' ');
}
Console.WriteLine(')');
}
}
}
private void ProcessNode(double value, Node one)
{
if (one.Datas == null)
{
foreach (var i in one.Nodes)
{
this.ProcessNode(value, i);
}
}
else
{
Node[] childrennodes = new Node[3];
foreach (var i in one.Datas)
{
int direction = this.m_comparer.Compare(i, value);
if (direction == 0)
{
this.AddData(ref childrennodes[1], i);
}
else
{
if (direction < 0)
{
this.AddData(ref childrennodes[0], i);
}
else
{
this.AddData(ref childrennodes[2], i);
}
}
}
childrennodes = childrennodes.Where(x => x != null).ToArray();
if (childrennodes.Length >= 2)
{
one.Datas = null;
one.Nodes = childrennodes;
}
}
}
private void AddData(ref Node node, double value)
{
node = node ?? new Node();
node.Datas = node.Datas ?? new List<double>();
node.Datas.Add(value);
}
private class Node
{
public Node[] Nodes;
public List<double> Datas;
}
}
public class EpsilonComparer : IComparer<double>
{
private readonly double epsilon;
public EpsilonComparer(double epsilon)
{
this.epsilon = epsilon;
}
public int Compare(double d1, double d2)
{
if (Math.Abs(d1 - d2) <= epsilon) return 0;
return d1.CompareTo(d2);
}
}
}
{ 0.3, 1.5 }, { 0.6, 4.5 }, { 0.9, 3 }
,看看你会得到什么。 - ohmusama(0.3, 1.5) (0.6, 4.5) (0.9, 3)
,这是我所期望的,但这并不能说明一般情况。 (代码可在此处在线测试:http://rextester.com/ZKGV94991) - HugoRune