Aleph-w 3.0
A C++ Library for Data Structures and Algorithms
Loading...
Searching...
No Matches
String_Palindromes.H
Go to the documentation of this file.
1/*
2 Aleph_w
3
4 Data structures & Algorithms
5 version 2.0.0b
6 https://github.com/lrleon/Aleph-w
7
8 This file is part of Aleph-w library
9
10 Copyright (c) 2002-2026 Leandro Rabindranath Leon
11
12 Permission is hereby granted, free of charge, to any person obtaining a copy
13 of this software and associated documentation files (the "Software"), to deal
14 in the Software without restriction, including without limitation the rights
15 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
16 copies of the Software, and to permit persons to whom the Software is
17 furnished to do so, subject to the following conditions:
18
19 The above copyright notice and this permission notice shall be included in all
20 copies or substantial portions of the Software.
21
22 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
25 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
28 SOFTWARE.
29*/
30
31
44# ifndef STRING_PALINDROMES_H
45# define STRING_PALINDROMES_H
46
47# include <algorithm>
48# include <string>
49# include <string_view>
50
51# include <tpl_array.H>
52
53namespace Aleph
54{
71
72
81 inline Manacher_Result manacher(const std::string_view text)
82 {
83 Manacher_Result result;
84 const size_t n = text.size();
85
86 if (n == 0)
87 {
88 result.longest_palindrome = "";
89 return result;
90 }
91
94
95 for (size_t i = 0; i < n; ++i)
96 {
97 result.odd_radius[i] = 0;
98 result.even_radius[i] = 0;
99 }
100
101 long long l = 0;
102 long long r = -1;
103
104 for (size_t i = 0; i < n; ++i)
105 {
106 size_t k = 1;
107 if (static_cast<long long>(i) <= r)
108 {
109 const size_t mirror = l + r - static_cast<long long>(i);
110 k = std::min(result.odd_radius[mirror],
111 static_cast<size_t>(r - static_cast<long long>(i) + 1));
112 }
113
114 while (static_cast<long long>(i) - static_cast<long long>(k) >= 0
115 and i + k < n
116 and text[i - k] == text[i + k])
117 ++k;
118
119 result.odd_radius[i] = k;
120
121 const long long new_l = static_cast<long long>(i) - static_cast<long long>(k) + 1;
122 const long long new_r = static_cast<long long>(i) + static_cast<long long>(k) - 1;
123 if (new_r > r)
124 {
125 l = new_l;
126 r = new_r;
127 }
128 }
129
130 l = 0;
131 r = -1;
132
133 for (size_t i = 0; i < n; ++i)
134 {
135 size_t k = 0;
136 if (static_cast<long long>(i) <= r)
137 {
138 const auto mirror = static_cast<size_t>(l + r - static_cast<long long>(i) + 1);
139 k = std::min(result.even_radius[mirror],
140 static_cast<size_t>(r - static_cast<long long>(i) + 1));
141 }
142
143 while (static_cast<long long>(i) - static_cast<long long>(k) - 1 >= 0
144 and i + k < n
145 and text[i - k - 1] == text[i + k])
146 ++k;
147
148 result.even_radius[i] = k;
149
150 const long long new_l = static_cast<long long>(i) - static_cast<long long>(k);
151 const long long new_r = static_cast<long long>(i) + static_cast<long long>(k) - 1;
152 if (new_r > r)
153 {
154 l = new_l;
155 r = new_r;
156 }
157 }
158
159 size_t best_len = 0;
160 size_t best_begin = 0;
161
162 for (size_t i = 0; i < n; ++i)
163 {
164 const size_t odd_len = 2 * result.odd_radius[i] - 1;
165 const size_t odd_begin = i + 1 - result.odd_radius[i];
166 if (odd_len > best_len)
167 {
170 }
171
172 const size_t even_len = 2 * result.even_radius[i];
173 const size_t even_begin = i - result.even_radius[i];
174 if (even_len > best_len)
175 {
178 }
179 }
180
181 result.longest_begin = best_begin;
182 result.longest_length = best_len;
183 result.longest_palindrome = std::string(text.substr(best_begin, best_len));
184
185 return result;
186 }
187
188
194 inline std::string longest_palindromic_substring(const std::string_view text)
195 {
197 }
198} // namespace Aleph
199
200# endif // STRING_PALINDROMES_H
Simple dynamic array with automatic resizing and functional operations.
Definition tpl_array.H:139
static Array create(size_t n)
Create an array with n logical elements.
Definition tpl_array.H:194
Main namespace for Aleph-w library functions.
Definition ah-arena.H:89
and
Check uniqueness with explicit hash + equality functors.
Divide_Conquer_DP_Result< Cost > divide_and_conquer_partition_dp(const size_t groups, const size_t n, Transition_Cost_Fn transition_cost, const Cost inf=dp_optimization_detail::default_inf< Cost >())
Optimize partition DP using divide-and-conquer optimization.
std::string longest_palindromic_substring(const std::string_view text)
Convenience wrapper returning only the longest palindromic substring.
Manacher_Result manacher(const std::string_view text)
Compute palindromic radii and the longest palindrome with Manacher.
Result object for Manacher's algorithm.
Array< size_t > odd_radius
odd_radius[i] is radius around center i (length = 2*r-1).
size_t longest_begin
0-based start index of the longest palindrome.
std::string longest_palindrome
The longest palindromic substring.
Array< size_t > even_radius
even_radius[i] is radius around center between i-1 and i (length = 2*r).
size_t longest_length
Length of the longest palindrome.
static int * k
gsl_rng * r
Dynamic array container with automatic resizing.
DynList< int > l