Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>view my code snippet <a href="http://rextester.com/VUJQ53092" rel="nofollow">here</a>. it's just for first level sorting and not optimized.</p> <p>OrderBy and ThenBy are using general algorithm. you need to re-implement OrderBy and ThenBy with special algorithm like mine. then it can work as <code>OrderBy().ThenBy()</code>.</p> <p><strong>Detail of algorithm:</strong></p> <p>in a sorted sequence(x1 x2 x3...) under your EpsilonComparer, if x4>x1, then x5>x1. if x4=x1, then x3=x1 and either x5>x1 or x5=x1.</p> <p>with epsilon(0.4), input following numbers: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</p> <p>result: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</p> <p><em>(a,b,c)</em> indicates these numbers are equal and the order of numbers is not fixed. they can be (a,b,c), (c,a,b) and any other order.</p> <p><em>a b</em> indicates a &lt; b and order is fixed.</p> <pre><code>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&lt;double&gt; m_comparer; private readonly double[] m_nums; public EpsilonSort(IComparer&lt;double&gt; comparer, params double[] nums) { this.m_comparer = comparer; this.m_nums = nums; } public void Sort() { Node root = new Node(); root.Datas = new List&lt;double&gt;(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 &lt; 0) { this.AddData(ref childrennodes[0], i); } else { this.AddData(ref childrennodes[2], i); } } } childrennodes = childrennodes.Where(x =&gt; x != null).ToArray(); if (childrennodes.Length &gt;= 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&lt;double&gt;(); node.Datas.Add(value); } private class Node { public Node[] Nodes; public List&lt;double&gt; Datas; } } public class EpsilonComparer : IComparer&lt;double&gt; { private readonly double epsilon; public EpsilonComparer(double epsilon) { this.epsilon = epsilon; } public int Compare(double d1, double d2) { if (Math.Abs(d1 - d2) &lt;= epsilon) return 0; return d1.CompareTo(d2); } } } </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload