From 860c56a4d21272d165103929bb1d7a9232c62f38 Mon Sep 17 00:00:00 2001 From: begeekmyfriend Date: Thu, 28 Sep 2017 09:50:13 +0800 Subject: [PATCH] Palindrome partitioning Signed-off-by: begeekmyfriend --- 005_longest_palindromic_substring/Makefile | 2 +- .../longest_palindromic_substring.c | 18 ++- 131_palindrome_patitioning/Makefile | 2 + .../palindrome_partition.c | 103 ++++++++++++++++++ 4 files changed, 118 insertions(+), 7 deletions(-) create mode 100644 131_palindrome_patitioning/Makefile create mode 100644 131_palindrome_patitioning/palindrome_partition.c diff --git a/005_longest_palindromic_substring/Makefile b/005_longest_palindromic_substring/Makefile index 2f15a5d..d2434e6 100644 --- a/005_longest_palindromic_substring/Makefile +++ b/005_longest_palindromic_substring/Makefile @@ -1,2 +1,2 @@ all: - gcc -O2 -o palindrome longest_palindromic_substring.c + gcc -O2 -o test longest_palindromic_substring.c diff --git a/005_longest_palindromic_substring/longest_palindromic_substring.c b/005_longest_palindromic_substring/longest_palindromic_substring.c index 4bfa4dc..540a9cb 100644 --- a/005_longest_palindromic_substring/longest_palindromic_substring.c +++ b/005_longest_palindromic_substring/longest_palindromic_substring.c @@ -2,15 +2,14 @@ #include #include -static char palindrome[1000]; - -static void palindrome_find(char *s, int len, int low, int high, int *max_size) { +static void find(char *s, int len, int low, int high, int *max_size, char *palindrome) { while (low >= 0 && high < len && s[low] == s[high]) { low--; high++; } low++; high--; + if (high - low + 1 > *max_size) { *max_size = high - low + 1; memcpy(palindrome, s + low, *max_size); @@ -28,18 +27,25 @@ static char *longestPalindrom(char *s) { return s; } + char *palindrome = malloc(1000); memset(palindrome, 0, sizeof(palindrome)); int max_size = 0; for (i = 0; i < len; i++) { - palindrome_find(s, len, i, i, &max_size); - palindrome_find(s, len, i, i + 1, &max_size); + /* start from the middle and scan both two sides */ + find(s, len, i, i, &max_size, palindrome); + find(s, len, i, i + 1, &max_size, palindrome); } return palindrome; } -int main(int argc, char **argv) { +int main(int argc, char **argv) +{ + if (argc != 2) { + fprintf(stderr, "Usage: ./test string\n"); + exit(-1); + } printf("%s\n", longestPalindrom(argv[1])); return 0; } diff --git a/131_palindrome_patitioning/Makefile b/131_palindrome_patitioning/Makefile new file mode 100644 index 0000000..3179327 --- /dev/null +++ b/131_palindrome_patitioning/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O2 -o test palindrome_partition.c diff --git a/131_palindrome_patitioning/palindrome_partition.c b/131_palindrome_patitioning/palindrome_partition.c new file mode 100644 index 0000000..14362ad --- /dev/null +++ b/131_palindrome_patitioning/palindrome_partition.c @@ -0,0 +1,103 @@ +#include +#include +#include +#include + +struct palindrome { + int low; + int high; +}; + +static void collect(char *s, int len, int low, int high, struct palindrome *results, int *count) +{ + while (low >= 0 && high < len && s[low] == s[high]) { + results[*count].low = low; + results[*count].high = high; + (*count)++; + low--; + high++; + } +} + +static void show(struct palindrome **stack, int size) +{ + int i; + for (i = 0; i < size; i++) { + printf("%d %d %d\n", i, stack[i]->low, stack[i]->high); + } +} + +static void recursive(struct palindrome *pal_set, int num, int start, + char *s, int len, struct palindrome **stack, int size, + char ***results, int *col_sizes, int *count) +{ + int i; + int begin = 0; + int end = size == 0 ? 0 : size - 1; + if (size > 0 && stack[begin]->low == 0 && stack[end]->high == len - 1) { + col_sizes[*count] = size; + results[*count] = malloc(size * sizeof(char *)); + for (i = 0; i < size; i++) { + int low = stack[i]->low; + int high = stack[i]->high; + results[*count][i] = malloc(high - low + 2); + memcpy(results[*count][i], s + low, high - low + 1); + results[*count][i][high - low + 1] = '\0'; + } + (*count)++; + } else { + for (i = start; i < num; i++) { + if (size == 0 || stack[size - 1]->high + 1 == pal_set[i].low) { + stack[size] = &pal_set[i]; + recursive(pal_set, num, i + 1, s, len, stack, size + 1, results, col_sizes, count); + } + } + } +} + +/** + ** Return an array of arrays of size *returnSize. + ** The sizes of the arrays are returned as *columnSizes array. + ** Note: Both returned array and *columnSizes array must be malloced, assume caller calls free(). + **/ +char*** partition(char* s, int** columnSizes, int* returnSize) { + int len = strlen(s); + if (len == 0) { + *returnSize = 0; + return NULL; + } + + int i, cap = 1000, count = 0; + struct palindrome *pal_set = malloc(cap * sizeof(*pal_set)); + for (i = 0; i < len; i++) { + collect(s, len, i, i, pal_set, &count); + collect(s, len, i, i + 1, pal_set, &count); + } + + char ***results = malloc(cap * sizeof(char **)); + struct palindrome **stack = malloc(count * sizeof(*stack)); + *columnSizes = malloc(cap * sizeof(int)); + recursive(pal_set, count, 0, s, len, stack, 0, results, *columnSizes, returnSize); + + return results; +} + +int main(int argc, char **argv) +{ + if (argc != 2) { + fprintf(stderr, "Usage: ./test string\n"); + exit(-1); + } + + int i, j, count = 0; + int *col_sizes; + char ***lists = partition(argv[1], &col_sizes, &count); + for (i = 0; i < count; i++) { + char **list = lists[i]; + for (j = 0; j < col_sizes[i]; j++) { + printf("%s ", list[j]); + } + printf("\n"); + } + return 0; +}