From 9085ee6a988091eaaaa6ec76538ef36c2fbdb0fd Mon Sep 17 00:00:00 2001 From: Elena Mokeeva Date: Tue, 12 Oct 2021 14:56:12 +0200 Subject: [PATCH] chore(C): add longest common subsequence (#536) --- algorithms/C/README.md | 1 + .../C/strings/longest-common-subsequence.c | 106 ++++++++++++++++++ 2 files changed, 107 insertions(+) create mode 100644 algorithms/C/strings/longest-common-subsequence.c diff --git a/algorithms/C/README.md b/algorithms/C/README.md index 4b814d11..140bdd49 100644 --- a/algorithms/C/README.md +++ b/algorithms/C/README.md @@ -39,6 +39,7 @@ - [Count Words](strings/count-words.c) - [Palindrome](strings/palindrome.c) - [Permutation of String](strings/Permutation-of-String.c) +- [Longest Common Subsequence](strings/longest-common-subsequence.c) ## Tree - [Height Of Tree](tree/height-of-a-tree.c) diff --git a/algorithms/C/strings/longest-common-subsequence.c b/algorithms/C/strings/longest-common-subsequence.c new file mode 100644 index 00000000..12f33c5d --- /dev/null +++ b/algorithms/C/strings/longest-common-subsequence.c @@ -0,0 +1,106 @@ +/* Program to find the longest common subsequence of two strings. +Example: longest common subsequence of "abcde" and "abzyxcde" is "cde". + +Worst case time complexety: O(n*m^2), where n is the length of the first string, + and m is the length of the second string. + Example strings for worst case time: "aaaaa" and "aaaaa" + Explanation: for each character in the first string, you + iterate through the second string. For each character of + the second string, you iterate through the common sequence + that starts at that character. In the worst case, + for each character in the second string, you iterate through + the remaining second string. That's why the algorithm is O(n*m^2) */ +#include +#include +#include + + +char* longest_common_subsequence(char *string1, char *string2); + +int main() +{ + /* Example: Finding longest common subsequence of following Strings + "Hello World! Ciao Mondo! Hei Maailma!" + and "Bonjour Le Monde! Hei Maailma! Ciao Mondo!" */ + + char* first_seqence1 = "Hello World! Ciao Mondo! Hei Maailma!"; + char* second_sequence1 = "Bonjour Le Monde! Hei Maailma! Ciao Mondo!"; + char* longest_subsequence1 = longest_common_subsequence(first_seqence1, second_sequence1); + printf("%s\n", longest_subsequence1); + free(longest_subsequence1); + + /* Output: "! Hei Maailma!"*/ + + /* Example: Finding longest common subsequence of following Strings + "abcde" + and "abzyxcde" */ + + char* first_seqence2 = "abcde"; + char* second_sequence2 = "abzyxcde"; + char* longest_subsequence2 = longest_common_subsequence(first_seqence2, second_sequence2); + printf("%s\n", longest_subsequence2); + free(longest_subsequence2); + + /* Output: "cde"*/ + + /* Example: Finding longest common subsequence of following Strings + "aaaaaa" + and "aaa" */ + + char* first_seqence3 = "aaaaaa"; + char* second_sequence3 = "aaa"; + char* longest_subsequence3 = longest_common_subsequence(first_seqence3, second_sequence3); + printf("%s\n", longest_subsequence3); + free(longest_subsequence3); + + /* Output: "aaa"*/ + +} + +/* Function which compares two character sequences and returns a pointer +to the longest common subsequence */ +char* longest_common_subsequence(char *string1, char *string2) +{ + int len_of_longest = 0; //length of the currently longest common subsequence + int index_in_current_subsequence = 0; //index for iteration through a common subsequence + char *pointer_to_longest; //pointer to the longest common subsequence inside string1 + char *original_string2 = string2; //copy of string2 + + //iterating through first string + // and evaluating the length of substring starting at the current character + while(*string1!='\0') + { + //iterating through string2 to check for common substring + while(*string2!='\0') + { + /* iterating through the common substring, to see how long it is. + Checking each character, if the subsequence doesn't match any longer, + of if one of the strings has ended */ + while (*(string2+index_in_current_subsequence) == +*(string1+index_in_current_subsequence) && *(string2+index_in_current_subsequence) != '\0' && +*(string2+index_in_current_subsequence) != '\0') + { + index_in_current_subsequence++; + } + + //saving the substring, if it's longer the the previously longest substring + if (index_in_current_subsequence>len_of_longest) + { + len_of_longest=index_in_current_subsequence; + pointer_to_longest=string1; + } + index_in_current_subsequence = 0; + string2++; + } + string2 = original_string2; //returning to the begin of string2 + string1++; + } + + //copying the subsequence from string2 into memory (heap) + char *subsequence = (char*) malloc((len_of_longest+1)*sizeof(char)); + strncpy(subsequence, pointer_to_longest, len_of_longest); + + //Setting the terminating character at the end + *(subsequence+len_of_longest)='\0'; + return subsequence; +}