Skip to content

Commit b6ab257

Browse files
author
wangzhijie01
committed
wangzhijie add for manacher 2020-4-28
1 parent 1f2fc52 commit b6ab257

File tree

3 files changed

+179
-0
lines changed

3 files changed

+179
-0
lines changed
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
/*************************************************************************
2+
> File Name: lowmanacher.c
3+
> Author: wangzhijie
4+
5+
> Created Time: 2020年04月28日 星期二 10时24分09秒
6+
************************************************************************/
7+
8+
#include<stdio.h>
9+
#include <string.h>
10+
#include <stdlib.h>
11+
12+
13+
#define MALLOC_ERROR(ptr)\
14+
if(NULL == ptr) { \
15+
printf("%s,%d malloc error!\n", __FUNCTION__,__LINE__);\
16+
}
17+
18+
void lowmanacher(int *arr, char *buf)
19+
{
20+
int i, j, size, max = 0;
21+
size = strlen(buf);
22+
for(i = 0; i < strlen(buf); i++){
23+
j = 1;
24+
while((i - j) >= 0 && (i + j) < size){
25+
if(buf[i - j] == buf[i+j]){
26+
arr[i]++;
27+
j++;
28+
}else
29+
break;
30+
}
31+
if(arr[max] < arr[i])
32+
max = i;
33+
}
34+
if(arr[max] == 0){
35+
printf("没有回文串\n");
36+
return;
37+
}
38+
39+
char *tmp = malloc(sizeof(char) * arr[max] * 2 + 1);
40+
memcpy(tmp, (buf + max) - arr[max], 2 * arr[max] + 1);
41+
printf("max palindrome position is %d, max palindrome segment is %s\n", max, tmp);
42+
43+
44+
}
45+
46+
47+
int main()
48+
{
49+
50+
char buf[100] = {
51+
0
52+
};
53+
54+
while(scanf("%s", buf) != EOF){
55+
//把每个字符代表的回文长度存储到数组中
56+
int *arr = malloc(sizeof(int) * strlen(buf));
57+
MALLOC_ERROR(arr);
58+
memset(arr, 0, sizeof(int) * strlen(buf));
59+
lowmanacher(arr, buf);
60+
}
61+
62+
63+
64+
return 0;
65+
}

2020-4-28-马拉车算法/manacher.c

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
/*************************************************************************
2+
> File Name: lowmanacher.c
3+
> Author: wangzhijie
4+
5+
> Created Time: 2020年04月28日 星期二 10时24分09秒
6+
************************************************************************/
7+
8+
#include<stdio.h>
9+
#include <string.h>
10+
#include <stdlib.h>
11+
12+
13+
#define MALLOC_ERROR(ptr)\
14+
if(NULL == ptr) { \
15+
printf("%s,%d malloc error!\n", __FUNCTION__,__LINE__);\
16+
}
17+
18+
//将数组中填充#,2*i+1必然是奇数,所以肯定是奇对称
19+
char* arrinsert(char *buf, int size)
20+
{
21+
//需要在最后加一个\0用来输出打印
22+
char *tmp = malloc(size * 2 + 1 + 1);
23+
MALLOC_ERROR(tmp);
24+
memset(tmp, 0, size * 2 + 2);
25+
int i;
26+
for(i = 0; i < size * 2 + 1; i += 2){
27+
tmp[i] = '#';
28+
tmp[i + 1] = buf[i / 2];
29+
}
30+
printf("new buf=%s\n", tmp);
31+
return tmp;
32+
}
33+
34+
void manacher(char *buf)
35+
{
36+
int i, j, size, max = 0, mirror = -1;
37+
size = strlen(buf);
38+
char *tmp = arrinsert(buf, size);
39+
size = strlen(tmp);
40+
int *arr = malloc( sizeof(int) * size);
41+
MALLOC_ERROR(arr);
42+
memset(arr, 0, sizeof(int) * size);
43+
//三种情况,在回文长度,需要在最长回文长度外在判断,或者在最长回文长度外,朴素查找
44+
//所以前两种情况只要i在最长回文半径内,则可以减少mirror[i]的查找,这就是马拉车算法精髓
45+
46+
for(i = 0; i < strlen(tmp); i++){
47+
//判断i是否在max内
48+
if(i < max + arr[max]){
49+
mirror = 2 * max - i;
50+
if(mirror < 0)
51+
j = 1;
52+
else
53+
j = arr[mirror];
54+
}else{
55+
j = 1;
56+
}
57+
while((i - j) >= 0 && (i + j) < size){
58+
if(tmp[i - j] == tmp[i+j]){
59+
arr[i]++;
60+
j++;
61+
}else
62+
break;
63+
}
64+
if(mirror != -1)
65+
arr[i] += arr[mirror];
66+
if(arr[max] < arr[i])
67+
max = i;
68+
mirror = -1;
69+
}
70+
71+
if(arr[max] == 0 || (tmp[arr[max] + max] == '#' && arr[max] == 1 )){
72+
printf("没有回文串\n");
73+
return;
74+
}
75+
printf("max=%d\n",max);
76+
77+
for(i = max - arr[max]; i <= arr[max] + max; i++){
78+
if(tmp[i] == '#')
79+
continue;
80+
else
81+
printf("%c",tmp[i]);
82+
}
83+
printf("\n");
84+
85+
free(tmp);
86+
}
87+
88+
89+
int main()
90+
{
91+
92+
char buf[100] = {
93+
0
94+
};
95+
96+
while(scanf("%s", buf) != EOF){
97+
//把每个字符代表的回文长度存储到数组中
98+
manacher(buf);
99+
}
100+
101+
return 0;
102+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
1:马拉车的精髓在于记录最大右界来减少匹配次数
2+
2:三种情况分别是
3+
i < max 但是i的回文半径大于最长回文半径
4+
i < max 回文半径小于最长回文半径
5+
i > max 需要暴力求解
6+
7+
对于前两种情况合并为一种,i关于最长回文半径中心店的mirror点,i可以跳过mirror点半径来
8+
进行匹配。
9+
第三种情况直接暴力求解即可
10+
11+
todo:
12+
优化代码运行速度,减少内存使用

0 commit comments

Comments
 (0)