diff --git "a/Homework \342\204\22611/Knuth\342\200\223Morris\342\200\223Pratt/Knuth\342\200\223Morris\342\200\223Pratt.sln" "b/Homework \342\204\22611/Knuth\342\200\223Morris\342\200\223Pratt/Knuth\342\200\223Morris\342\200\223Pratt.sln" new file mode 100644 index 0000000..07b4ccd --- /dev/null +++ "b/Homework \342\204\22611/Knuth\342\200\223Morris\342\200\223Pratt/Knuth\342\200\223Morris\342\200\223Pratt.sln" @@ -0,0 +1,31 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.31410.357 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Knuth–Morris–Pratt", "Knuth–Morris–Pratt\Knuth–Morris–Pratt.vcxproj", "{5C13E66F-7004-4B91-82CA-D62CAB4C2071}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {5C13E66F-7004-4B91-82CA-D62CAB4C2071}.Debug|x64.ActiveCfg = Debug|x64 + {5C13E66F-7004-4B91-82CA-D62CAB4C2071}.Debug|x64.Build.0 = Debug|x64 + {5C13E66F-7004-4B91-82CA-D62CAB4C2071}.Debug|x86.ActiveCfg = Debug|Win32 + {5C13E66F-7004-4B91-82CA-D62CAB4C2071}.Debug|x86.Build.0 = Debug|Win32 + {5C13E66F-7004-4B91-82CA-D62CAB4C2071}.Release|x64.ActiveCfg = Release|x64 + {5C13E66F-7004-4B91-82CA-D62CAB4C2071}.Release|x64.Build.0 = Release|x64 + {5C13E66F-7004-4B91-82CA-D62CAB4C2071}.Release|x86.ActiveCfg = Release|Win32 + {5C13E66F-7004-4B91-82CA-D62CAB4C2071}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {F66AE844-2478-4972-BBC9-7D9AFC17B3F7} + EndGlobalSection +EndGlobal diff --git "a/Homework \342\204\22611/Knuth\342\200\223Morris\342\200\223Pratt/Knuth\342\200\223Morris\342\200\223Pratt/KMP.c" "b/Homework \342\204\22611/Knuth\342\200\223Morris\342\200\223Pratt/Knuth\342\200\223Morris\342\200\223Pratt/KMP.c" new file mode 100644 index 0000000..e072af0 --- /dev/null +++ "b/Homework \342\204\22611/Knuth\342\200\223Morris\342\200\223Pratt/Knuth\342\200\223Morris\342\200\223Pratt/KMP.c" @@ -0,0 +1,66 @@ +#include "KMP.h" +#include +#include + +int* findPrefix(char* substring, int* error) +{ + int* prefix = calloc(strlen(substring) + 1, sizeof(int)); + if (prefix == NULL) + { + *error = 1; + return NULL; + } + prefix[0] = 0; + int i = 1; + int j = 0; + while (substring[i] != '\0') + { + if (substring[j] == substring[i]) + { + prefix[i] = j + 1; + i++; + j++; + } + else if (j == 0) + { + prefix[i] = 0; + i++; + } + else + { + j = prefix[j - 1]; + } + } + return prefix; +} + +int algorithmKMP(char* string, char* substring, int* prefix) +{ + int counterForString = 0; + int CounterForSubstring = 0; + while (string[counterForString] != '\0') + { + if (string[counterForString] == substring[CounterForSubstring]) + { + counterForString++; + CounterForSubstring++; + if (CounterForSubstring == strlen(substring)) + { + return counterForString - strlen(substring) + 1; + } + } + else if (CounterForSubstring == 0) + { + counterForString++; + if (counterForString == strlen(string)) + { + return -1; + } + } + else + { + CounterForSubstring = prefix[CounterForSubstring - 1]; + } + } + return -1; +} \ No newline at end of file diff --git "a/Homework \342\204\22611/Knuth\342\200\223Morris\342\200\223Pratt/Knuth\342\200\223Morris\342\200\223Pratt/KMP.h" "b/Homework \342\204\22611/Knuth\342\200\223Morris\342\200\223Pratt/Knuth\342\200\223Morris\342\200\223Pratt/KMP.h" new file mode 100644 index 0000000..7e582cb --- /dev/null +++ "b/Homework \342\204\22611/Knuth\342\200\223Morris\342\200\223Pratt/Knuth\342\200\223Morris\342\200\223Pratt/KMP.h" @@ -0,0 +1,7 @@ +#pragma once + +// Function for finding the maximum matching suffix and prefix +int* findPrefix(char* substring, int* error); + +// Function for searching for a substring in a string +int algorithmKMP(char* string, char* substring, int* prefix); \ No newline at end of file diff --git "a/Homework \342\204\22611/Knuth\342\200\223Morris\342\200\223Pratt/Knuth\342\200\223Morris\342\200\223Pratt/Knuth\342\200\223Morris\342\200\223Pratt.vcxproj" "b/Homework \342\204\22611/Knuth\342\200\223Morris\342\200\223Pratt/Knuth\342\200\223Morris\342\200\223Pratt/Knuth\342\200\223Morris\342\200\223Pratt.vcxproj" new file mode 100644 index 0000000..c149091 --- /dev/null +++ "b/Homework \342\204\22611/Knuth\342\200\223Morris\342\200\223Pratt/Knuth\342\200\223Morris\342\200\223Pratt/Knuth\342\200\223Morris\342\200\223Pratt.vcxproj" @@ -0,0 +1,157 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 16.0 + Win32Proj + {5c13e66f-7004-4b91-82ca-d62cab4c2071} + KnuthMorrisPratt + 10.0 + + + + Application + true + v142 + Unicode + + + Application + false + v142 + true + Unicode + + + Application + true + v142 + Unicode + + + Application + false + v142 + true + Unicode + + + + + + + + + + + + + + + + + + + + + true + + + false + + + true + + + false + + + + Level3 + true + WIN32;_DEBUG;_CRT_SECURE_NO_WARNINGS;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + + + + + Level3 + true + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + true + true + + + + + Level3 + true + _DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + + + + + Level3 + true + true + true + NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + true + true + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git "a/Homework \342\204\22611/Knuth\342\200\223Morris\342\200\223Pratt/Knuth\342\200\223Morris\342\200\223Pratt/Knuth\342\200\223Morris\342\200\223Pratt.vcxproj.filters" "b/Homework \342\204\22611/Knuth\342\200\223Morris\342\200\223Pratt/Knuth\342\200\223Morris\342\200\223Pratt/Knuth\342\200\223Morris\342\200\223Pratt.vcxproj.filters" new file mode 100644 index 0000000..83ddec1 --- /dev/null +++ "b/Homework \342\204\22611/Knuth\342\200\223Morris\342\200\223Pratt/Knuth\342\200\223Morris\342\200\223Pratt/Knuth\342\200\223Morris\342\200\223Pratt.vcxproj.filters" @@ -0,0 +1,48 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Исходные файлы + + + Исходные файлы + + + Исходные файлы + + + Исходные файлы + + + Исходные файлы + + + + + Файлы заголовков + + + Файлы заголовков + + + Файлы заголовков + + + Файлы заголовков + + + \ No newline at end of file diff --git "a/Homework \342\204\22611/Knuth\342\200\223Morris\342\200\223Pratt/Knuth\342\200\223Morris\342\200\223Pratt/Main.c" "b/Homework \342\204\22611/Knuth\342\200\223Morris\342\200\223Pratt/Knuth\342\200\223Morris\342\200\223Pratt/Main.c" new file mode 100644 index 0000000..fe13fc7 --- /dev/null +++ "b/Homework \342\204\22611/Knuth\342\200\223Morris\342\200\223Pratt/Knuth\342\200\223Morris\342\200\223Pratt/Main.c" @@ -0,0 +1,49 @@ +#include "KMP.h" +#include "ReadString.h" +#include "ReadFile.h" +#include +#include +#include "TestKMP.h" + +int main() +{ + if (!testKMP()) + { + printf("Test failed"); + return -1; + } + printf("enter the substring\n"); + int error = 0; + char* substring = readString(&error); + if (error == 1) + { + printf("memory not allocated"); + return -1; + } + char* string = readFile("Text.txt", &error); + if (error == 1) + { + free(substring); + printf("memory not allocated"); + return -1; + } + if (error == 2) + { + free(substring); + printf("file not found"); + return -1; + } + int* prefix = findPrefix(substring, &error); + if (error == 1) + { + free(string); + free(substring); + printf("memory not allocated"); + return -1; + } + const int result = algorithmKMP(string, substring, prefix); + free(substring); + free(string); + free(prefix); + printf("the position of the first occurrence of the substring in the string (-1 if there is no occurrence) = %d", result); +} \ No newline at end of file diff --git "a/Homework \342\204\22611/Knuth\342\200\223Morris\342\200\223Pratt/Knuth\342\200\223Morris\342\200\223Pratt/ReadFile.c" "b/Homework \342\204\22611/Knuth\342\200\223Morris\342\200\223Pratt/Knuth\342\200\223Morris\342\200\223Pratt/ReadFile.c" new file mode 100644 index 0000000..6ce5e66 --- /dev/null +++ "b/Homework \342\204\22611/Knuth\342\200\223Morris\342\200\223Pratt/Knuth\342\200\223Morris\342\200\223Pratt/ReadFile.c" @@ -0,0 +1,41 @@ +#include "ReadFile.h" +#include +#include + +char* readFile(const char* filename, int* error) +{ + FILE* file = fopen(filename, "r"); + if (file == NULL) + { + *error = 2; + return NULL; + } + int counter = 0; + char temporary = '\0'; + while (!feof(file)) + { + if (fscanf(file, "%c", &temporary) != EOF) + { + counter++; + } + } + fseek(file, 0L, SEEK_SET); + char* string = calloc(counter + 1, sizeof(char)); + if (string == NULL) + { + *error = 1; + return NULL; + } + int newCounter = 0; + while (!feof(file) && newCounter < counter) + { + if (fscanf(file, "%c", &temporary) != EOF) + { + string[newCounter] = temporary; + newCounter++; + } + } + string[newCounter] = '\0'; + fclose(file); + return string; +} \ No newline at end of file diff --git "a/Homework \342\204\22611/Knuth\342\200\223Morris\342\200\223Pratt/Knuth\342\200\223Morris\342\200\223Pratt/ReadFile.h" "b/Homework \342\204\22611/Knuth\342\200\223Morris\342\200\223Pratt/Knuth\342\200\223Morris\342\200\223Pratt/ReadFile.h" new file mode 100644 index 0000000..21de1c0 --- /dev/null +++ "b/Homework \342\204\22611/Knuth\342\200\223Morris\342\200\223Pratt/Knuth\342\200\223Morris\342\200\223Pratt/ReadFile.h" @@ -0,0 +1,4 @@ +#pragma once + +// Function for reading text from a file +char* readFile(const char* filename, int* error); diff --git "a/Homework \342\204\22611/Knuth\342\200\223Morris\342\200\223Pratt/Knuth\342\200\223Morris\342\200\223Pratt/ReadString.c" "b/Homework \342\204\22611/Knuth\342\200\223Morris\342\200\223Pratt/Knuth\342\200\223Morris\342\200\223Pratt/ReadString.c" new file mode 100644 index 0000000..1c3e0c9 --- /dev/null +++ "b/Homework \342\204\22611/Knuth\342\200\223Morris\342\200\223Pratt/Knuth\342\200\223Morris\342\200\223Pratt/ReadString.c" @@ -0,0 +1,37 @@ +#include "ReadString.h" +#include +#include +#include + +char* readString(int* error) +{ + int index = 0; + int size = 100; + char* array = calloc(size, sizeof(char)); + if (array == NULL) + { + *error = 1; + return NULL; + } + char symbol = getchar(); + while (symbol != '\n') + { + array[index] = symbol; + if (strlen(array) == size) + { + size = size * 2; + char* temporary = realloc(array, size * sizeof(char)); + if (temporary == NULL) + { + *error = 1; + free(array); + return NULL; + } + array = temporary; + } + symbol = getchar(); + index++; + } + array[index] = '\0'; + return array; +} \ No newline at end of file diff --git "a/Homework \342\204\22611/Knuth\342\200\223Morris\342\200\223Pratt/Knuth\342\200\223Morris\342\200\223Pratt/ReadString.h" "b/Homework \342\204\22611/Knuth\342\200\223Morris\342\200\223Pratt/Knuth\342\200\223Morris\342\200\223Pratt/ReadString.h" new file mode 100644 index 0000000..7fc7010 --- /dev/null +++ "b/Homework \342\204\22611/Knuth\342\200\223Morris\342\200\223Pratt/Knuth\342\200\223Morris\342\200\223Pratt/ReadString.h" @@ -0,0 +1,4 @@ +#pragma once + +// Function for entering and reading substrings of arbitrary size +char* readString(int* error); \ No newline at end of file diff --git "a/Homework \342\204\22611/Knuth\342\200\223Morris\342\200\223Pratt/Knuth\342\200\223Morris\342\200\223Pratt/Test.txt" "b/Homework \342\204\22611/Knuth\342\200\223Morris\342\200\223Pratt/Knuth\342\200\223Morris\342\200\223Pratt/Test.txt" new file mode 100644 index 0000000..8de08e1 --- /dev/null +++ "b/Homework \342\204\22611/Knuth\342\200\223Morris\342\200\223Pratt/Knuth\342\200\223Morris\342\200\223Pratt/Test.txt" @@ -0,0 +1 @@ +asdasda sdcdvdsvr rgrggg njn rtr plerg romrovrmvmrov vvjei3-133 wef32f934f eqf0jewjew ascnucbnew8fvh348hvwe wvewrvw wivew0ivew viv eqrgj39q93f34 f3f 3fy834fy348fh3 f34fu 348f34j8f34f8herv834fhvnv ervherver7vhervbryvhrevhhqe7v 134yg834hg3498gy3h4g834gh34g rvjovwevnerubernver vervnrghbftn rfre tkf sdnvjrg7eruvberuvnwer9gfr hfnrjgughnerugberng erguberngijeruveqnvuerhvuervnjv vhreuvhreuvqjwjgioeqr \ No newline at end of file diff --git "a/Homework \342\204\22611/Knuth\342\200\223Morris\342\200\223Pratt/Knuth\342\200\223Morris\342\200\223Pratt/TestKMP.c" "b/Homework \342\204\22611/Knuth\342\200\223Morris\342\200\223Pratt/Knuth\342\200\223Morris\342\200\223Pratt/TestKMP.c" new file mode 100644 index 0000000..9ba2c14 --- /dev/null +++ "b/Homework \342\204\22611/Knuth\342\200\223Morris\342\200\223Pratt/Knuth\342\200\223Morris\342\200\223Pratt/TestKMP.c" @@ -0,0 +1,43 @@ +#include "TestKMP.h" +#include "ReadFile.h" +#include "KMP.h" +#include + +bool testKMP() +{ + int error = 0; + char* string = readFile("Test.txt", &error); + if (error != 0) + { + return false; + } + int* firstPrefix = findPrefix("dcdv", &error); + if (error == 1) + { + free(string); + return false; + } + int* secondPrefix = findPrefix("rfre", &error); + if (error == 1) + { + free(firstPrefix); + free(string); + return false; + } + int* thirdPrefix = findPrefix("eewgeg", &error); + if (error == 1) + { + free(secondPrefix); + free(firstPrefix); + free(string); + return false; + } + const int firstResult = algorithmKMP(string, "dcdv", firstPrefix); + const int secondResult = algorithmKMP(string, "rfre", secondPrefix); + const int thirdResult = algorithmKMP(string, "eewgeg", thirdPrefix); + free(thirdPrefix); + free(secondPrefix); + free(firstPrefix); + free(string); + return firstResult == 10 && secondResult == 289 && thirdResult == -1; +} \ No newline at end of file diff --git "a/Homework \342\204\22611/Knuth\342\200\223Morris\342\200\223Pratt/Knuth\342\200\223Morris\342\200\223Pratt/TestKMP.h" "b/Homework \342\204\22611/Knuth\342\200\223Morris\342\200\223Pratt/Knuth\342\200\223Morris\342\200\223Pratt/TestKMP.h" new file mode 100644 index 0000000..6ce03bf --- /dev/null +++ "b/Homework \342\204\22611/Knuth\342\200\223Morris\342\200\223Pratt/Knuth\342\200\223Morris\342\200\223Pratt/TestKMP.h" @@ -0,0 +1,5 @@ +#pragma once +#include + +// Function for testing the KMP algorithm +bool testKMP(); \ No newline at end of file diff --git "a/Homework \342\204\22611/Knuth\342\200\223Morris\342\200\223Pratt/Knuth\342\200\223Morris\342\200\223Pratt/Text.txt" "b/Homework \342\204\22611/Knuth\342\200\223Morris\342\200\223Pratt/Knuth\342\200\223Morris\342\200\223Pratt/Text.txt" new file mode 100644 index 0000000..af9e874 --- /dev/null +++ "b/Homework \342\204\22611/Knuth\342\200\223Morris\342\200\223Pratt/Knuth\342\200\223Morris\342\200\223Pratt/Text.txt" @@ -0,0 +1 @@ +acccdercjc ovmv3omvrjrvjrverjvtyu wgbfdbbbbb \ No newline at end of file