Add sequential implementation

This commit is contained in:
Raffaele Mignone 2021-03-15 21:04:23 +01:00
parent 1526bd1db6
commit 24535aff47
Signed by: norangebit
GPG Key ID: F5255658CB220573
11 changed files with 153 additions and 0 deletions

8
.idea/.gitignore vendored Normal file
View File

@ -0,0 +1,8 @@
# Default ignored files
/shelf/
/workspace.xml
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml
# Editor-based HTTP Client requests
/httpRequests/

2
.idea/kmp.iml Normal file
View File

@ -0,0 +1,2 @@
<?xml version="1.0" encoding="UTF-8"?>
<module classpath="CMake" type="CPP_MODULE" version="4" />

4
.idea/misc.xml Normal file
View File

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CMakeWorkspace" PROJECT_DIR="$PROJECT_DIR$" />
</project>

8
.idea/modules.xml Normal file
View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/kmp.iml" filepath="$PROJECT_DIR$/.idea/kmp.iml" />
</modules>
</component>
</project>

6
.idea/vcs.xml Normal file
View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>

6
CMakeLists.txt Normal file
View File

@ -0,0 +1,6 @@
cmake_minimum_required(VERSION 3.17)
project(kmp C)
set(CMAKE_C_STANDARD 99)
add_executable(kmp main.c kmp.c kmp.h util.h util.c)

68
kmp.c Normal file
View File

@ -0,0 +1,68 @@
#include <malloc.h>
#include <string.h>
#define CHUNK 5
int *create_lps(char *pattern, int pattern_len, int *lps) {
int last_matched_char = 1;
int last_prefix_char = 0;
lps[0] = 0;
while (last_matched_char < pattern_len) {
if (pattern[last_matched_char] == pattern[last_prefix_char]) {
lps[last_matched_char] = last_prefix_char + 1;
last_matched_char++;
last_prefix_char++;
} else if (last_prefix_char != 0)
// check if matches the previous prefix
last_prefix_char = lps[last_prefix_char - 1];
else {
// if there isn't a prefix restart from the begin
lps[last_matched_char] = 0;
last_matched_char++;
}
}
return lps;
}
int *search_pattern(char *text, char *pattern, int *lps, int *match_number, int *residue) {
int size = CHUNK;
int *matches = (int *) malloc(sizeof(int) * size);
int text_index = 0;
int pattern_index = 0;
int text_len = strlen(text);
int pattern_len = strlen(pattern);
while (text_index < text_len) {
// char matches
if (text[text_index] == pattern[pattern_index]) {
text_index++;
pattern_index++;
// full match found
if (pattern_index == pattern_len) {
// growth array if full
if (*match_number == size) {
size *= 2;
matches = (int *) realloc(matches, size * sizeof(int));
}
matches[*match_number] = text_index - pattern_len;
*match_number = *match_number + 1;
pattern_index = lps[pattern_index - 1];
}
// char not matches on first char
} else if (pattern_index == 0) {
text_index++;
} else {
pattern_index = lps[pattern_index - 1];
}
}
*residue = pattern_index;
return matches;
}

8
kmp.h Normal file
View File

@ -0,0 +1,8 @@
#ifndef KMP_KMP_H
#define KMP_KMP_H
int *create_lps(char *, int, int *);
int *search_pattern(char *, char *, int *, int *, int *);
#endif //KMP_KMP_H

25
main.c Normal file
View File

@ -0,0 +1,25 @@
#include <stdio.h>
#include <string.h>
#include "kmp.h"
#include "util.h"
int main() {
char *patter = "acabacacd";
char *text = "acfacabacabacacdac";
int pattern_len = strlen(patter);
// long proper suffix array
int lps[pattern_len];
create_lps(patter, pattern_len, lps);
int match_number = 0;
int residue;
int *matches = search_pattern(text, patter, lps, &match_number, &residue);
print_array(matches, match_number);
printf("%d\n", residue);
}

12
util.c Normal file
View File

@ -0,0 +1,12 @@
#include <stdio.h>
void print_array(int *array, int length) {
if (length == 0) return;
printf("|");
for (int i = 0; i < length; ++i) {
printf("%d|", array[i]);
}
printf("\n");
}

6
util.h Normal file
View File

@ -0,0 +1,6 @@
#ifndef KMP_UTIL_H
#define KMP_UTIL_H
void print_array(int *, int);
#endif //KMP_UTIL_H