Add sequential implementation
This commit is contained in:
parent
1526bd1db6
commit
24535aff47
8
.idea/.gitignore
vendored
Normal file
8
.idea/.gitignore
vendored
Normal 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
2
.idea/kmp.iml
Normal 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
4
.idea/misc.xml
Normal 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
8
.idea/modules.xml
Normal 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
6
.idea/vcs.xml
Normal 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
6
CMakeLists.txt
Normal 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
68
kmp.c
Normal 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
8
kmp.h
Normal 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
25
main.c
Normal 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
12
util.c
Normal 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");
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user