chore(C): add longest common subsequence (#536)

pull/567/head
Elena Mokeeva 2021-10-12 14:56:12 +02:00 committed by GitHub
parent 399383294c
commit 9085ee6a98
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 107 additions and 0 deletions

View File

@ -39,6 +39,7 @@
- [Count Words](strings/count-words.c) - [Count Words](strings/count-words.c)
- [Palindrome](strings/palindrome.c) - [Palindrome](strings/palindrome.c)
- [Permutation of String](strings/Permutation-of-String.c) - [Permutation of String](strings/Permutation-of-String.c)
- [Longest Common Subsequence](strings/longest-common-subsequence.c)
## Tree ## Tree
- [Height Of Tree](tree/height-of-a-tree.c) - [Height Of Tree](tree/height-of-a-tree.c)

View File

@ -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 <stdio.h>
#include <string.h>
#include <stdlib.h>
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;
}