@@ -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