-
Notifications
You must be signed in to change notification settings - Fork 0
Hw2 Lzw #4
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Hw2 Lzw #4
Changes from all commits
e72b626
2c330e0
c3167fc
a25c8cf
00b07e7
37dbc95
4f411d5
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,6 @@ | ||
| image: Visual Studio 2019 | ||
|
|
||
| build_script: | ||
| - For /R %%I in (*.sln) do dotnet test %%I | ||
|
|
||
| test: off |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,31 @@ | ||
| | ||
| Microsoft Visual Studio Solution File, Format Version 12.00 | ||
| # Visual Studio Version 16 | ||
| VisualStudioVersion = 16.0.31005.135 | ||
| MinimumVisualStudioVersion = 10.0.40219.1 | ||
| Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Hw2LZW", "hw2LZW\Hw2LZW.csproj", "{956FF906-65B8-45A7-AEEC-0C4F4D47EF5D}" | ||
| EndProject | ||
| Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "hw2Lzw.Test", "hw2LzwTest\hw2Lzw.Test.csproj", "{705F21DF-850F-439F-BF37-F0F8EF554073}" | ||
| EndProject | ||
| Global | ||
| GlobalSection(SolutionConfigurationPlatforms) = preSolution | ||
| Debug|Any CPU = Debug|Any CPU | ||
| Release|Any CPU = Release|Any CPU | ||
| EndGlobalSection | ||
| GlobalSection(ProjectConfigurationPlatforms) = postSolution | ||
| {956FF906-65B8-45A7-AEEC-0C4F4D47EF5D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | ||
| {956FF906-65B8-45A7-AEEC-0C4F4D47EF5D}.Debug|Any CPU.Build.0 = Debug|Any CPU | ||
| {956FF906-65B8-45A7-AEEC-0C4F4D47EF5D}.Release|Any CPU.ActiveCfg = Release|Any CPU | ||
| {956FF906-65B8-45A7-AEEC-0C4F4D47EF5D}.Release|Any CPU.Build.0 = Release|Any CPU | ||
| {705F21DF-850F-439F-BF37-F0F8EF554073}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | ||
| {705F21DF-850F-439F-BF37-F0F8EF554073}.Debug|Any CPU.Build.0 = Debug|Any CPU | ||
| {705F21DF-850F-439F-BF37-F0F8EF554073}.Release|Any CPU.ActiveCfg = Release|Any CPU | ||
| {705F21DF-850F-439F-BF37-F0F8EF554073}.Release|Any CPU.Build.0 = Release|Any CPU | ||
| EndGlobalSection | ||
| GlobalSection(SolutionProperties) = preSolution | ||
| HideSolutionNode = FALSE | ||
| EndGlobalSection | ||
| GlobalSection(ExtensibilityGlobals) = postSolution | ||
| SolutionGuid = {DB7EE293-FCD3-4437-92C9-C3ABFADE5DE7} | ||
| EndGlobalSection | ||
| EndGlobal |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,105 @@ | ||
| using System; | ||
| using System.Collections.Generic; | ||
| using System.Collections; | ||
| using System.IO; | ||
|
|
||
| namespace Hw2LZW | ||
| { | ||
| /// <summary> | ||
| /// класс для сжатия и разжатия | ||
| /// </summary> | ||
| public static class LZW | ||
| { | ||
| private static int GetCountOfBytes(byte[] array) | ||
| { | ||
| for (int i = array.Length - 1; i >= 0; i--) | ||
| { | ||
| if (array[i] != 0) | ||
| { | ||
| return i + 1; | ||
| } | ||
| } | ||
| return 1; | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// функция сжатия файла | ||
| /// </summary> | ||
| /// <param name="pathFile">путь до файла, который будем сжимать</param> | ||
| public static void Compress(string pathFile) | ||
| { | ||
| using var file = new FileStream(pathFile, FileMode.Open); | ||
| var trie = new Trie(); | ||
| var codes = new Queue<int>(); | ||
| for (int i = 0; i < file.Length; ++i) | ||
| { | ||
| var byter = (byte)file.ReadByte(); | ||
| var codeOfBytes = trie.IsAdd(byter); | ||
| if (codeOfBytes != -1) | ||
| { | ||
| codes.Enqueue(codeOfBytes); | ||
| trie.IsAdd(byter); | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. И снова добавляем байт в дерево? Хм, зачем?
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Надо придумать и написать этому рациональное объяснение. В реальном проекте нельзя просто взять и проигнорировать комментарий ревьюера. |
||
| } | ||
| } | ||
| codes.Enqueue(trie.GetCode()); | ||
| var countOfBytes = GetCountOfBytes(BitConverter.GetBytes(trie.CountCodes)); | ||
| using var fileZipped = new FileStream(pathFile + ".zipped", FileMode.CreateNew); | ||
| fileZipped.WriteByte((byte)countOfBytes); | ||
| var size = codes.Count; | ||
| for (int i = 0; i < size; i++) | ||
| { | ||
| var helpArray = BitConverter.GetBytes(codes.Dequeue()); | ||
| fileZipped.Write(helpArray, 0, countOfBytes); | ||
| } | ||
| } | ||
|
|
||
| private static Hashtable InitializeHashtable() | ||
| { | ||
| var hashtable = new Hashtable(); | ||
| for (int i = 0; i < 256; i++) | ||
| { | ||
| hashtable.Add(i, new byte[] { (byte)i }); | ||
| } | ||
| return hashtable; | ||
| } | ||
|
|
||
| private static void AddLastSymbol(int code, Hashtable hashtable) | ||
| { | ||
| var bytes = (byte[])hashtable[code]; | ||
| var previous = (byte[])hashtable[hashtable.Count - 1]; | ||
| previous[previous.Length - 1] = bytes[0]; | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// функция для разжатия | ||
| /// </summary> | ||
| /// <param name="pathFile">путь до сжатого файла</param> | ||
| public static void Decompress(string pathFile) | ||
| { | ||
| var hashtable = InitializeHashtable(); | ||
| var codes = hashtable.Count; | ||
| using var fileZipped = new FileStream(pathFile, FileMode.Open); | ||
| using var file = new FileStream(pathFile.Substring(0, pathFile.Length - 7), FileMode.OpenOrCreate); | ||
| int maxLength = fileZipped.ReadByte(); | ||
| for (int i = 0; i < fileZipped.Length - 1; i += maxLength) | ||
| { | ||
| var codeInBytes = new byte[4]; | ||
| for (int j = 0; j < maxLength; ++j) | ||
| { | ||
| codeInBytes[j] = (byte)fileZipped.ReadByte(); | ||
| } | ||
| var code = BitConverter.ToInt32(codeInBytes, 0); | ||
| if (i != 0) | ||
| { | ||
| AddLastSymbol(code, hashtable); | ||
| } | ||
| var bytesArray = (byte[])hashtable[code]; | ||
| var copyBytesArray = new byte[bytesArray.Length + 1]; | ||
| Array.Copy(bytesArray, copyBytesArray, bytesArray.Length); | ||
| hashtable.Add(codes, copyBytesArray); | ||
| codes++; | ||
| file.Write(bytesArray); | ||
| } | ||
| } | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,34 @@ | ||
| using System; | ||
| using System.IO; | ||
|
|
||
| namespace Hw2LZW | ||
| { | ||
| class Program | ||
| { | ||
| static void Main(string[] args) | ||
| { | ||
| if (args.Length != 2) | ||
| { | ||
| Console.WriteLine("Ошибка ввода!"); | ||
| return; | ||
| } | ||
| if (args[1] == "-c") | ||
| { | ||
| LZW.Compress(args[0]); | ||
| var compressedFileSize = new FileInfo(args[0]); | ||
| var decompressedFileSize = new FileInfo(args[0] + ".zipped"); | ||
|
Comment on lines
+18
to
+19
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Наоборот же :) |
||
| Console.WriteLine($"Коэффициент сжатия: x {(double)compressedFileSize.Length / decompressedFileSize.Length}"); | ||
| } | ||
| else if (args[1] == "-u") | ||
| { | ||
| LZW.Decompress(args[0]); | ||
| Console.WriteLine("Файл разжат!"); | ||
| } | ||
| else | ||
| { | ||
| Console.WriteLine("Ошибка ввода!"); | ||
| return; | ||
| } | ||
| } | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,107 @@ | ||
| using System; | ||
| using System.Collections.Generic; | ||
|
|
||
| namespace Hw2LZW | ||
| { | ||
| /// <summary> | ||
| /// вспомогательный класс для реализация Lzw | ||
| /// </summary> | ||
| public class Trie | ||
| { | ||
| private class Node | ||
| { | ||
| public byte Bytes { get; } | ||
|
|
||
| public bool IsUsed { get; set; } | ||
|
|
||
| public int IdByte; | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Я пишу "у этих свойств видимость уж слишком широкая, сеттер можно было убрать", а Вы такой "о, почему бы не превратить свойство в public-поле?". Типа "сгорел сарай, гори и хата"? Нет, не прокатит. |
||
|
|
||
| public int CodeBytes { get; set; } | ||
|
|
||
| public Dictionary<byte, Node> Sons; | ||
|
|
||
| public Node(byte bytes, int codeByte, bool isUsed) | ||
| { | ||
| IsUsed = isUsed; | ||
| Bytes = bytes; | ||
| IdByte = codeByte; | ||
| Sons = new Dictionary<byte, Node>(); | ||
| } | ||
|
|
||
| public Node IsFind(byte value) | ||
| => Sons.TryGetValue(value, out Node node) ? node : null; | ||
| } | ||
|
|
||
| private Node root = new Node(0, 0, false); | ||
|
|
||
| private Node runner; | ||
|
|
||
| public Trie() | ||
| { | ||
| for (int i = 0; i < 256; ++i) | ||
| { | ||
| InitRoot((byte)i, i); | ||
| } | ||
| runner = root; | ||
| } | ||
|
|
||
| public int CountCodes { get; set; } | ||
|
|
||
| private void InitRoot(byte idSymbol, int index) | ||
| { | ||
|
|
||
| var son = new Node(idSymbol, index, false); | ||
| root.Sons.Add(idSymbol, son); | ||
| son.CodeBytes = CountCodes; | ||
| CountCodes++; | ||
| } | ||
|
|
||
| private bool CheckAdd(byte value, Node node) | ||
| => node.IsFind(value) == null; | ||
|
|
||
| public int LastCode { get; set; } | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. По-хорошему, к свойствам (особенно с неочевидными названиями, как это) тоже надо комментарии
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Не исправлено |
||
|
|
||
| /// <summary> | ||
| /// функция добавления | ||
| /// </summary> | ||
| /// <param name="value">байт, который хотим добавить</param> | ||
| /// <returns>если такой байт уже есть, то вернем "-1"</returns> | ||
| public int IsAdd(byte value) | ||
| { | ||
| if (runner == root) | ||
| { | ||
| var check = runner.Sons[value]; | ||
| if (!check.IsUsed) | ||
| { | ||
| check.IsUsed = true; | ||
| runner = runner.Sons[value]; | ||
| LastCode = runner.Bytes; | ||
| return -1; | ||
| } | ||
| } | ||
| var isCheck = CheckAdd(value, runner); | ||
| if (isCheck) | ||
| { | ||
| var son = new Node(value, CountCodes, true); | ||
| son.CodeBytes = CountCodes; | ||
| CountCodes++; | ||
| runner.Sons.Add(value, son); | ||
| runner = root; | ||
| return LastCode; | ||
| } | ||
| else | ||
| { | ||
| runner = runner.Sons[value]; | ||
| LastCode = runner.CodeBytes; | ||
| return -1; | ||
| } | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// функция для возврата кода у узла | ||
| /// </summary> | ||
| /// <returns>возвращается код узла</returns> | ||
| public int GetCode() | ||
| => runner.Bytes; | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| <Project Sdk="Microsoft.NET.Sdk"> | ||
|
|
||
| <PropertyGroup> | ||
| <OutputType>Exe</OutputType> | ||
| <TargetFramework>netcoreapp3.1</TargetFramework> | ||
| </PropertyGroup> | ||
|
|
||
| </Project> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,53 @@ | ||
| using NUnit.Framework; | ||
| using System.IO; | ||
|
|
||
| namespace hw2LzwTest | ||
| { | ||
| [TestFixture] | ||
| public class Tests | ||
| { | ||
| private bool Compare(string path1, string path2) | ||
| { | ||
| using FileStream file1 = File.OpenRead(path1); | ||
| using FileStream file2 = File.OpenRead(path2); | ||
| if (file1.Length != file2.Length) | ||
| { | ||
| return false; | ||
| } | ||
| for (int i = 0; i < file1.Length; ++i) | ||
| { | ||
| if (file1.ReadByte() != file2.ReadByte()) | ||
| { | ||
| return false; | ||
| } | ||
| } | ||
| return true; | ||
| } | ||
|
|
||
| [TestCase] | ||
| public void LZWWithTxt() | ||
| { | ||
| string path1 = "..\\..\\..\\TestTxt.txt"; | ||
| string path2 = "..\\..\\..\\TestTxtCopy.txt"; | ||
|
Comment on lines
+30
to
+31
This comment was marked as resolved.
Sorry, something went wrong. |
||
| File.Copy(path1, path2); | ||
| Hw2LZW.LZW.Compress(path1); | ||
| Hw2LZW.LZW.Decompress(path1 + ".zipped"); | ||
| File.Delete(path1 + ".zipped"); | ||
| Assert.IsTrue(Compare(path1, path2)); | ||
| File.Delete(path2); | ||
| } | ||
|
|
||
| [TestCase] | ||
| public void LZWWithImg() | ||
| { | ||
| string path1 = "..\\..\\..\\TestImg.jpg"; | ||
| string path2 = "..\\..\\..\\TestImgCopy.jpg"; | ||
| File.Copy(path1, path2); | ||
| Hw2LZW.LZW.Compress(path1); | ||
| Hw2LZW.LZW.Decompress(path1 + ".zipped"); | ||
| File.Delete(path1 + ".zipped"); | ||
| Assert.IsTrue(Compare(path1, path2)); | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
| File.Delete(path2); | ||
| } | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| sleep and code | ||
| eat and code | ||
| walk and coee |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,19 @@ | ||
| <Project Sdk="Microsoft.NET.Sdk"> | ||
|
|
||
| <PropertyGroup> | ||
| <TargetFramework>netcoreapp3.1</TargetFramework> | ||
|
|
||
| <IsPackable>false</IsPackable> | ||
| </PropertyGroup> | ||
|
|
||
| <ItemGroup> | ||
| <PackageReference Include="NUnit" Version="3.12.0" /> | ||
| <PackageReference Include="NUnit3TestAdapter" Version="3.16.1" /> | ||
| <PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.5.0" /> | ||
| </ItemGroup> | ||
|
|
||
| <ItemGroup> | ||
| <ProjectReference Include="..\hw2LZW\Hw2LZW.csproj" /> | ||
| </ItemGroup> | ||
|
|
||
| </Project> |

This comment was marked as resolved.
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.