00001
00002
00003
00004
00005
00006 namespace NewGamePhysics.Mathematics
00007 {
00008 using System;
00009 using System.Text;
00010
00014 public enum BitUnbiasAlgorithm
00015 {
00020 VonNeuman,
00021
00026 MLS,
00027
00032 AMLS,
00033 }
00034
00039 public class BitUnbiaser
00040 {
00044 private BitUnbiasAlgorithm algorithm;
00045
00050 public BitUnbiaser(BitUnbiasAlgorithm algorithm)
00051 {
00052 this.algorithm = algorithm;
00053 }
00054
00065 public string Process(string input)
00066 {
00067 if (string.IsNullOrEmpty(input))
00068 {
00069 throw new ArgumentNullException("input", "input string cannot be null or empty");
00070 }
00071
00072 if (input.Length < 2)
00073 {
00074 throw new ArgumentException("input must consist of at least 2 characters", "input");
00075 }
00076
00077 StringBuilder output = new StringBuilder(input.Length);
00078 Amls(input, ref output);
00079 return output.ToString();
00080 }
00081
00087 private void Amls(string input, ref StringBuilder output)
00088 {
00089 char[] inputC = input.ToCharArray();
00090 int start = 0;
00091 int end = input.Length - 1;
00092 AmlsStep(ref inputC, ref output, start, end);
00093 }
00094
00103 private void AmlsStep(ref char[] inputC, ref StringBuilder output, int start, int end)
00104 {
00105 if (start >= end)
00106 {
00107 return;
00108 }
00109
00110 int indexD = start;
00111 int indexL = start;
00112 int indexH = end;
00113
00114 do
00115 {
00116 if (inputC[indexL] == inputC[indexH])
00117 {
00118 inputC[indexD] = inputC[indexL];
00119 indexD++;
00120 inputC[indexH] = '0';
00121 }
00122 else
00123 {
00124 output.Append(inputC[indexL]);
00125 inputC[indexH] = '1';
00126 }
00127
00128 indexH--;
00129 indexL++;
00130 } while (indexH > indexL);
00131
00132
00133 if (this.algorithm == BitUnbiasAlgorithm.VonNeuman)
00134 {
00135 return;
00136 }
00137
00138
00139 indexD--;
00140 AmlsStep(ref inputC, ref output, start, indexD);
00141
00142
00143 if (this.algorithm == BitUnbiasAlgorithm.MLS)
00144 {
00145 return;
00146 }
00147
00148
00149 indexH++;
00150 AmlsStep(ref inputC, ref output, indexH, end);
00151 }
00152 }
00153 }