Advertisement
Guest User

SplitOnLength

a guest
Dec 30th, 2010
210
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 7.63 KB | None | 0 0
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Diagnostics;
  4.  
  5. namespace SplitOnLength
  6. {
  7.     static class StringSplitter
  8.     {
  9.         public static IEnumerable<string> SaeedsOriginalApproach(this string str, int allowedLength)
  10.         {
  11.             var ret1 = str.Split(' ');
  12.             var ret2 = new List<string>();
  13.             ret2.Add("");
  14.             int index = 0;
  15.             foreach (var item in ret1)
  16.             {
  17.                 if (item.Length + 1 + ret2[index].Length <= allowedLength)
  18.                 {
  19.                     ret2[index] += ' ' + item;
  20.                     if (ret2[index].Length >= allowedLength)
  21.                     {
  22.                         ret2.Add("");
  23.                         index++;
  24.                     }
  25.                 }
  26.                 else
  27.                 {
  28.                     ret2.Add(item);
  29.                     index++;
  30.                 }
  31.             }
  32.             return ret2;
  33.         }
  34.  
  35.         public static IEnumerable<string> SaeedsApproach(this string str, int allowedLength)
  36.         {
  37.             var ret1 = str.Split(' ');
  38.             string current = "";
  39.             foreach (var item in ret1)
  40.             {
  41.                 if (item.Length + 1 + current.Length <= allowedLength)
  42.                 {
  43.                     current += ' ' + item;
  44.                     if (current.Length >= allowedLength)
  45.                     {
  46.                         yield return current;
  47.                         current = "";
  48.                     }
  49.                 }
  50.                 else
  51.                 {
  52.                     yield return current;
  53.                     current = "";
  54.                 }
  55.             }
  56.         }
  57.  
  58.         public static IEnumerable<string> SplitOnLength(this string input, int length, bool maintainWords)
  59.         {
  60.             int index = 0;
  61.             while (index < input.Length)
  62.             {
  63.                 int stepsBackward = 0;
  64.  
  65.                 if (index + length < input.Length)
  66.                 {
  67.                     if (maintainWords)
  68.                     {
  69.                         yield return GetBiggestAllowableSubstring(input, index, length, out stepsBackward);
  70.                     }
  71.                     else
  72.                     {
  73.                         yield return input.Substring(index, length);
  74.                     }
  75.                 }
  76.                 else
  77.                 {
  78.                     yield return input.Substring(index);
  79.                 }
  80.  
  81.                 index += (length - stepsBackward);
  82.             }
  83.         }
  84.  
  85.         static string GetBiggestAllowableSubstring(string input, int index, int length, out int stepsBackward)
  86.         {
  87.             stepsBackward = 0;
  88.  
  89.             int lastIndex = index + length - 1;
  90.  
  91.             if (!char.IsWhiteSpace(input[lastIndex + 1]))
  92.             {
  93.                 int adjustedLastIndex = input.LastIndexOf(' ', lastIndex, length);
  94.                 stepsBackward = lastIndex - adjustedLastIndex;
  95.                 lastIndex = adjustedLastIndex;
  96.             }
  97.  
  98.             if (lastIndex == -1)
  99.             {
  100.                 throw new ArgumentOutOfRangeException("The input string contains at least one word greater in length than the specified length.");
  101.             }
  102.  
  103.             return input.Substring(index, lastIndex - index + 1);
  104.         }
  105.     }
  106.  
  107.     class Program
  108.     {
  109.         static void Main(string[] args)
  110.         {
  111.             string s = "This is a sample block of text that I would pass through the string splitter.";
  112.  
  113.             Console.WriteLine("Testing SplitOnLength(10):");
  114.             foreach (string str in s.SplitOnLength(10, true))
  115.             {
  116.                 Console.WriteLine(str);
  117.             }
  118.  
  119.             Console.WriteLine();
  120.             Console.WriteLine("Testing SaeedsOriginalApproach(10):");
  121.             foreach (string str in s.SaeedsOriginalApproach(10))
  122.             {
  123.                 Console.WriteLine(str);
  124.             }
  125.  
  126.             Console.WriteLine();
  127.             Console.WriteLine("Testing SaeedsApproach(10):");
  128.             foreach (string str in s.SaeedsApproach(10))
  129.             {
  130.                 Console.WriteLine(str);
  131.             }
  132.  
  133.             Console.WriteLine();
  134.             Console.WriteLine("Finished. Press Enter to continue.");
  135.             Console.ReadLine();
  136.  
  137.             // This is the entire text of Kafka's 'In the Penal Colony',
  138.             // as a sample input of significant length.
  139.             string longInput = SplitOnLength.Properties.Resources.InThePenalColony;
  140.  
  141.             // This is an excerpt of the text of the OP's question,
  142.             // as a sample input of small-medium length.
  143.             string shortInput = SplitOnLength.Properties.Resources.QuestionText;
  144.  
  145.             do
  146.             {
  147.                 try
  148.                 {
  149.                     Console.Write("Enter a split size: ");
  150.                     int length = int.Parse(Console.ReadLine());
  151.  
  152.                     Console.WriteLine();
  153.                     Console.WriteLine("Testing my method...");
  154.                     Console.WriteLine();
  155.  
  156.                     TimeSpan splitOnLengthTime = TestSplitMethod(longInput, length, (str, len) => str.SplitOnLength(len, true));
  157.                     TimeSpan saeedsOriginalApproachTime = TestSplitMethod(longInput, length, (str, len) => str.SaeedsOriginalApproach(len));
  158.                     TimeSpan saeedsApproachTime = TestSplitMethod(longInput, length, (str, len) => str.SaeedsApproach(len));
  159.  
  160.                     Console.WriteLine("Results from longer input:");
  161.                     Console.WriteLine("SplitOnLength: {0} ms", splitOnLengthTime.TotalMilliseconds);
  162.                     Console.WriteLine("SaeedsOriginalApproach: {0} ms", saeedsOriginalApproachTime.TotalMilliseconds);
  163.                     Console.WriteLine("SaeedsApproach: {0} ms", saeedsApproachTime.TotalMilliseconds);
  164.  
  165.                     splitOnLengthTime = TestSplitMethod(shortInput, length, (str, len) => str.SplitOnLength(len, true));
  166.                     saeedsOriginalApproachTime = TestSplitMethod(shortInput, length, (str, len) => str.SaeedsOriginalApproach(len));
  167.                     saeedsApproachTime = TestSplitMethod(shortInput, length, (str, len) => str.SaeedsApproach(len));
  168.  
  169.                     Console.WriteLine();
  170.                     Console.WriteLine("Results from shorter input:");
  171.                     Console.WriteLine("SplitOnLength: {0} ms", splitOnLengthTime.TotalMilliseconds);
  172.                     Console.WriteLine("SaeedsOriginalApproach: {0} ms", saeedsOriginalApproachTime.TotalMilliseconds);
  173.                     Console.WriteLine("SaeedsApproach: {0} ms", saeedsApproachTime.TotalMilliseconds);
  174.                 }
  175.                 catch (Exception ex)
  176.                 {
  177.                     Console.WriteLine(ex.Message);
  178.                 }
  179.                 finally
  180.                 {
  181.                     Console.WriteLine();
  182.                     Console.Write("Go again? ");
  183.                     Console.WriteLine();
  184.                 }
  185.             }
  186.             while (Console.ReadLine().StartsWith("Y", StringComparison.OrdinalIgnoreCase));
  187.         }
  188.  
  189.         static TimeSpan TestSplitMethod(string input, int length, Func<string, int, IEnumerable<string>> splitter)
  190.         {
  191.             // Ensure results aren't thrown off by garbage collections affecting
  192.             // certain runs more or less harshly than others.
  193.             GC.Collect();
  194.  
  195.             Stopwatch stopwatch = Stopwatch.StartNew();
  196.  
  197.             IEnumerable<string> split = splitter(input, length);
  198.             foreach (string s in split)
  199.             { }
  200.  
  201.             stopwatch.Stop();
  202.  
  203.             return stopwatch.Elapsed;
  204.         }
  205.     }
  206. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement