Skip to content

Commit f1c72bf

Browse files
committed
ArithmeticCodingAlgm new realization
1 parent 487fe66 commit f1c72bf

4 files changed

Lines changed: 21254 additions & 7 deletions

File tree

AlgorithmsLibrary/ArithmeticCodingAlgm/ArithmeticCodingAlgm.cs

Lines changed: 88 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -48,14 +48,22 @@ public static IAlgmEncoded<string, IAlgmEncoded<int, Dictionary<char, int>>> Enc
4848
{
4949
List<Symbol> codes = GetSymbolsRanges(source);
5050
decimal HighRange = 1, LowRange = 0, h, l;
51+
52+
//List<char> TheImmutablePart = new List<char>();
53+
StringBuilder TheImmutablePart = new StringBuilder();
54+
5155
foreach (char c in source)
5256
{
5357
Symbol item = codes.Find(x => x.Data == c);
5458
h = HighRange; l = LowRange;
5559
HighRange = l + (h - l) * item.HighRange;
5660
LowRange = l + (h - l) * item.LowRange;
61+
DiscardTheImmutablePart(ref TheImmutablePart, ref HighRange, ref LowRange);
5762
}
58-
string answer = "0";
63+
64+
// ищем оптимальное представление числа
65+
StringBuilder answer = new StringBuilder();
66+
answer.Append('0');
5967
if (LowRange != 0)
6068
{
6169
int[] number = new int[28];
@@ -77,14 +85,80 @@ public static IAlgmEncoded<string, IAlgmEncoded<int, Dictionary<char, int>>> Enc
7785
result = Convert.ToDecimal(convertToString(number, k));
7886
if (k == 28) break;
7987
}
80-
answer = "";
88+
answer.Clear();
89+
answer.Append(TheImmutablePart);
90+
//foreach (char c in TheImmutablePart)
91+
// answer += c;
8192
for (int i = 0; i < k; i++)
82-
answer += number[i].ToString();
93+
answer.Append(number[i].ToString());
8394
}
8495

85-
double compressionRatio = CalculateCompressionRatio(source, answer);
86-
return new EncodedMessage<string, IAlgmEncoded<int, Dictionary<char, int>>>(answer, new EncodedMessage<int, Dictionary<char, int>>(source.Length, GetFrequencies(source), compressionRatio), compressionRatio);
96+
double compressionRatio = CalculateCompressionRatio(source, answer.ToString());
97+
return new EncodedMessage<string, IAlgmEncoded<int, Dictionary<char, int>>>(answer.ToString(), new EncodedMessage<int, Dictionary<char, int>>(source.Length, GetFrequencies(source), compressionRatio), compressionRatio);
8798
}
99+
100+
private static void DiscardTheImmutablePart(ref StringBuilder theImmutablePart, ref decimal highRange, ref decimal lowRange)
101+
{
102+
string lr = lowRange.ToString();
103+
string hr = highRange.ToString();
104+
int i=0, cnt =0;
105+
while (i<lr.Length && i<hr.Length && lr[i]==hr[i])
106+
{
107+
if (!((i == 0 && lr[i] == '0') || lr[i] == ','))
108+
{
109+
theImmutablePart.Append(lr[i]);
110+
highRange *= 10; highRange -= (int)highRange % 10;
111+
lowRange *= 10; lowRange -= (int)lowRange % 10;
112+
//cnt++;
113+
}
114+
115+
i++;
116+
}
117+
//highRange *= (decimal)Math.Pow(10, cnt);
118+
//highRange -= (int)highRange;
119+
//lowRange *= (decimal)Math.Pow(10, cnt);
120+
//lowRange -= (int)lowRange;
121+
}
122+
123+
private static void DiscardTheImmutablePart(ref decimal highRange, ref decimal lowRange, ref decimal code, ref int index, string encoded,
124+
ref bool thePreviousDigitIsZero, ref int CntOfZero)
125+
{
126+
string lr = lowRange.ToString();
127+
string hr = highRange.ToString();
128+
string c = code.ToString();
129+
int i = 0, encodedLength = encoded.Length;
130+
while (i < lr.Length && i < hr.Length && i < c.Length && lr[i] == hr[i] && lr[i]==c[i])
131+
{
132+
if (!((i == 0 && lr[i] == '0') || lr[i] == ','))
133+
{
134+
highRange *= 10; highRange -= (int)highRange % 10;
135+
lowRange *= 10; lowRange -= (int)lowRange % 10;
136+
code = Convert.ToDecimal("0," + (index<encodedLength?encoded.Substring(index, Math.Min(28, encodedLength - index)):"0" ));
137+
index++;
138+
//code *= 10; code -= (int)code % 10;
139+
//if (index<encodedLength)
140+
//{
141+
// if (encoded[index]=='0')
142+
// {
143+
// CntOfZero++; index++;
144+
// thePreviousDigitIsZero = true;
145+
// }
146+
// else
147+
// {
148+
149+
// if (thePreviousDigitIsZero)
150+
// {
151+
// code += (decimal)(int.Parse(encoded[index++].ToString()) / Math.Pow(10, c.Length - 2+CntOfZero));
152+
// }
153+
// else
154+
155+
// }
156+
//}
157+
}
158+
i++;
159+
}
160+
}
161+
88162
private static string convertToString(int[] number, int index)
89163
{
90164
//if (index > 28) index = 28;
@@ -98,8 +172,14 @@ public static IAlgmEncoded<string> Decode(Dictionary<char, int> frequencies, str
98172
List<Symbol> codes = GetSymbolsRanges(frequencies, CountOfAllSymbols);
99173
StringBuilder decoded = new StringBuilder(string.Empty);
100174

101-
//decimal code = int.Parse(encoded) / (decimal)Math.Pow(10, encoded.Length);
102-
decimal code = Convert.ToDecimal("0," + encoded);
175+
bool thePreviousDigitIsZero = false;
176+
int CntOfZero = 0;
177+
int IndexInEncodedString = 1;
178+
decimal code = Convert.ToDecimal("0," + encoded.Substring(0, Math.Min(28, encoded.Length)));
179+
//int IndexInEncodedString = 28;
180+
//if (encoded.Length < 28)
181+
// IndexInEncodedString = encoded.Length - 1;
182+
//decimal code = Convert.ToDecimal("0," + encoded.Substring(0, IndexInEncodedString));
103183
decimal HighRange = 1, LowRange = 0, h, l;
104184
for (int i = 0; i < CountOfAllSymbols; i++)
105185
{
@@ -108,6 +188,7 @@ public static IAlgmEncoded<string> Decode(Dictionary<char, int> frequencies, str
108188
decoded.Append(item.Data);
109189
HighRange = l + (h - l) * item.HighRange;
110190
LowRange = l + (h - l) * item.LowRange;
191+
DiscardTheImmutablePart(ref HighRange, ref LowRange, ref code, ref IndexInEncodedString, encoded, ref thePreviousDigitIsZero, ref CntOfZero);
111192
}
112193

113194
var decodedString = decoded.ToString();

0 commit comments

Comments
 (0)