Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Sabelnikov_RGR3_2_2_CodingTheory.docx
Скачиваний:
0
Добавлен:
01.07.2025
Размер:
227.33 Кб
Скачать
  1. Класс главного окна

/// <summary>

/// Interaction logic for MainWindow.xaml

/// </summary>

public partial class MainWindow : Window, INotifyPropertyChanged

{

public List<Letter> Letters { get; set; }

private Arithmetic arithmetic; // algo core

public String Power

{

get { return arithmetic == null ? "null" : "2^" + arithmetic.Power + "=" + BigInteger.Pow(new BigInteger(2), arithmetic.Power); }

}

public String LeftEdgeBinary

{

get

{

if (arithmetic == null) return "null";

var res = "";

var tmp = arithmetic.Left;

for (var i = 0; i < arithmetic.Power; i++)

{

var rem = new BigInteger();

tmp = BigInteger.DivRem(tmp, new BigInteger(2), out rem);

res += rem.IsOne ? "1" : "0";

}

char[] arr = res.ToCharArray();

Array.Reverse(arr);

return new string(arr);

}

}

public String RightEdgeBinary

{

get

{

if (arithmetic == null) return "null";

var res = "";

var tmp = arithmetic.Right;

for (var i = 0; i < arithmetic.Power; i++)

{

var rem = new BigInteger();

tmp = BigInteger.DivRem(tmp, new BigInteger(2), out rem);

res += rem.IsOne ? "1" : "0";

}

char[] arr = res.ToCharArray();

Array.Reverse(arr);

return new string(arr);

}

}

public String LeftEdge

{

get { return arithmetic == null ? "null" : arithmetic.Left.ToString(); }

}

public String RightEdge

{

get { return arithmetic == null ? "null" : arithmetic.Right.ToString(); }

}

public String EncodedText

{

get { return arithmetic == null ? "null" : arithmetic.EncodedText; }

}

public MainWindow()

{

// Edit alphabet here

Letters = new List<Letter>

{

///////////////// EXAMPLE ////////////////////////////////

//new Letter {Char = 'a', Name = "a", Probability = 0.750},

//new Letter {Char = 'b', Name = "b", Probability = 0.250},

///////////////////////////////////////////////////////////

/////////////////////// REAL LIFE /////////////////////////

new Letter {Char = 'о', Name = "о", Probability = 0.095},

new Letter {Char = 'е', Name = "е", Probability = 0.074},

new Letter {Char = 'а', Name = "а", Probability = 0.064},

new Letter {Char = 'и', Name = "и", Probability = 0.064},

new Letter {Char = 'т', Name = "т", Probability = 0.056},

new Letter {Char = 'н', Name = "н", Probability = 0.056},

new Letter {Char = 'с', Name = "с", Probability = 0.047},

new Letter {Char = 'р', Name = "р", Probability = 0.041},

new Letter {Char = 'в', Name = "в", Probability = 0.039},

new Letter {Char = 'л', Name = "л", Probability = 0.036},

new Letter {Char = 'к', Name = "к", Probability = 0.029},

new Letter {Char = 'м', Name = "м", Probability = 0.026},

new Letter {Char = 'д', Name = "д", Probability = 0.026},

new Letter {Char = 'п', Name = "п", Probability = 0.024},

new Letter {Char = 'у', Name = "у", Probability = 0.021},

new Letter {Char = 'я', Name = "я", Probability = 0.019},

new Letter {Char = 'ы', Name = "ы", Probability = 0.016},

new Letter {Char = 'з', Name = "з", Probability = 0.015},

new Letter {Char = 'ь', Name = "ь", Probability = 0.01},

new Letter {Char = 'ъ', Name = "ъ", Probability = 0.013},

new Letter {Char = 'б', Name = "б", Probability = 0.013},

new Letter {Char = 'г', Name = "г", Probability = 0.01},

new Letter {Char = 'ч', Name = "ч", Probability = 0.01},

new Letter {Char = 'й', Name = "й", Probability = 0.01},

new Letter {Char = 'х', Name = "х", Probability = 0.009},

new Letter {Char = 'ж', Name = "ж", Probability = 0.007},

new Letter {Char = 'ю', Name = "ю", Probability = 0.007},

new Letter {Char = 'ш', Name = "ш", Probability = 0.006},

new Letter {Char = 'ц', Name = "ц", Probability = 0.002},

new Letter {Char = 'щ', Name = "щ", Probability = 0.002},

new Letter {Char = 'э', Name = "э", Probability = 0.002},

new Letter {Char = 'ф', Name = "ф", Probability = 0.002},

new Letter {Char = ',', Name = ",", Probability = 0.002},

new Letter {Char = '.', Name = ".", Probability = 0.002},

new Letter {Char = ' ', Name = "пробел", Probability = 0.145},

};

InitializeComponent();

this.DataContext = this;

}

private void update()

{

// Update all values

NotifyPropertyChanged("LeftEdge");

NotifyPropertyChanged("RightEdge");

NotifyPropertyChanged("LeftEdgeBinary");

NotifyPropertyChanged("RightEdgeBinary");

NotifyPropertyChanged("EncodedText");

NotifyPropertyChanged("Power");

}

private void ButtonNext_OnClick(object sender, RoutedEventArgs e)

{

if (arithmetic == null) return;

arithmetic.MakeAStep(); // make a step

update();

}

private void ButtonStartRestart_OnClick(object sender, RoutedEventArgs e)

{

if (String.IsNullOrEmpty(TextBoxInput.Text)) return;

// start an algo

arithmetic = new Arithmetic(Letters, TextBoxInput.Text.Length, TextBoxInput.Text);

update();

}

private void ButtonFinal_OnClick(object sender, RoutedEventArgs e)

{

if (arithmetic == null) return;

while (!arithmetic.MakeAStep()); // make all steps

update();

}

// For auto updating

public event PropertyChangedEventHandler PropertyChanged;

private void NotifyPropertyChanged(String propertyName)

{

PropertyChangedEventHandler handler = PropertyChanged;

if (null != handler)

{

handler(this, new PropertyChangedEventArgs(propertyName));

}

}

}

  1. Выводы

В результате выполнения лабораторной работы была разработана программа для работы по алгоритму арифметического кодирования.

Данный алгоритм опережает алгоритм Хаффмана по показателям сжатия. Но существует ряд практических проблем при реализации. Мы знаем, что Хаффман довольно просто кодируется и представляется в памяти ЭВМ. В этом и состоит его главное преимущество. При арифметическом кодировании стоит проблема точности вычислений. В реальном алфавите довольно маленькие вероятности появления символов. Закодировав небольшое предложение, мы уже получаем угрозу вылететь за пределы точности выбранного нами типа данных. Здесь есть 3 варианта решения проблемы:

  1. Использование блочного кодирования. Каждый блок будет иметь такую длину, которую максимально может позволить точность стандартного типа данных с плавающей точкой. Нужно заметить, что эта длина будет одинаковой для всех передаваемых блоков.

  2. Использование "длинной арифметики". Математические операции позволяют перевести расчеты в множество целых чисел, и далее оперировать на уровне классов типа BigInteger, которые вмещают произвольное целое число.

  3. Сохранение неизменяющихся цифр. Во время выполнения алгоритма некоторые цифры стают одинаковыми для обоих границ диапазона. Их можно сохранять в другое место, чтобы освободить память для новых цифр.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]