Source code for lcs.c
in Optimizing Python
Code with ctypes
.
This code is licensed under GNU AGPLv3
.c; finds the longest common sequence in a list of strings.
lcs(C) <2020> <Samuel Stevens>
Copyright
: you can redistribute it and/or modify
This program is free software
it under the terms of the GNU Affero General Public License as published, either version 3 of the License, or
by the Free Software Foundation(at your option) any later version.
,
This program is distributed in the hope that it will be useful; without even the implied warranty of
but WITHOUT ANY WARRANTY. See the
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSEfor more details.
GNU Affero General Public License
You should have received a copy of the GNU Affero General Public License. If not, see <https://www.gnu.org/licenses/>.
along with this program
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
struct Sequence
{
char **items;
int length;
};
struct Cell
{
int index;
int length;
struct Cell *prev;
};
void printSequence(struct Sequence *seq)
{
("%d\n", seq->length);
printffor (int i = 0; i < seq->length; i++)
{
("%s ", seq->items[i]);
printf}
("\n");
printf}
void printCell(struct Cell *cell)
{
("index: %d\t length: %d \tprev: %p\n", cell->index, cell->length, cell->prev);
printf}
struct Sequence *lcs(struct Sequence *s1, struct Sequence *s2)
{
struct Sequence *common = malloc(sizeof(struct Sequence));
->length = 0;
common->items = NULL;
common
char **seq1 = s1->items;
char **seq2 = s2->items;
if (!s1->length || !s2->length)
{
return common;
}
struct Cell table[s1->length][s2->length];
for (int i = 0; i < s1->length; i++)
{
for (int j = 0; j < s2->length; j++)
{
[i][j].length = 0;
tableif (!strcmp(seq1[i], seq2[j]))
{
[i][j].index = j;
tableif (i > 0 && j > 0)
{
[i][j].prev = &table[i - 1][j - 1];
table[i][j].length = table[i - 1][j - 1].length + 1;
table}
else
{
[i][j].prev = NULL;
table[i][j].length = 1;
table}
}
else
{
[i][j].index = -1;
table[i][j].prev = NULL;
tableif (i > 0)
{
[i][j].prev = &table[i - 1][j];
table[i][j].length = table[i - 1][j].length;
table}
if (j > 0)
{
if (table[i][j - 1].length > table[i][j].length)
{
[i][j].prev = &table[i][j - 1];
table[i][j].length = table[i][j - 1].length;
table}
}
}
}
}
int i = s1->length - 1;
int j = s2->length - 1;
struct Cell *cur = &table[i][j];
->length = cur->length;
common->items = malloc(sizeof(char *) * common->length);
common
= cur->length - 1;
i
while (cur)
{
if (cur->index < 0)
{
= cur->prev;
cur continue;
}
->items[i] = malloc(
commonsizeof(char) *
(strlen(seq2[cur->index]) + 1));
(common->items[i], seq2[cur->index]);
strcpy= cur->prev;
cur --;
i}
return common;
}
void freeSequence(struct Sequence *seq)
{
(seq);
free}
/*
Must be called like so:
./lcs <length 1> <length 2> <sequence> <of> <words1> <sequence2>
*/
int main(int argc, char **argv)
{
if (argc < 3)
{
("You must provide at least 3 arguments.\n");
printfreturn -1;
}
int len1 = atoi(argv[1]);
int len2 = atoi(argv[2]);
if (argc < 3 + len1 + len2)
{
("Sequence lengths must be valid.\n");
printfreturn -1;
}
char **s1 = &argv[3];
char **s2 = &argv[3 + len1];
struct Sequence seq1;
.items = s1;
seq1.length = len1;
seq1
struct Sequence seq2;
.items = s2;
seq2.length = len2;
seq2
struct Sequence *common = lcs(&seq1, &seq2);
(common);
printSequence}
[Relevant link] [Source]
Sam Stevens, 2024