Advertisement
Guest User

Untitled

a guest
Nov 22nd, 2017
67
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 5.33 KB | None | 0 0
  1. using System;
  2. using System.Collections.Generic;
  3.  
  4. namespace CircualBuffer
  5. {
  6.     class MainClass
  7.     {
  8.         public static void Main (string[] args)
  9.         {
  10. //          var bufferItems = new BufferItem[] {
  11. //              new BufferItem("001", "foo"),
  12. //              new BufferItem("001", "bar"),
  13. //              new BufferItem("001", "baz"),
  14. //              new BufferItem("002", "foo"),
  15. //              new BufferItem("002", "baz"),
  16. //              new BufferItem("003", "foo"),
  17. //              new BufferItem("004", "foo"),
  18. //              new BufferItem("005", "foo"),
  19. //              new BufferItem("006", "foo"),
  20. //              new BufferItem("006", "bar"),
  21. //              new BufferItem("006", "baz"),
  22. //          };
  23.  
  24. //          var bufferItems = new BufferItem[] {
  25. //              new BufferItem("1", ""),
  26. //              new BufferItem("1", ""),
  27. //              new BufferItem("1", ""),
  28. //              new BufferItem("1", ""),
  29. //              new BufferItem("2", ""),
  30. //              new BufferItem("2", ""),
  31. //              new BufferItem("3", ""),
  32. //              new BufferItem("3", "")
  33. //          };
  34.  
  35.             var bufferItems = new BufferItem[] {
  36.                 new BufferItem("1", ""),
  37.                 new BufferItem("1", ""),
  38.                 new BufferItem("1", ""),
  39.                 new BufferItem("2", ""),
  40.                 new BufferItem("2", ""),
  41.                 new BufferItem("3", ""),
  42.                 new BufferItem("4", ""),
  43.                 new BufferItem("5", ""),
  44.                 new BufferItem("6", ""),
  45.                 new BufferItem("6", ""),
  46.                 new BufferItem("6", "")
  47.             };
  48.  
  49.  
  50.             var result = BufferItemSorter.Sort (bufferItems);
  51.  
  52.             for (int i = 0; i < result.Length; i++)
  53.             {
  54.                 Console.Write (result [i].Preffix);
  55.                 Console.Write (":");
  56.                 Console.Write (result [i].Value);
  57.  
  58.                 Console.WriteLine ();
  59.             }
  60.  
  61.             Console.ReadLine ();
  62.         }
  63.     }
  64.  
  65.     public static class BufferItemSorter
  66.     {
  67.         public static BufferItem[] Sort(BufferItem[] items)
  68.         {  
  69.             var sortedItems = CreateSortedArrayCopy(items, new BufferItemComparer());
  70.  
  71.             var clusters = CreateClusters(sortedItems);
  72.  
  73.             if (clusters.Length == 1)
  74.             {
  75.                 throw new ArgumentException ("argument sequence contains same preffix");
  76.             }
  77.  
  78.             if (clusters [0].Length == 1)
  79.             {
  80.                 return sortedItems;
  81.             }
  82.  
  83.             var resultItems = new BufferItem[items.Length];
  84.             var busySlots = new bool[items.Length];
  85.  
  86.             for (int i = 0; i < clusters[0].Length; i++)
  87.             {
  88.                 var itemPosition = i * clusters [0].MinDistance;
  89.                 resultItems [itemPosition] = sortedItems [clusters [0].StartIndex + i];
  90.                 busySlots[itemPosition] = true;
  91.             }
  92.  
  93.             for (int i = 1; i < clusters.Length; i++)
  94.             {
  95.                 var currentCluster = clusters[i];
  96.  
  97.                 var itemPosition = i;
  98.                 for (var j = 0; j < currentCluster.Length; j++)
  99.                 {
  100.                     if (j != 0)
  101.                     {
  102.                         itemPosition = itemPosition + currentCluster.MinDistance;
  103.                     }
  104.  
  105.                     while (busySlots[itemPosition] != false)
  106.                     {
  107.                         itemPosition++;
  108.                     }  
  109.  
  110.                     resultItems [itemPosition] = sortedItems [currentCluster.StartIndex + j];
  111.                     busySlots[itemPosition] = true;
  112.                 }
  113.             }
  114.  
  115.             return resultItems;
  116.         }
  117.  
  118.         private static T[] CreateSortedArrayCopy<T>(T[] items, IComparer<T> comparer)
  119.         {
  120.             var buffer = new T[items.Length];
  121.             Array.Copy(items, buffer, buffer.Length);
  122.             Array.Sort(buffer, comparer);
  123.  
  124.             return buffer;
  125.         }
  126.  
  127.         private static ClusterData[] CreateClusters (BufferItem[] sortedItems)
  128.         {
  129.             var clusterList = new LinkedList<ClusterData> ();
  130.  
  131.             var index = 1;
  132.             var clusterStartIndex = 0;
  133.             while (index < sortedItems.Length)
  134.             {
  135.                 var lastItem = sortedItems.Length - index == 1;
  136.                 if (sortedItems[index].Preffix != sortedItems[clusterStartIndex].Preffix || lastItem)
  137.                 {
  138.                     var clusterLength = index - clusterStartIndex;
  139.                     if (lastItem)
  140.                     {
  141.                         clusterLength++;
  142.                     }
  143.                     var minDistance = sortedItems.Length / clusterLength;
  144.                     var maxDistance = sortedItems.Length % clusterLength > 0
  145.                             ? minDistance + 1
  146.                             : minDistance;
  147.                     var cluster = new ClusterData(minDistance, maxDistance, clusterStartIndex, clusterLength);
  148.                     clusterList.AddLast (cluster);
  149.  
  150.                     clusterStartIndex = index;
  151.                 }
  152.  
  153.                 index++;
  154.             }
  155.  
  156.             var resultArray = new ClusterData[clusterList.Count];
  157.             var arrayIndex = 0;
  158.             foreach (var cluster in clusterList)
  159.             {
  160.                 resultArray [arrayIndex] = cluster;
  161.                 arrayIndex++;
  162.             }
  163.             var sortedArray = CreateSortedArrayCopy (resultArray, new ClusterDataLengthDescComparer ());
  164.  
  165.             return sortedArray;
  166.         }
  167.  
  168.         private struct ClusterData
  169.         {
  170.             public readonly int MinDistance;
  171.  
  172.             public readonly int MaxDistance;
  173.  
  174.             public readonly int StartIndex;
  175.  
  176.             public readonly int Length;
  177.  
  178.             public ClusterData(int minDistance, int maxDistaince, int startIndex, int length)
  179.             {
  180.                 MinDistance = minDistance;
  181.                 MaxDistance = maxDistaince;
  182.                 StartIndex = startIndex;
  183.                 Length = length;
  184.             }
  185.         }
  186.  
  187.         private class ClusterDataLengthDescComparer : IComparer<ClusterData>
  188.         {
  189.             public int Compare(ClusterData val1, ClusterData val2)
  190.             {
  191.                 return val1.Length.CompareTo (val2.Length) * -1;
  192.             }
  193.         }
  194.     }
  195.  
  196.     public struct BufferItem
  197.     {
  198.         public readonly string Preffix;
  199.  
  200.         public readonly string Value;
  201.  
  202.         public BufferItem(string preffix, string value)
  203.         {
  204.             Preffix = preffix;
  205.             Value = value;
  206.         }
  207.     }
  208.  
  209.     public class BufferItemComparer : IComparer<BufferItem>
  210.     {
  211.         public int Compare(BufferItem val1, BufferItem val2)
  212.         {
  213.             var compareResult = val1.Preffix.CompareTo (val2.Preffix);
  214.  
  215.             if (compareResult != 0)
  216.             {
  217.                 return compareResult;
  218.             }
  219.  
  220.             return val1.Value.CompareTo (val2.Value);
  221.         }
  222.     }
  223. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement