diff --git a/BWT/BWT/Program.cs b/BWT/BWT/Program.cs deleted file mode 100644 index 11af52d..0000000 --- a/BWT/BWT/Program.cs +++ /dev/null @@ -1,208 +0,0 @@ -namespace Sort; - -using System; -using System.Text; - -enum WhichStringIsBigger -{ - First, - Second, - Same, - Error -} -class Program -{ - public const int NumberOfCharacters = 65536; - - // A method of comparing two rows using indexes indicating their beginning - public static WhichStringIsBigger CompareStrings(string stringToBWT, int positionFirst, int positionSecond) - { - int cyclicalFirstStringPosition = positionFirst; - int cyclicalSecondStringPosition = positionSecond; - int comparedSymbolsCount = 0; - while (comparedSymbolsCount < stringToBWT.Length) - { - if (stringToBWT[cyclicalFirstStringPosition % stringToBWT.Length] > stringToBWT[cyclicalSecondStringPosition % stringToBWT.Length]) - { - return WhichStringIsBigger.First; - } - else if (stringToBWT[cyclicalFirstStringPosition % stringToBWT.Length] < stringToBWT[cyclicalSecondStringPosition % stringToBWT.Length]) - { - return WhichStringIsBigger.Second; - } - - ++cyclicalFirstStringPosition; - ++cyclicalSecondStringPosition; - ++comparedSymbolsCount; - } - return WhichStringIsBigger.Same; - } - - // Sorting by inserts - public static void InsertSort(string stringToBWT, int[] arrayPositions, int startArray, int endArray) - { - for (int i = startArray + 1; i <= endArray; ++i) - { - int j = i; - while (j >= startArray + 1 && CompareStrings(stringToBWT, (arrayPositions[j - 1] + 1) % arrayPositions.Length, - (arrayPositions[j] + 1) % arrayPositions.Length) == WhichStringIsBigger.First) - { - (arrayPositions[j - 1], arrayPositions[j]) = (arrayPositions[j], arrayPositions[j - 1]); - - --j; - } - } - } - - // Finding a reference element - public static int Partition(string stringToBWT, int[] arrayPositions, int startArray, int endArray) - { - int pivot = arrayPositions[endArray]; - int i = startArray; - - for (int j = startArray; j < endArray; ++j) - { - WhichStringIsBigger result = CompareStrings(stringToBWT, (arrayPositions[j] + 1) % arrayPositions.Length, (pivot + 1) % arrayPositions.Length); - if (result == WhichStringIsBigger.Second || result == WhichStringIsBigger.Same) - { - (arrayPositions[j], arrayPositions[i]) = (arrayPositions[i], arrayPositions[j]); - - ++i; - } - } - (arrayPositions[i], arrayPositions[endArray]) = (arrayPositions[endArray], arrayPositions[i]); - return i; - } - - // Quick sort, which sorts an array of indexes by comparing rows obtained by cyclic permutations - public static void QSort(string stringToBWT, int[] arrayPositions, int startArray, int endArray) - { - if (endArray - startArray + 1 <= 10) - { - InsertSort(stringToBWT, arrayPositions,startArray, endArray); - return; - } - if (startArray < endArray) - { - int positionElement = Partition(stringToBWT, arrayPositions, startArray, endArray); - QSort(stringToBWT, arrayPositions, startArray, positionElement - 1); - QSort(stringToBWT, arrayPositions, positionElement + 1, endArray); - } - } - - // Shell for running quick sort - public static void QuickSort(string stringToBWT, int[] arrayPositions) - { - QSort(stringToBWT, arrayPositions, 0, arrayPositions.Length - 1); - } - - // String compression by the Burrows-Wheeler algorithm - public static (string result, int firstPosition) BwtConvert(string stringToBWT) - { - var arrayPositions = new int[stringToBWT.Length]; - for (int i = 0; i < stringToBWT.Length; ++i) - { - arrayPositions[i] = i; - } - - QuickSort(stringToBWT, arrayPositions); - - var stringAfterBWT = new StringBuilder(stringToBWT); - for (int i = 0; i < stringToBWT.Length; ++i) - { - stringAfterBWT[i] = stringToBWT[arrayPositions[i]]; - } - - int firstPosition = 0; - for (int i = 0; i < stringToBWT.Length; ++i) - { - if (arrayPositions[i] == stringToBWT.Length - 1) - { - firstPosition = i; - return (stringAfterBWT.ToString(), firstPosition); - } - } - return (stringAfterBWT.ToString(), firstPosition); - } - - // The function receives a string after the Burrows-Wheeler algorithm as input, returns a string before the Burrows-Wheeler algorithm - public static string BWTReverseСonvert(string stringAfterBWT, int firstPosition) - { - var arraySymbols = new int[NumberOfCharacters]; - var arrayPreCalculationTable = new int[stringAfterBWT.Length]; - - for (int i = 0; i < stringAfterBWT.Length; ++i) - { - ++arraySymbols[stringAfterBWT[i]]; - } - - int summary = 0; - for (int i = 0; i < NumberOfCharacters; i++) - { - summary = summary + arraySymbols[i]; - arraySymbols[i] = summary - arraySymbols[i]; - } - - for (int i = 0; i < stringAfterBWT.Length; ++i) - { - int j = i - 1; - while (j >= 0) - { - if (stringAfterBWT[i] == stringAfterBWT[j]) - { - arrayPreCalculationTable[i]++; - } - --j; - } - } - var stringBeforeBWT = new StringBuilder(stringAfterBWT); - int positionForNewChar = stringBeforeBWT.Length - 1; - stringBeforeBWT[positionForNewChar] = stringAfterBWT[firstPosition]; - --positionForNewChar; - int sum = arrayPreCalculationTable[firstPosition] + arraySymbols[stringAfterBWT[firstPosition]]; - while (positionForNewChar >= 0) - { - stringBeforeBWT[positionForNewChar] = stringAfterBWT[sum]; - sum = arrayPreCalculationTable[sum] + arraySymbols[stringAfterBWT[sum]]; - --positionForNewChar; - } - return stringBeforeBWT.ToString(); - } - - // Checking compression and unzipping by the Burrows-Wheeler algorithm - public static bool TestBWT() - { - string stringToTest = "ABACABA"; - (var stringAfterBWT, var firstPosition) = BwtConvert(stringToTest); - if (stringAfterBWT != "BCABAAA") - { - return false; - } - return BWTReverseСonvert(stringAfterBWT, firstPosition) == "ABACABA"; - } - - public static void Main(string[] args) - { - if (TestBWT()) - { - Console.WriteLine("All tests correct"); - } - else - { - Console.WriteLine("Some problems with tests..."); - return; - } - Console.WriteLine("Input string"); - var stringToBWT = Console.ReadLine(); - if (stringToBWT == null) - { - Console.WriteLine("You input null string or your input is not correct"); - return; - } - (var returnedStringFromBWT, var firstPosition) = BwtConvert(stringToBWT); - Console.WriteLine("String after BWT"); - Console.WriteLine(returnedStringFromBWT); - var stringBeforeBWT = BWTReverseСonvert(returnedStringFromBWT, firstPosition); - Console.WriteLine(stringBeforeBWT); - } -} \ No newline at end of file diff --git a/BWT/BWT.sln b/stackCalculator/stackCalculator.sln similarity index 58% rename from BWT/BWT.sln rename to stackCalculator/stackCalculator.sln index db64427..bbded00 100644 --- a/BWT/BWT.sln +++ b/stackCalculator/stackCalculator.sln @@ -3,7 +3,7 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 17 VisualStudioVersion = 17.4.33403.182 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BWT", "BWT\BWT.csproj", "{97F74F11-2F27-4B42-A5B1-8D88573DFB01}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "StackCalculator", "stackCalculator\StackCalculator.csproj", "{89A2482C-4A20-41A4-9A42-1623A4FA88C3}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -11,15 +11,15 @@ Global Release|Any CPU = Release|Any CPU EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {97F74F11-2F27-4B42-A5B1-8D88573DFB01}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {97F74F11-2F27-4B42-A5B1-8D88573DFB01}.Debug|Any CPU.Build.0 = Debug|Any CPU - {97F74F11-2F27-4B42-A5B1-8D88573DFB01}.Release|Any CPU.ActiveCfg = Release|Any CPU - {97F74F11-2F27-4B42-A5B1-8D88573DFB01}.Release|Any CPU.Build.0 = Release|Any CPU + {89A2482C-4A20-41A4-9A42-1623A4FA88C3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {89A2482C-4A20-41A4-9A42-1623A4FA88C3}.Debug|Any CPU.Build.0 = Debug|Any CPU + {89A2482C-4A20-41A4-9A42-1623A4FA88C3}.Release|Any CPU.ActiveCfg = Release|Any CPU + {89A2482C-4A20-41A4-9A42-1623A4FA88C3}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {65A6BC48-3287-4942-BACC-A033A3982A41} + SolutionGuid = {E6D50142-7CF4-466F-9F0D-9262A98C0B2C} EndGlobalSection EndGlobal diff --git a/stackCalculator/stackCalculator/InterfaceForStack.cs b/stackCalculator/stackCalculator/InterfaceForStack.cs new file mode 100644 index 0000000..3941104 --- /dev/null +++ b/stackCalculator/stackCalculator/InterfaceForStack.cs @@ -0,0 +1,17 @@ +namespace StackCalculator; + +// Interface for the stack +interface IOperationsWithStack +{ + // Add element to stack + void AddElement(double value); + + // Remove element in stack and return deleted item + (bool, double) RemoveElement(); + + // Print all elements + void PrintTheElements(); + + // Checking that the stack is empty + bool IsEmpty(); +} \ No newline at end of file diff --git a/stackCalculator/stackCalculator/Program.cs b/stackCalculator/stackCalculator/Program.cs new file mode 100644 index 0000000..cb588b8 --- /dev/null +++ b/stackCalculator/stackCalculator/Program.cs @@ -0,0 +1,31 @@ +using System; +using StackCalculator; + +Test test = new Test(); +if (test.TestForProgram()) +{ + Console.WriteLine("All tests correct"); +} +else +{ + Console.WriteLine("Problems..."); + return; +} + +Console.WriteLine("Enter an example in the postfix form"); +var stringWithExpression = Console.ReadLine(); + +PostfixCalculator calculator = new PostfixCalculator(); +if (stringWithExpression == null) +{ + return; +} + +var stackList = new StackList(); +(bool isCorrectWork, double result) = calculator.ConvertToAResponse(stringWithExpression, stackList); +if (!isCorrectWork) +{ + Console.WriteLine("Problems with expression or you tried to divide by zero!"); + return; +} +Console.WriteLine(result); \ No newline at end of file diff --git a/stackCalculator/stackCalculator/Stack.cs b/stackCalculator/stackCalculator/Stack.cs new file mode 100644 index 0000000..ecb7f2f --- /dev/null +++ b/stackCalculator/stackCalculator/Stack.cs @@ -0,0 +1,17 @@ +namespace StackCalculator; + +//Standart stack +abstract public class Stack : IOperationsWithStack +{ + // Add element to stack + virtual public void AddElement(double value) { } + + // Remove element in stack and return deleted item + virtual public (bool, double) RemoveElement() { return (false, 0); } + + // Print all elements + virtual public void PrintTheElements() { } + + // Checking that the stack is empty + virtual public bool IsEmpty() { return false; } +} \ No newline at end of file diff --git a/stackCalculator/stackCalculator/StackCalculator.cs b/stackCalculator/stackCalculator/StackCalculator.cs new file mode 100644 index 0000000..13ff6c7 --- /dev/null +++ b/stackCalculator/stackCalculator/StackCalculator.cs @@ -0,0 +1,73 @@ +namespace StackCalculator; + +// Calculator that counts algebraic expressions in postfix form +public class PostfixCalculator +{ + private const double delta = 0.0000000000001; + + // Receives the input string in which the expression is written in postfix form, finds the result + public (bool, double) ConvertToAResponse(string stringWithExpression, Stack stackExpression) + { + int i = 0; + string[] expressionArray = stringWithExpression.Split(' '); + while (i < expressionArray.Length) + { + var isCorrectNumber = Int32.TryParse(expressionArray[i], out var number); + if (isCorrectNumber) + { + stackExpression.AddElement(number); + } + else + { + if (expressionArray[i].Length != 1) + { + return (false, 0); + } + double numberAfter = 0; + (var isCorrect, var firstNumber) = stackExpression.RemoveElement(); + + if (!isCorrect) + { + return (false, 0); + } + + (isCorrect, var secondNumber) = stackExpression.RemoveElement(); + + if (!isCorrect) + { + return (false, 0); + } + + switch (expressionArray[i][0]) + { + case '*': + numberAfter = firstNumber * secondNumber; + break; + case '+': + numberAfter = firstNumber + secondNumber; + break; + case '-': + numberAfter = secondNumber - firstNumber; + break; + case '/': + if (Math.Abs(firstNumber) < delta) + { + return (false, 0); + } + numberAfter = secondNumber / firstNumber; + break; + default: + return (false, 0); + } + stackExpression.AddElement(numberAfter); + } + ++i; + } + (var isCorrectExpression, var result) = stackExpression.RemoveElement(); + if (!isCorrectExpression) + { + return (false, 0); + } + return stackExpression.IsEmpty() ? (true, result) : (false, 0); + } +} diff --git a/stackCalculator/stackCalculator/StackWIthArray.cs b/stackCalculator/stackCalculator/StackWIthArray.cs new file mode 100644 index 0000000..ffe5a4a --- /dev/null +++ b/stackCalculator/stackCalculator/StackWIthArray.cs @@ -0,0 +1,56 @@ +namespace StackCalculator; + +// Stack implemented on an array +public class StackWithArray : Stack +{ + private double[] stackArray; + private int numberOfElements; + private int sizeStack = 10; + + public StackWithArray() + { + stackArray = new double[sizeStack]; + } + + public bool ChangeStackSize(int size) + { + if (size < sizeStack) + { + return false; + } + Array.Resize(ref stackArray, size); + return true; + } + + public override void AddElement(double value) + { + if (numberOfElements == sizeStack) + { + ChangeStackSize(sizeStack * 2); + } + stackArray[numberOfElements] = value; + ++numberOfElements; + } + + public override (bool, double) RemoveElement() + { + if (numberOfElements == 0) + { + return (false, 0); + } + double result = stackArray[numberOfElements - 1]; + --numberOfElements; + return (true, result); + } + + public override void PrintTheElements() + { + for (int i = 0; i < numberOfElements; i++) + { + Console.WriteLine(stackArray[i]); + } + } + + public override bool IsEmpty() + => numberOfElements == 0; +} diff --git a/stackCalculator/stackCalculator/StackWithList.cs b/stackCalculator/stackCalculator/StackWithList.cs new file mode 100644 index 0000000..844e0fc --- /dev/null +++ b/stackCalculator/stackCalculator/StackWithList.cs @@ -0,0 +1,58 @@ +namespace StackCalculator; + +// Stack implemented on list +public class StackList : Stack +{ + private StackElement headStack; + + public override void AddElement(double value) + { + var item = new StackElement(value); + if (headStack == null) + { + headStack = item; + } + else + { + StackElement copy = headStack; + headStack = item; + headStack.Next = copy; + } + } + + public override(bool, double) RemoveElement() + { + if (headStack == null) + { + return (false, 0); + } + double item = headStack.ValueStack; + StackElement copy = headStack.Next; + headStack = copy; + return (true, item); + } + + public override void PrintTheElements() + { + StackElement walker = headStack; + while (walker != null) + { + Console.WriteLine(walker.ValueStack); + walker = walker.Next; + } + } + + public override bool IsEmpty() => headStack == null; + + private class StackElement + { + public StackElement(double value) + { + ValueStack = value; + Next = null; + } + + public double ValueStack { get; set; } + public StackElement Next { get; set; } + } +} \ No newline at end of file diff --git a/stackCalculator/stackCalculator/Tests.cs b/stackCalculator/stackCalculator/Tests.cs new file mode 100644 index 0000000..0a3a872 --- /dev/null +++ b/stackCalculator/stackCalculator/Tests.cs @@ -0,0 +1,29 @@ +namespace StackCalculator; + +public class Test +{ + // Tests the program + public bool TestForProgram() + { + var calculator = new PostfixCalculator(); + var stackList = new StackList(); + (var isCorrectWork, var result) = calculator.ConvertToAResponse("123 23 +", stackList); + if (!isCorrectWork || result != 146) + { + return false; + } + var stackArray = new StackWithArray(); + (isCorrectWork, result) = calculator.ConvertToAResponse("123 23 +", stackArray); + if (!isCorrectWork || result != 146) + { + return false; + } + (isCorrectWork, result) = calculator.ConvertToAResponse("123 23", stackList); + if (isCorrectWork) + { + return false; + } + (isCorrectWork, result) = calculator.ConvertToAResponse("123 23", stackArray); + return !isCorrectWork; + } +} diff --git a/BWT/BWT/BWT.csproj b/stackCalculator/stackCalculator/stackCalculator.csproj similarity index 73% rename from BWT/BWT/BWT.csproj rename to stackCalculator/stackCalculator/stackCalculator.csproj index f02677b..d4116cd 100644 --- a/BWT/BWT/BWT.csproj +++ b/stackCalculator/stackCalculator/stackCalculator.csproj @@ -7,4 +7,8 @@ enable + + + +