public static CharFreq[] GetMas(string s) { var mas = s.Distinct().ToArray();//взять массив разных символов CharFreq[] smas = new CharFreq[mas.Length]; for (int i = 0; i < mas.Length; i++)//перевести массив символов в массив объектов класса { smas[i] = new CharFreq(mas[i]); double c = 0; for (int j = 0; j < s.Length; j++) { if (s[j] == mas[i]) { c++; } } smas[i].frequency = c / s.Length; } Array.Sort(smas);//сортировать по частоте return(smas); }
///// <summary> ///// Сортировщик очереди ///// </summary> ///// <param name="s"></param> ///// <param name="r"></param> ///// <returns></returns> //private static int comparer(this Tuple<List<char>, string, double> s, Tuple<List<char>, string, double> r) //{ // return s.Item3.CompareTo(r.Item3); //} /// <summary> /// Кодирование по алгоритму Хоффмана /// </summary> /// <param name="s"></param> /// <param name="encode"></param> /// <returns></returns> public static string Hoffman(string s, bool encode = true) { string res = ""; if (encode) { var constmas = CharFreq.GetMas(s); //набор символов с частотой constmas.Reverse(); var mas = new List <Turn>(); //список пар нескольких символов и их суммарной частоты TempList.Add("-----Исходный набор символов:"); for (int i = 0; i < constmas.Length; i++) { mas.Add(new Turn(constmas[i].simbol, "", constmas[i].frequency)); TempList.Add($"symbol[{i}] = {constmas[i].simbol} \t{constmas[i].frequency}"); } //генерируется таблица while (mas.Count > 1) { mas.Sort(); mas.Reverse(); for (int i = 0; i < mas.Count; i++) { string t = ""; for (int j = 0; j < mas[i].SymbolList.Count; j++) { t += $"{mas[i].SymbolList[j].Item1}({mas[i].SymbolList[j].Item2})"; } TempList.Add($"{t} \t{mas[i].value}"); } mas[0] += mas[1]; mas.RemoveAt(1); TempList.Add(""); //вдруг ускорит поиск mas.Sort(); mas.Reverse(); } HofTable = mas[0]; //генерируется вывод string tmp = ""; for (int i = 0; i < HofTable.Count; i++) { tmp += HofTable.SymbolList[i].Item1; } for (int i = 0; i < s.Length; i++) { res += HofTable.SymbolList[tmp.IndexOf(s[i])].Item2 + " "; } //res += HofTable.SymbolList[Array.BinarySearch(tmp.ToArray(),s[i])].Item2 + " "; } else { //генерируется вывод var tmp = s.Split(' ').Where(n => n.Length > 0).ToArray(); TempList.Add($"Декодируемая строка без пробелов:"); for (int i = 0; i < tmp.Length; i++) { TempList.Add($"tmp[{i}] = {tmp[i]}"); for (int j = 0; j < HofTable.Count; j++) { if (tmp[i] == HofTable.SymbolList[j].Item2) { res += HofTable.SymbolList[j].Item1; break; } } } } return(res); }
/// <summary> /// Попытка взлома по частоте символов /// </summary> /// <param name="s"></param> /// <returns></returns> public static string Hacking(string s) { //массив принятых частот (отсортированный в порядке убывания) FreqMas[1] = new CharFreq('о', 0.10983); FreqMas[2] = new CharFreq('е', 0.08483); FreqMas[3] = new CharFreq('а', 0.07998); FreqMas[4] = new CharFreq('и', 0.07367); FreqMas[5] = new CharFreq('н', 0.067); FreqMas[6] = new CharFreq('т', 0.06318); FreqMas[7] = new CharFreq('с', 0.05473); FreqMas[8] = new CharFreq('р', 0.04746); FreqMas[9] = new CharFreq('в', 0.04533); FreqMas[10] = new CharFreq('л', 0.04343); FreqMas[11] = new CharFreq('к', 0.03486); FreqMas[12] = new CharFreq('м', 0.03203); FreqMas[13] = new CharFreq('д', 0.02977); FreqMas[14] = new CharFreq('п', 0.02804); FreqMas[15] = new CharFreq('у', 0.02615); FreqMas[16] = new CharFreq('я', 0.02001); FreqMas[17] = new CharFreq('ы', 0.01898); FreqMas[18] = new CharFreq('ь', 0.01735); FreqMas[19] = new CharFreq('г', 0.01687); FreqMas[20] = new CharFreq('з', 0.01641); FreqMas[21] = new CharFreq('б', 0.01592); FreqMas[22] = new CharFreq('ч', 0.0145); FreqMas[23] = new CharFreq('й', 0.01208); FreqMas[24] = new CharFreq('х', 0.00966); FreqMas[25] = new CharFreq('ж', 0.0094); FreqMas[26] = new CharFreq('ш', 0.00718); FreqMas[27] = new CharFreq('ю', 0.00639); FreqMas[28] = new CharFreq('ц', 0.00486); FreqMas[29] = new CharFreq('щ', 0.00361); FreqMas[30] = new CharFreq('э', 0.00331); FreqMas[31] = new CharFreq('ф', 0.00267); FreqMas[32] = new CharFreq('ъ', 0.00037); FreqMas[33] = new CharFreq('ё', 0.00013); s = new string(s.Where(n => n != ' ' && n != ',' && n != '.' && n != ';' && n != ':' && n != '(' && n != ')' && n != '!' && n != '?' && n != '-' && n != '—' && n != '…' && n != '\n' && n != '\t').ToArray()).ToLower();//убрать из строки все пробелы, точки, запятые, все буквы заменить на маленькие TempList.Add($"Исправленная исходная строка: {s}"); var smas = CharFreq.GetMas(s); //smas=smas.Reverse().ToArray();//реверсировать массив (чтоб было по убыванию) TempList.Add("----------------Сортированный массив частот в тексте:"); for (int i = 0; i < smas.Length; i++) { TempList.Add($"\tsmas[{i}] = {smas[i].simbol} \t{smas[i].frequency}"); } string tmp = ""; for (int i = 0; i < smas.Length; i++)//перевести отсортированный массив в строку { tmp += smas[i].simbol; } tmp = new string(tmp.Reverse().ToArray());//tmp.Show(); TempList.Add("----------------Строка символов текста по убыванию частоты: " + tmp); TempList.Add($"----------------Перевод символов строки:"); string res = ""; for (int i = 0; i < s.Length; i++)//перевести каждый символ в строке, зная частоту { try { int k = tmp.IndexOf(s[i]); res += FreqMas[k + 1].simbol; TempList.Add($"\ts[{i}] = {s[i]} \t(частота {smas[smas.Length - 1 - k].frequency}) \t------> \t{FreqMas[k + 1].simbol} (принятая частота {FreqMas[k + 1].frequency})"); } catch { throw new Exception("Походу неизвестный символ"); } } return(res); }
public int CompareTo(object obj) { CharFreq t = (CharFreq)obj; return(frequency.CompareTo(t.frequency)); }