/// <summary> /// Кодирует заданную исходную последовательность символов с помощью указанных основания и словаря частот встречаемости символов. /// </summary> /// <exception cref="ArgumentNullException">Исключение, которое выдается если <paramref name="source"/> или <paramref name="occurrenceFrequencies"/> равен null.</exception> /// <exception cref="ArithmeticCodingException">Исключение, которое выдается при отсутствии символа из исходной последовательности в словаре частот встречаемости символов.</exception> /// <param name="source">Исходная последовательность символов.</param> /// <param name="occurrenceFrequencies">Словарь частот встречаемости символов.</param> /// <param name="radix">Основание.</param> /// <returns>Арифметическое значение.</returns> public static ArithmeticValue Encode(char[] source, IReadOnlyDictionary <char, int> occurrenceFrequencies, int radix) { if (source == null) { throw new ArgumentNullException(nameof(source)); } if (occurrenceFrequencies == null) { throw new ArgumentNullException(nameof(occurrenceFrequencies)); } var cumulativeFrequencies = ArithmeticDictionary.GetEncodingCumulativeFrequencies(occurrenceFrequencies); var lower = new BigInteger(0); var pf = new BigInteger(1); foreach (var symbol in source) { if (!occurrenceFrequencies.ContainsKey(symbol)) { throw new ArithmeticCodingException($"Символ '{symbol}' (код - {(int)symbol}) не найден в словаре частот символов."); } lower = lower * source.Length + cumulativeFrequencies[symbol] * pf; pf *= occurrenceFrequencies[symbol]; } var upper = lower + pf; var power = CodingHelper.GetPower(pf, radix); var mantissa = (upper - 1) / BigInteger.Pow(radix, power); return(new ArithmeticValue(occurrenceFrequencies, mantissa, radix, power)); }