fork download
  1. using System;
  2. using System.Diagnostics;
  3.  
  4. namespace ConsoleApplication1 {
  5.  
  6. internal class Program {
  7.  
  8. /// <summary>Looks for the next occurrence of a sequence in a byte array</summary>
  9. /// <param name="array">Array that will be scanned</param>
  10. /// <param name="start">Index in the array at which scanning will begin</param>
  11. /// <param name="sequence">Sequence the array will be scanned for</param>
  12. /// <returns>
  13. /// The index of the next occurrence of the sequence of -1 if not found
  14. /// </returns>
  15. private static int findSequence(byte[] array, int start, byte[] sequence) {
  16. int end = array.Length - sequence.Length; // past here no match is possible
  17. byte firstByte = sequence[0]; // cached to tell compiler there's no aliasing
  18.  
  19. while(start <= end) {
  20. // scan for first byte only. compiler-friendly.
  21. if(array[start] == firstByte) {
  22. // scan for rest of sequence
  23. for (int offset = 1;; ++offset) {
  24. if(offset == sequence.Length) { // full sequence matched?
  25. return start;
  26. } else if(array[start + offset] != sequence[offset]) {
  27. break;
  28. }
  29. }
  30. }
  31. ++start;
  32. }
  33.  
  34. // end of array reached without match
  35. return -1;
  36. }
  37.  
  38. private static void checkSingleByteSequence() {
  39. byte[] sequence = new byte[] { 123 };
  40.  
  41. Debug.Assert(findSequence(new byte[] { 123 }, 0, sequence) == 0);
  42. Debug.Assert(findSequence(new byte[] { 100 }, 0, sequence) == -1);
  43.  
  44. Debug.Assert(findSequence(new byte[] { 123, 124, 125 }, 0, sequence) == 0);
  45. Debug.Assert(findSequence(new byte[] { 122, 123, 124 }, 0, sequence) == 1);
  46. Debug.Assert(findSequence(new byte[] { 121, 122, 123 }, 0, sequence) == 2);
  47.  
  48. Debug.Assert(findSequence(new byte[] { 123, 124, 125, 126 }, 1, sequence) == -1);
  49. Debug.Assert(findSequence(new byte[] { 122, 123, 124, 125 }, 2, sequence) == -1);
  50. Debug.Assert(findSequence(new byte[] { 123, 124, 123, 124 }, 1, sequence) == 2);
  51. Debug.Assert(findSequence(new byte[] { 120, 121, 122, 123 }, 3, sequence) == 3);
  52. Debug.Assert(findSequence(new byte[] { 121, 122, 123, 124 }, 3, sequence) == -1);
  53. }
  54.  
  55. private static void checkThreeByteSequence() {
  56. byte[] sequence = new byte[] { 150, 150, 160 };
  57.  
  58. Debug.Assert(findSequence(new byte[] { 100 }, 0, sequence) == -1);
  59. Debug.Assert(findSequence(new byte[] { 100, 200 }, 0, sequence) == -1);
  60. Debug.Assert(findSequence(new byte[] { 100, 110 }, 1, sequence) == -1);
  61. Debug.Assert(findSequence(new byte[] { 100, 110, 120 }, 0, sequence) == -1);
  62. Debug.Assert(findSequence(new byte[] { 100, 110, 120, 130 }, 3, sequence) == -1);
  63.  
  64. Debug.Assert(findSequence(new byte[] { 150 }, 0, sequence) == -1);
  65. Debug.Assert(findSequence(new byte[] { 100, 150 }, 0, sequence) == -1);
  66. Debug.Assert(findSequence(new byte[] { 150, 150 }, 1, sequence) == -1);
  67. Debug.Assert(findSequence(new byte[] { 100, 150, 150, 150 }, 0, sequence) == -1);
  68. Debug.Assert(findSequence(new byte[] { 150, 150, 120, 150 }, 3, sequence) == -1);
  69.  
  70. Debug.Assert(findSequence(new byte[] { 150, 150, 160, 170 }, 0, sequence) == 0);
  71. Debug.Assert(findSequence(new byte[] { 150, 150, 160, 170 }, 1, sequence) == -1);
  72.  
  73. Debug.Assert(findSequence(new byte[] { 140, 150, 150, 160 }, 0, sequence) == 1);
  74. Debug.Assert(findSequence(new byte[] { 140, 150, 150, 160 }, 1, sequence) == 1);
  75. Debug.Assert(findSequence(new byte[] { 140, 150, 150, 160 }, 2, sequence) == -1);
  76. }
  77.  
  78. public static void Main(string[] args) {
  79. checkSingleByteSequence();
  80. checkThreeByteSequence();
  81. }
  82.  
  83. }
  84.  
  85. }
Success #stdin #stdout 0.01s 13968KB
stdin
Standard input is empty
stdout
Standard output is empty